ruby-montage 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +132 -0
- data/Rakefile +12 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/circle.yml +13 -0
- data/lib/montage.rb +6 -0
- data/lib/montage/client.rb +109 -0
- data/lib/montage/client/documents.rb +79 -0
- data/lib/montage/client/files.rb +39 -0
- data/lib/montage/client/schemas.rb +19 -0
- data/lib/montage/collection.rb +43 -0
- data/lib/montage/collections.rb +21 -0
- data/lib/montage/collections/documents.rb +13 -0
- data/lib/montage/collections/errors.rb +13 -0
- data/lib/montage/collections/files.rb +13 -0
- data/lib/montage/collections/schemas.rb +13 -0
- data/lib/montage/errors.rb +5 -0
- data/lib/montage/operators.rb +34 -0
- data/lib/montage/operators/equal.rb +17 -0
- data/lib/montage/operators/gt.rb +17 -0
- data/lib/montage/operators/gte.rb +17 -0
- data/lib/montage/operators/ilike.rb +17 -0
- data/lib/montage/operators/in.rb +17 -0
- data/lib/montage/operators/like.rb +17 -0
- data/lib/montage/operators/lt.rb +17 -0
- data/lib/montage/operators/lte.rb +17 -0
- data/lib/montage/operators/nil.rb +17 -0
- data/lib/montage/operators/not.rb +17 -0
- data/lib/montage/operators/not_in.rb +17 -0
- data/lib/montage/query.rb +107 -0
- data/lib/montage/query_parser.rb +112 -0
- data/lib/montage/resource.rb +47 -0
- data/lib/montage/resources.rb +25 -0
- data/lib/montage/resources/document.rb +9 -0
- data/lib/montage/resources/error.rb +9 -0
- data/lib/montage/resources/file.rb +9 -0
- data/lib/montage/resources/schema.rb +9 -0
- data/lib/montage/resources/token.rb +13 -0
- data/lib/montage/response.rb +49 -0
- data/lib/montage/support.rb +25 -0
- data/lib/montage/version.rb +3 -0
- data/ruby-montage.gemspec +36 -0
- metadata +251 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
module Montage
|
2
|
+
class Client
|
3
|
+
module Files
|
4
|
+
# Public: Get a list of files.
|
5
|
+
#
|
6
|
+
# Returns a Montage::Response
|
7
|
+
# def files
|
8
|
+
# get("files/", "file")
|
9
|
+
# end
|
10
|
+
|
11
|
+
# Public: Get a single file
|
12
|
+
#
|
13
|
+
# file_id - Required. The uuid of the file.
|
14
|
+
#
|
15
|
+
# Returns a Montage::Response
|
16
|
+
# def file(file_id)
|
17
|
+
# get("files/#{file_id}/", "file")
|
18
|
+
# end
|
19
|
+
|
20
|
+
# Public: Upload a new file
|
21
|
+
#
|
22
|
+
# file - Required. The file to upload.
|
23
|
+
#
|
24
|
+
# Returns a Montage::Response
|
25
|
+
# def new_file(file)
|
26
|
+
# post("files/", "file", file)
|
27
|
+
# end
|
28
|
+
|
29
|
+
# Public: Delete a file
|
30
|
+
#
|
31
|
+
# file_id - Required. The uuid of the file.
|
32
|
+
#
|
33
|
+
# Returns a Montage::Response
|
34
|
+
# def destroy_file(file_id)
|
35
|
+
# delete("files/#{file_id}/", "file")
|
36
|
+
# end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Montage
|
2
|
+
class Client
|
3
|
+
module Schemas
|
4
|
+
# Public: Get a list of schemas
|
5
|
+
#
|
6
|
+
# Returns a Montage::Response
|
7
|
+
def schemas
|
8
|
+
get("schemas/", "schema")
|
9
|
+
end
|
10
|
+
|
11
|
+
# Public: Get a single schema
|
12
|
+
#
|
13
|
+
# Returns a Montage::Response
|
14
|
+
def schema(name)
|
15
|
+
get("schemas/#{name}/", "schema")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Montage
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :raw_items, :items
|
6
|
+
|
7
|
+
def initialize(raw_items)
|
8
|
+
@raw_items = raw_items.dup.freeze
|
9
|
+
@items = parse_items
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.collection_name
|
13
|
+
"resources"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.resource_name
|
17
|
+
"resource"
|
18
|
+
end
|
19
|
+
|
20
|
+
def item_class
|
21
|
+
@item_class ||= Montage::Resources.find_class(self.class.resource_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_items
|
25
|
+
raw_items.map do |raw_item|
|
26
|
+
if raw_item["_meta"]
|
27
|
+
raw_item["created_at"] = raw_item["_meta"]["created"]
|
28
|
+
raw_item["updated_at"] = raw_item["_meta"]["modified"]
|
29
|
+
end
|
30
|
+
|
31
|
+
item_class.new(raw_item)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def singular?
|
36
|
+
items.length < 2
|
37
|
+
end
|
38
|
+
|
39
|
+
def each(&block)
|
40
|
+
items.each { |item| yield(item) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'montage/collections/errors'
|
2
|
+
require 'montage/collections/files'
|
3
|
+
require 'montage/collections/schemas'
|
4
|
+
require 'montage/collections/documents'
|
5
|
+
|
6
|
+
module Montage
|
7
|
+
module Collections
|
8
|
+
def self.classes
|
9
|
+
[
|
10
|
+
Montage::Errors,
|
11
|
+
Montage::Files,
|
12
|
+
Montage::Schemas,
|
13
|
+
Montage::Documents
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find_class(name)
|
18
|
+
self.classes.find(Proc.new { Montage::Collection }) { |c| c.collection_name == name }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'montage/operators/equal'
|
2
|
+
require 'montage/operators/not'
|
3
|
+
require 'montage/operators/not_in'
|
4
|
+
require 'montage/operators/lte'
|
5
|
+
require 'montage/operators/gte'
|
6
|
+
require 'montage/operators/lt'
|
7
|
+
require 'montage/operators/gt'
|
8
|
+
require 'montage/operators/ilike'
|
9
|
+
require 'montage/operators/like'
|
10
|
+
require 'montage/operators/in'
|
11
|
+
require 'montage/operators/nil'
|
12
|
+
|
13
|
+
module Montage
|
14
|
+
module Operators
|
15
|
+
def self.classes
|
16
|
+
[
|
17
|
+
Montage::Operators::Equal,
|
18
|
+
Montage::Operators::Not,
|
19
|
+
Montage::Operators::Lte,
|
20
|
+
Montage::Operators::Gte,
|
21
|
+
Montage::Operators::Lt,
|
22
|
+
Montage::Operators::Gt,
|
23
|
+
Montage::Operators::NotIn,
|
24
|
+
Montage::Operators::In,
|
25
|
+
Montage::Operators::Ilike,
|
26
|
+
Montage::Operators::Like,
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.find_operator(query_string)
|
31
|
+
self.classes.find(Proc.new { Montage::Operators::Nil }) { |c| c == query_string }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'montage/errors'
|
2
|
+
require 'montage/query_parser'
|
3
|
+
require 'montage/support'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Montage
|
7
|
+
class Query
|
8
|
+
include Montage::Support
|
9
|
+
|
10
|
+
attr_accessor :query
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@query = { filter: {} }
|
14
|
+
end
|
15
|
+
|
16
|
+
# Defines the limit to apply to the query, defaults to nil
|
17
|
+
#
|
18
|
+
# Merges a hash:
|
19
|
+
# { limit: 10 }
|
20
|
+
#
|
21
|
+
# Returns self
|
22
|
+
#
|
23
|
+
def limit(max = nil)
|
24
|
+
clone.tap { |r| r.query.merge!(limit: max) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# Defines the offset to apply to the query, defaults to nil
|
28
|
+
#
|
29
|
+
# Merges a hash:
|
30
|
+
# { offset: 10 }
|
31
|
+
#
|
32
|
+
# Returns a copy of self
|
33
|
+
#
|
34
|
+
def offset(value = nil)
|
35
|
+
clone.tap { |r| r.query.merge!(offset: value) }
|
36
|
+
end
|
37
|
+
|
38
|
+
# Defines the order clause for the query and merges it into the query hash
|
39
|
+
#
|
40
|
+
# Accepts either a string or a hash:
|
41
|
+
# order("foo asc") or
|
42
|
+
# order(:foo => :asc) or
|
43
|
+
# order(:foo => "asc")
|
44
|
+
#
|
45
|
+
# Defaults the direction to asc if no value is passed in for that, or if it is not a valid value
|
46
|
+
#
|
47
|
+
# Merges a hash:
|
48
|
+
# { order: "foo asc" }
|
49
|
+
#
|
50
|
+
# Returns a copy of self
|
51
|
+
#
|
52
|
+
def order(clause = {})
|
53
|
+
if clause.is_a?(Hash)
|
54
|
+
direction = clause.values.first.to_s
|
55
|
+
field = clause.keys.first.to_s
|
56
|
+
else
|
57
|
+
direction = clause.split(" ")[1]
|
58
|
+
field = clause.split(" ")[0]
|
59
|
+
direction = "asc" unless %w(asc desc).include?(direction)
|
60
|
+
end
|
61
|
+
|
62
|
+
clone.tap{ |r| r.query.merge!(order_by: field, ordering: direction) }
|
63
|
+
end
|
64
|
+
|
65
|
+
# Parses the SQL string passed into the method
|
66
|
+
#
|
67
|
+
# Raises an exception if it is not a valid query (at least three "words"):
|
68
|
+
# parse_string_clause("foo bar")
|
69
|
+
#
|
70
|
+
# Raises an exception if the operator given is not a valid operator
|
71
|
+
# parse_string_clause("foo * 'bar'")
|
72
|
+
#
|
73
|
+
# Returns a hash:
|
74
|
+
# parse_string_clause("foo <= 1")
|
75
|
+
# => { foo__lte: 1.0 }
|
76
|
+
#
|
77
|
+
|
78
|
+
# Adds a where clause to the query filter hash
|
79
|
+
#
|
80
|
+
# Accepts either a Hash or a String
|
81
|
+
# where(foo: 1)
|
82
|
+
# where("foo > 1")
|
83
|
+
#
|
84
|
+
# Merges a hash:
|
85
|
+
# { foo: 1 }
|
86
|
+
#
|
87
|
+
# Returns a copy of self
|
88
|
+
#
|
89
|
+
def where(clause)
|
90
|
+
clone.tap { |r| r.query[:filter].merge!(QueryParser.new(clause).parse) }
|
91
|
+
end
|
92
|
+
|
93
|
+
# Specifies and index to use on a query. RethinkDB isn't as smart as some other
|
94
|
+
# database engines when selecting a query plan, but it does let you specify
|
95
|
+
# which index to use
|
96
|
+
#
|
97
|
+
def index(field)
|
98
|
+
clone.tap { |r| r.query.merge!(index: field) }
|
99
|
+
end
|
100
|
+
|
101
|
+
# Parses the current query hash and returns a JSON string
|
102
|
+
#
|
103
|
+
def to_json
|
104
|
+
@query.to_json
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|