arangodb-odm 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -1
- data/Gemfile.lock +5 -2
- data/README.md +20 -0
- data/Rakefile +1 -7
- data/VERSION +1 -1
- data/lib/arangodb-odm.rb +33 -1
- data/lib/collections.rb +24 -0
- data/lib/indices.rb +26 -0
- data/lib/queries.rb +58 -2
- data/test/example_document.rb +2 -1
- data/test/helper.rb +5 -0
- data/test/test_collections.rb +8 -0
- data/test/test_indices.rb +7 -0
- data/test/test_queries.rb +20 -0
- metadata +13 -23
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -25,7 +25,6 @@ GEM
|
|
25
25
|
multi_json (1.4.0)
|
26
26
|
multi_xml (0.5.1)
|
27
27
|
rake (10.0.2)
|
28
|
-
rcov (1.0.0)
|
29
28
|
rdoc (2.4.3)
|
30
29
|
hoe (>= 1.12.1)
|
31
30
|
minitest (~> 1.3)
|
@@ -36,6 +35,10 @@ GEM
|
|
36
35
|
shoulda-matchers (1.4.2)
|
37
36
|
activesupport (>= 3.0.0)
|
38
37
|
bourne (~> 1.1.2)
|
38
|
+
simplecov (0.7.1)
|
39
|
+
multi_json (~> 1.0)
|
40
|
+
simplecov-html (~> 0.7.1)
|
41
|
+
simplecov-html (0.7.1)
|
39
42
|
|
40
43
|
PLATFORMS
|
41
44
|
ruby
|
@@ -45,6 +48,6 @@ DEPENDENCIES
|
|
45
48
|
httparty
|
46
49
|
jeweler (~> 1.6.4)
|
47
50
|
json
|
48
|
-
rcov
|
49
51
|
rdoc (~> 2.4.2)
|
50
52
|
shoulda
|
53
|
+
simplecov
|
data/README.md
CHANGED
@@ -57,6 +57,12 @@
|
|
57
57
|
#### First by example
|
58
58
|
|
59
59
|
ExampleDocument.where('foo' => 'bar', 'a' => 'b').first
|
60
|
+
|
61
|
+
#### Range
|
62
|
+
|
63
|
+
# Make sure you've setup a skip-list index on the attribute
|
64
|
+
ExampleDocument.attribute('test').left(0).right(100).all
|
65
|
+
ExampleDocument.attribute('test').left(0).right(100).closed(true).skip(10).limit(10).all
|
60
66
|
|
61
67
|
## Callbacks
|
62
68
|
|
@@ -98,6 +104,20 @@
|
|
98
104
|
|
99
105
|
def change_something_else; end
|
100
106
|
end
|
107
|
+
|
108
|
+
## Indices
|
109
|
+
|
110
|
+
### Skip List Index Definition
|
111
|
+
|
112
|
+
class ExampleDocument < ArangoDb::Base
|
113
|
+
collection :examples
|
114
|
+
skiplist :test, :something_else
|
115
|
+
end
|
116
|
+
|
117
|
+
### Creating indices
|
118
|
+
|
119
|
+
# Creates all indices defined in the document. Run it once when you setup your document model...
|
120
|
+
ExampleDocument.ensure_indices
|
101
121
|
|
102
122
|
## Copyright
|
103
123
|
|
data/Rakefile
CHANGED
@@ -33,13 +33,7 @@ Rake::TestTask.new(:test) do |test|
|
|
33
33
|
test.verbose = true
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
Rcov::RcovTask.new do |test|
|
38
|
-
test.libs << 'test'
|
39
|
-
test.pattern = 'test/**/test_*.rb'
|
40
|
-
test.verbose = true
|
41
|
-
test.rcov_opts << '--exclude "gems/*"'
|
42
|
-
end
|
36
|
+
# TODO simplecov
|
43
37
|
|
44
38
|
task :default => :test
|
45
39
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/lib/arangodb-odm.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
require "httparty"
|
3
3
|
require "json"
|
4
|
+
|
5
|
+
require "collections"
|
4
6
|
require "queries"
|
7
|
+
require "indices"
|
5
8
|
|
6
9
|
module ArangoDb
|
7
10
|
class Transport
|
@@ -29,60 +32,83 @@ module ArangoDb
|
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
35
|
+
class Index
|
36
|
+
attr_accessor :indices
|
37
|
+
|
38
|
+
def initialize(indices)
|
39
|
+
@indices = indices
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
32
43
|
module Properties
|
33
44
|
def self.included(klass)
|
34
45
|
klass.extend ClassMethods
|
35
46
|
end
|
36
47
|
|
37
48
|
module ClassMethods
|
49
|
+
# The collection to use for this document.
|
38
50
|
def collection(value)
|
39
51
|
(class << self; self; end).send(:define_method, 'collection') do
|
40
52
|
value.to_s
|
41
53
|
end
|
42
54
|
end
|
43
55
|
|
56
|
+
def skiplist(*fields)
|
57
|
+
(class << self; self; end).send(:define_method, 'skiplist') do
|
58
|
+
fields.to_a
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets the transport class to use. Defaults to httparty.
|
44
63
|
def transport(value)
|
45
64
|
(class << self; self; end).send(:define_method, 'transport') do
|
46
65
|
value
|
47
66
|
end
|
48
67
|
end
|
49
68
|
|
69
|
+
# Sets the document value proxy to use.
|
50
70
|
def target(value)
|
51
71
|
(class << self; self; end).send(:define_method, 'target') do
|
52
72
|
value
|
53
73
|
end
|
54
74
|
end
|
55
75
|
|
76
|
+
# Callback that is being invoked before a document is first created.
|
56
77
|
def before_create(value)
|
57
78
|
self.send(:define_method, 'before_create') do
|
58
79
|
value
|
59
80
|
end
|
60
81
|
end
|
61
82
|
|
83
|
+
# Callback that is being invoked after a document is first created.
|
62
84
|
def after_create(value)
|
63
85
|
self.send(:define_method, 'after_create') do
|
64
86
|
value
|
65
87
|
end
|
66
88
|
end
|
67
89
|
|
90
|
+
# Callback that is being invoked before a document is updated.
|
68
91
|
def before_save(value)
|
69
92
|
self.send(:define_method, 'before_save') do
|
70
93
|
value
|
71
94
|
end
|
72
95
|
end
|
73
96
|
|
97
|
+
# Callback that is being invoked after a document was updated.
|
74
98
|
def after_save(value)
|
75
99
|
self.send(:define_method, 'after_save') do
|
76
100
|
value
|
77
101
|
end
|
78
102
|
end
|
79
103
|
|
104
|
+
# Callback that is being invoked before a document is destroyed.
|
80
105
|
def before_destroy(value)
|
81
106
|
self.send(:define_method, 'before_destroy') do
|
82
107
|
value
|
83
108
|
end
|
84
109
|
end
|
85
110
|
|
111
|
+
# Callback that is being invoked after a document was destroyed.
|
86
112
|
def after_destroy(value)
|
87
113
|
self.send(:define_method, 'after_destroy') do
|
88
114
|
value
|
@@ -106,18 +132,24 @@ module ArangoDb
|
|
106
132
|
#
|
107
133
|
# class ExampleDocument < ArangoDb::Base
|
108
134
|
# collection :examples
|
135
|
+
# skiplist [:a, :b]
|
109
136
|
# end
|
110
137
|
class Base
|
111
138
|
include ArangoDb::Properties
|
139
|
+
extend ArangoDb::Collections::ClassMethods
|
112
140
|
extend ArangoDb::Queries::ClassMethods
|
141
|
+
extend ArangoDb::Indices::ClassMethods
|
113
142
|
transport ArangoDb::Transport
|
114
143
|
target ArangoDb::Document
|
115
144
|
db_attrs []
|
116
|
-
attr_reader :target
|
145
|
+
attr_reader :target, :index
|
117
146
|
|
118
147
|
def initialize
|
119
148
|
@transport = self.class.transport
|
120
149
|
@target = self.class.target.new(self.class.collection, self.class.db_attributes)
|
150
|
+
if self.class.respond_to?(:skiplist) and self.class.skiplist
|
151
|
+
@index = ArangoDb::Index.new(:skiplist => self.class.skiplist)
|
152
|
+
end
|
121
153
|
end
|
122
154
|
|
123
155
|
def self.find(document_handle)
|
data/lib/collections.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module ArangoDb
|
2
|
+
module Collections
|
3
|
+
module ClassMethods
|
4
|
+
# POST /_api/collection
|
5
|
+
# Creates an new collection with a given name. The request must contain an object with the following attributes.
|
6
|
+
# name: The name of the collection.
|
7
|
+
# waitForSync (optional, default: false): If true then the data is synchronised to disk before returning from a create or update of an document.
|
8
|
+
# journalSize (optional, default is a configuration parameter): The maximal size of a journal or datafile. Note that this also limits the maximal
|
9
|
+
# size of a single object. Must be at least 1MB.
|
10
|
+
# isSystem (optional, default is false): If true, create a system collection. In this case collection-name should start with an underscore.
|
11
|
+
# End users should normally create non-system collections only.
|
12
|
+
# API implementors may be required to create system collections in very special occasions, but normally a regular collection will do.
|
13
|
+
# type (optional, default is 2): the type of the collection to create. The following values for type are valid:
|
14
|
+
# 2: document collections
|
15
|
+
# 3: edge collection
|
16
|
+
def create_collection(options = {})
|
17
|
+
res = transport.post("/_api/collection", :body => options.merge('name' => collection).to_json)
|
18
|
+
if res.parsed_response and not res.parsed_response["code"] == 200
|
19
|
+
res.parsed_response["id"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/indices.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module ArangoDb
|
2
|
+
module Indices
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
# POST /_api/index?collection=collection-identifier
|
6
|
+
# Creates a skip-list index for the collection collection-identifier, if it does not already exist. The call expects an object
|
7
|
+
# containing the index details.
|
8
|
+
# type: must be equal to "skiplist".
|
9
|
+
# fields: A list of attribute paths.
|
10
|
+
# unique: If true, then create a unique index.
|
11
|
+
def create_skiplist(fields)
|
12
|
+
query_parameters = { "type" => "skiplist", "unique" => false, "fields" => fields }
|
13
|
+
endpoint = "/_api/index?collection=#{collection}"
|
14
|
+
res = transport.post(endpoint, :body => query_parameters.to_json)
|
15
|
+
if res.parsed_response and not (res.parsed_response["code"] == 200 or res.parsed_response["code"] == 201)
|
16
|
+
raise "Couldn't create skip list index: #{res.parsed_response["code"]}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def ensure_indices
|
21
|
+
create_skiplist(skiplist) if skiplist
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/queries.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module ArangoDb
|
2
2
|
module Queries
|
3
3
|
class QueryResult < Array
|
4
|
+
# TODO
|
4
5
|
end
|
5
6
|
|
6
7
|
class Query
|
@@ -24,6 +25,26 @@ module ArangoDb
|
|
24
25
|
self
|
25
26
|
end
|
26
27
|
|
28
|
+
def attribute(attr_name)
|
29
|
+
@attribute = attr_name
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def left(number)
|
34
|
+
@left = number
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def right(number)
|
39
|
+
@right = number
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def closed(boolean)
|
44
|
+
@closed = boolean
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
27
48
|
def first
|
28
49
|
@model.first(query_parameters)
|
29
50
|
end
|
@@ -31,13 +52,17 @@ module ArangoDb
|
|
31
52
|
def all
|
32
53
|
@model.all(query_parameters)
|
33
54
|
end
|
34
|
-
|
55
|
+
|
35
56
|
private
|
36
57
|
def query_parameters
|
37
58
|
options = {}
|
38
59
|
options['limit'] = @limit if @limit
|
39
60
|
options['skip'] = @skip if @skip
|
40
61
|
options['example'] = @where if @where
|
62
|
+
options['left'] = @left if @left
|
63
|
+
options['right'] = @right if @right
|
64
|
+
options['attribute'] = @attribute if @attribute
|
65
|
+
options['closed'] = @closed if @closed
|
41
66
|
options
|
42
67
|
end
|
43
68
|
end
|
@@ -56,9 +81,24 @@ module ArangoDb
|
|
56
81
|
# example: The example.
|
57
82
|
# skip: The documents to skip in the query. (optional)
|
58
83
|
# limit: The maximal amount of documents to return. (optional)
|
84
|
+
#
|
85
|
+
# PUT /_api/simple/range
|
86
|
+
# This will find all documents within a given range. You must declare a skip-list index on the attribute in order
|
87
|
+
# to be able to use a range query.The call expects a JSON hash array as body with the following attributes:
|
88
|
+
# collection: The identifier or name of the collection to query.
|
89
|
+
# attribute: The attribute path to check.
|
90
|
+
# left: The lower bound.
|
91
|
+
# right: The upper bound.
|
92
|
+
# closed: If true, use interval including left and right, otherwise exclude right, but include left.
|
93
|
+
# skip: The documents to skip in the query. (optional)
|
94
|
+
# limit: The maximal amount of documents to return. (optional)
|
59
95
|
def all(options = {})
|
60
96
|
query_parameters = {'collection' => collection}; endpoint = '/_api/simple/all'
|
61
|
-
|
97
|
+
if options and options['example'] and options['example'].any?
|
98
|
+
endpoint = '/_api/simple/by-example'
|
99
|
+
elsif options and options['left'] and options['right'] and options['attribute']
|
100
|
+
endpoint = '/_api/simple/range'
|
101
|
+
end
|
62
102
|
res = transport.put(endpoint, :body => query_parameters.merge(options).to_json)
|
63
103
|
if res.code == 201 and res.parsed_response and res.parsed_response["result"]
|
64
104
|
query_result = QueryResult.new
|
@@ -91,6 +131,22 @@ module ArangoDb
|
|
91
131
|
def skip(number)
|
92
132
|
Query.new(self).skip(number)
|
93
133
|
end
|
134
|
+
|
135
|
+
def attribute(attr_name)
|
136
|
+
Query.new(self).attribute(attr_name)
|
137
|
+
end
|
138
|
+
|
139
|
+
def left(number)
|
140
|
+
Query.new(self).left(number)
|
141
|
+
end
|
142
|
+
|
143
|
+
def right(number)
|
144
|
+
Query.new(self).right(number)
|
145
|
+
end
|
146
|
+
|
147
|
+
def closed(boolean)
|
148
|
+
Query.new(self).closed(boolean)
|
149
|
+
end
|
94
150
|
end
|
95
151
|
end
|
96
152
|
end
|
data/test/example_document.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -19,5 +19,10 @@ require 'another_example_document.rb'
|
|
19
19
|
# Set your ArangoDB host...
|
20
20
|
ArangoDb::Transport.base_uri 'http://localhost:8529'
|
21
21
|
|
22
|
+
# Initial setup
|
23
|
+
ExampleDocument.create_collection # only needed to be able to create indices on the initial test run
|
24
|
+
ExampleDocument.ensure_indices
|
25
|
+
# AnotherExampleDocument.create_collection
|
26
|
+
|
22
27
|
class Test::Unit::TestCase
|
23
28
|
end
|
data/test/test_queries.rb
CHANGED
@@ -29,4 +29,24 @@ class TestArangoDbQueries < Test::Unit::TestCase
|
|
29
29
|
example_document = ExampleDocument.where(:something => 'not existant').first
|
30
30
|
assert_nil example_document
|
31
31
|
end
|
32
|
+
|
33
|
+
should "get documents in a given range" do
|
34
|
+
ts = Time.now.to_i + rand(1000); count = 10
|
35
|
+
count.times {|i| ExampleDocument.create(:foo => "1", :test => ts + i)}
|
36
|
+
|
37
|
+
example_documents = ExampleDocument.attribute(:test).left(ts + 6).right(ts + 9).all
|
38
|
+
assert_not_nil example_documents
|
39
|
+
assert_equal example_documents.size, 3
|
40
|
+
assert_equal example_documents[0].test, ts + 6
|
41
|
+
assert_equal example_documents[1].test, ts + 7
|
42
|
+
assert_equal example_documents[2].test, ts + 8
|
43
|
+
|
44
|
+
example_documents = ExampleDocument.attribute(:test).left(ts + 6).right(ts + 9).closed(true).all
|
45
|
+
assert_not_nil example_documents
|
46
|
+
assert_equal example_documents.size, 4
|
47
|
+
assert_equal example_documents[0].test, ts + 6
|
48
|
+
assert_equal example_documents[1].test, ts + 7
|
49
|
+
assert_equal example_documents[2].test, ts + 8
|
50
|
+
assert_equal example_documents[3].test, ts + 9
|
51
|
+
end
|
32
52
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arangodb-odm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 1
|
10
|
+
version: 0.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Oliver Kiessler
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-12-
|
18
|
+
date: 2012-12-08 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
@@ -93,20 +93,6 @@ dependencies:
|
|
93
93
|
type: :development
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
requirement: &id006 !ruby/object:Gem::Requirement
|
96
|
-
none: false
|
97
|
-
requirements:
|
98
|
-
- - ">="
|
99
|
-
- !ruby/object:Gem::Version
|
100
|
-
hash: 3
|
101
|
-
segments:
|
102
|
-
- 0
|
103
|
-
version: "0"
|
104
|
-
version_requirements: *id006
|
105
|
-
name: rcov
|
106
|
-
prerelease: false
|
107
|
-
type: :development
|
108
|
-
- !ruby/object:Gem::Dependency
|
109
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
110
96
|
none: false
|
111
97
|
requirements:
|
112
98
|
- - ~>
|
@@ -117,12 +103,12 @@ dependencies:
|
|
117
103
|
- 4
|
118
104
|
- 2
|
119
105
|
version: 2.4.2
|
120
|
-
version_requirements: *
|
106
|
+
version_requirements: *id006
|
121
107
|
name: rdoc
|
122
108
|
prerelease: false
|
123
109
|
type: :development
|
124
110
|
- !ruby/object:Gem::Dependency
|
125
|
-
requirement: &
|
111
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
126
112
|
none: false
|
127
113
|
requirements:
|
128
114
|
- - ">="
|
@@ -131,12 +117,12 @@ dependencies:
|
|
131
117
|
segments:
|
132
118
|
- 0
|
133
119
|
version: "0"
|
134
|
-
version_requirements: *
|
120
|
+
version_requirements: *id007
|
135
121
|
name: httparty
|
136
122
|
prerelease: false
|
137
123
|
type: :runtime
|
138
124
|
- !ruby/object:Gem::Dependency
|
139
|
-
requirement: &
|
125
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
140
126
|
none: false
|
141
127
|
requirements:
|
142
128
|
- - ">="
|
@@ -145,7 +131,7 @@ dependencies:
|
|
145
131
|
segments:
|
146
132
|
- 0
|
147
133
|
version: "0"
|
148
|
-
version_requirements: *
|
134
|
+
version_requirements: *id008
|
149
135
|
name: json
|
150
136
|
prerelease: false
|
151
137
|
type: :runtime
|
@@ -167,11 +153,15 @@ files:
|
|
167
153
|
- Rakefile
|
168
154
|
- VERSION
|
169
155
|
- lib/arangodb-odm.rb
|
156
|
+
- lib/collections.rb
|
157
|
+
- lib/indices.rb
|
170
158
|
- lib/queries.rb
|
171
159
|
- test/another_example_document.rb
|
172
160
|
- test/example_document.rb
|
173
161
|
- test/helper.rb
|
174
162
|
- test/test_arangodb-odm.rb
|
163
|
+
- test/test_collections.rb
|
164
|
+
- test/test_indices.rb
|
175
165
|
- test/test_queries.rb
|
176
166
|
homepage: http://github.com/okiess/arangodb-odm
|
177
167
|
licenses:
|