Skip to content

Commit

Permalink
Merge pull request nirvana#17 from splatte/manage_views
Browse files Browse the repository at this point in the history
Add support for "create view" and "delete view"
  • Loading branch information
n1rvana committed Dec 21, 2015
2 parents 3f8528b + beead45 commit d605c2f
Showing 1 changed file with 127 additions and 80 deletions.
207 changes: 127 additions & 80 deletions lib/couchie.ex
Original file line number Diff line number Diff line change
@@ -1,139 +1,186 @@
defmodule Couchie do
@moduledoc """
Minimalist Elixir interface to Couchbase 2.0.
Couchie is based on cberl which is a NIF of the libcouchbase & Jiffy JSON encoder NIF.
JSON support is built in. Pass in terms and they are encoded as JSON.
When you fetch JSON documents you get terms.
To store raw data, pass in a binary.
"""
@moduledoc """
Minimalist Elixir interface to Couchbase 2.0.
Couchie is based on cberl which is a NIF of the libcouchbase & Jiffy JSON encoder NIF.
JSON support is built in. Pass in terms and they are encoded as JSON.
When you fetch JSON documents you get terms.
To store raw data, pass in a binary.
"""

@doc """
Open a connection pool to the server:
Open takes a connection configuration consisting of connection name,
Open a connection pool to the server:
Open takes a connection configuration consisting of connection name,
size of the pool to set up, hostname & port, username, password.
## Examples
## Examples
# open connection named "default_connection" to the default bucket, which should be used for testing only
Couchie.open(:default_connection)
{ok, <0.XX.0>} #=> successful connection to default bucket on localhost
# open connection named "default_connection" to the default bucket, which should be used for testing only
Couchie.open(:default_connection)
{ok, <0.XX.0>} #=> successful connection to default bucket on localhost
# if your bucket is password protected:
Couchie.open(:secret, 10, 'localhost:8091', 'bucket_name', 'bucket_pasword')
{ok, <0.XX.0>} #=> successful connection to the named bucket, which you can access using the id "secret"
# if your bucket isn't password protected (and isn't default)
Couchie.open(:connection, 10, 'localhost:8091', 'bucket_name')
{ok, <0.XX.0>} #=> successful connection to the named bucket, which you can access using the id "application"
Couchie.open(:secret, 10, 'localhost:8091', 'bucket_name', 'bucket_pasword')
{ok, <0.XX.0>} #=> successful connection to the named bucket, which you can access using the id "secret"
"""
def open(name) do
# if your bucket isn't password protected (and isn't default)
Couchie.open(:connection, 10, 'localhost:8091', 'bucket_name')
{ok, <0.XX.0>} #=> successful connection to the named bucket, which you can access using the id "application"
"""
def open(name) do
open(name, 10, 'localhost:8091')
end
end

def open(name, size) do
def open(name, size) do
open(name, size, 'localhost:8091')
end
def open(name, size, host) do
end

def open(name, size, host) do
IO.puts "Opening #{name}, #{size}, #{host}"
open(name, size, host, '', '', '')
IO.puts "Opened #{name}, #{size}, #{host}"
end
open(name, size, host, '', '', '')
IO.puts "Opened #{name}, #{size}, #{host}"
end

def open(name, size, host, bucket) do # assume the bucket user and pass are the same as bucket name
open(name, size, host, bucket, bucket, bucket)
end
end

def open(name, size, host, bucket, password) do # username is same as bucket name
def open(name, size, host, bucket, password) do # username is same as bucket name
open(name, size, host, bucket, bucket, password)
end
end

def open(name, size, host, bucket, username, pass) do #currently usernames are set to bucket names in this interface.
IO.puts "Opening #{name}, #{size}, #{host}, #{username}, #{pass}, #{bucket} "
:cberl.start_link(name, size, host, username, pass, bucket, Couchie.Transcoder)
:cberl.start_link(name, size, host, username, pass, bucket, Couchie.Transcoder)
end

@doc """
Shutdown the connection to a particular bucket
@doc """
Shutdown the connection to a particular bucket
Couchie.close(:connection)
"""
"""
def close(pool) do
:cberl.stop(pool)
end

@doc """
Create document if it doesn't exist, or replace it if it does.
Create document if it doesn't exist, or replace it if it does.
First parameter is the connection you passed into Couchie.open()
## Examples
## Examples
#
Couchie.set(:default, "key", "document data")
"""
Couchie.set(:default, "key", "document data")
"""
def set(connection, key, document) do
Couchie.set(connection, key, document, 0)
end

@doc """
Create document if it doesn't exist, or replace it if it does.
Create document if it doesn't exist, or replace it if it does.
First parameter is the connection you passed into Couchie.open()
If you want the document to be purged after a period of time, use the Expiration.
If you want the document to be purged after a period of time, use the Expiration.
Set expiration to zero for permanent storage (or use set/3)
## Example
## Example
Couchie.set(:default, "key", "document data", 0)
"""
Couchie.set(:default, "key", "document data", 0)
"""
def set(connection, key, document, expiration) do
:cberl.set(connection, key, expiration, document) # NOTE: cberl parameter order is different!
end


@doc """
Get document. Keys should be binary.
## Example

Couchie.get(:connection, "test_key")
#=> {"test_key" 1234567890, "value"} # The middle figure is the CAS for this document.
"""
@doc """
Get document. Keys should be binary.
## Example
Couchie.get(:connection, "test_key")
#=> {"test_key" 1234567890, "value"} # The middle figure is the CAS for this document.
"""
def get(connection, key) do
:cberl.get(connection, key)
end

@doc """
Get multiple documents from a list of keys Keys should be binary.
## Example

Couchie.mget(:connection, ["test_key", "another key"])
"""
@doc """
Get multiple documents from a list of keys Keys should be binary.
## Example
Couchie.mget(:connection, ["test_key", "another key"])
"""
def mget(connection, keys) do
:cberl.mget(connection, keys)
end

@doc """
Delete document. Key should be binary.
## Example
@doc """
Delete document. Key should be binary.
## Example
Couchie.delete(:connection, "test_key")
"""
Couchie.delete(:connection, "test_key")
"""
def delete(connection, key) do
:cberl.remove(connection, key)
end

@doc """
Delete document. Key should be binary.
## Example
@doc """
Delete document. Key should be binary.
## Example
Couchie.delete(:connection, "test_key")
"""
def query(connection, doc, view, args) do
:cberl.view(connection, doc, view, args)
end
Couchie.delete(:connection, "test_key")
"""
def query(connection, doc, view, args) do
:cberl.view(connection, doc, view, args)
end

end
defmodule DesignDoc do
@moduledoc """
A struct that encapsulates a single view definition.
It contains the following fields:
* `:name` - the view's name
* `:map` - the map function as JavaScript code
* `:reduce` - the reduce function as JavaScript code (optional)
"""
defstruct name: nil, map: nil, reduce: nil
end

@doc """
Creates or updates a view.
Specify the name of the design you want to create or update as `doc_name`.
The third parameter can be one view definition or a list of them. See DesignDoc struct above.
## Example
Couchie.create_view(:db, "my-views", %Couchie.DesignDoc{name: "only_youtube", map: "function(doc, meta) { if (doc.docType == 'youtube') { emit(doc.docType, doc); }}"})
"""
def create_view(connection, doc_name, %DesignDoc{} = view), do: create_view(connection, doc_name, [view])
def create_view(connection, doc_name, views) do
design_doc = {[{
"views",
{ views |> Enum.map(&view_as_json(&1)) }
}]}
:cberl.set_design_doc(connection, doc_name, design_doc)
end

defp view_as_json(view) do
# convert one view definition to a tuple that can later be converted to json
{ view.name,
{ view
|> Map.take([:map, :reduce])
|> Enum.filter(fn {k, v} -> !is_nil(v) end) # only put fields that are not nil
}
}
end

@doc """
Delete view.
## Example
Couchie.delete_view(:connection, "design-doc-id")
"""
def delete_view(connection, doc_name) do
:cberl.remove_design_doc(connection, doc_name)
end
end

0 comments on commit d605c2f

Please sign in to comment.