mongolitedb 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c4ba47f1829ac304ccd6b11f7ef4ea97e06b4c1
4
- data.tar.gz: 020c5c5191f247972874ac9f4c474e4ca7272ed8
3
+ metadata.gz: 61d2c498c08966845f3e8d5ac13c8858599f831b
4
+ data.tar.gz: 514b684b4a2c21f75437f68bdf1b39b7cb8baea0
5
5
  SHA512:
6
- metadata.gz: c7012586e2c0a364f5952de9c9e932fe01fd9c183f951eeb6807295cf718c92af3143527a5a2d30c0a504788727ac370b0463213bd73393342ca094d82fcba74
7
- data.tar.gz: cd39d1355be855655dde02048e8523017c658067e90d4719cc29f5866850b2118eb754d34e3bb78255e9747dd52d98c5ddfdb6a1d877209284ef7b9130487722
6
+ metadata.gz: f89e5e7be09e0992104210f61c7eb3340f23b1628422075f4973a510e29a4c5b5e524eff969363ab50c44c3a5bcf63d71135dd612e4e18c3cd9f4932f82f3b9c
7
+ data.tar.gz: c5a076ba07eb8f8a2d77da70ef8f7b8f55ae05d898ad89371084981bb90638fdf3d23c437cfb75f416638893703b467bd86715c70b1d68f43047bd9673b7abc0
data/lib/matcher.rb ADDED
@@ -0,0 +1,87 @@
1
+ require 'predicate_matcher'
2
+
3
+ class Matcher
4
+ def initialize(query)
5
+ @query = query
6
+ end
7
+
8
+ def match(obj)
9
+ if @query.length > 1
10
+ # We always have an implied $and for multiple entries
11
+ matcher = AndMatcher.new({"$and" => @query.map{|k,v| {k => v}}})
12
+ elsif @query.length == 0
13
+ matcher = EmptyMatcher.new(@query)
14
+ else
15
+ # we only have one entry
16
+ case @query.keys.first
17
+ when "$or"
18
+ matcher = OrMatcher.new(@query)
19
+ when "$nor"
20
+ matcher = NorMatcher.new(@query)
21
+ when "$and"
22
+ matcher = AndMatcher.new(@query)
23
+ else
24
+ matcher = AttrMatcher.new(@query)
25
+ end
26
+ end
27
+ return matcher.match(obj)
28
+ end
29
+ end
30
+
31
+ class AttrMatcher < Matcher
32
+ def match(obj)
33
+ attribute = @query.keys.first
34
+ if attribute.include?(".")
35
+ value = obj
36
+ attribute.split(".").each do |attr|
37
+ value = value[attr]
38
+ if value.nil?
39
+ return false
40
+ end
41
+ end
42
+ else
43
+ value = obj[@query.keys.first]
44
+ end
45
+ predicate = @query.values.first
46
+ if predicate.kind_of? Hash
47
+ matcher = PredicateMatcher.new(predicate)
48
+ return matcher.match(value)
49
+ else
50
+ return value == predicate
51
+ end
52
+ end
53
+ end
54
+
55
+ class AndMatcher < Matcher
56
+ def match(obj)
57
+ does_it_match = true
58
+ @query.values.first.each do |subquery|
59
+ matcher = Matcher.new(subquery)
60
+ does_it_match &&= matcher.match(obj)
61
+ end
62
+ return does_it_match
63
+ end
64
+ end
65
+
66
+ class EmptyMatcher < Matcher
67
+ def match(obj)
68
+ true
69
+ end
70
+ end
71
+
72
+ class OrMatcher < Matcher
73
+ def match(obj)
74
+ does_it_match = false
75
+ @query.values.first.each do |subquery|
76
+ matcher = Matcher.new(subquery)
77
+ does_it_match ||= matcher.match(obj)
78
+ end
79
+ return does_it_match
80
+ end
81
+ end
82
+
83
+ class NorMatcher < Matcher
84
+ def match(obj)
85
+ return !OrMatcher.new(@query).match(obj)
86
+ end
87
+ end
data/lib/mongolitedb.rb CHANGED
@@ -1,160 +1,92 @@
1
1
  require 'json'
2
+ require 'matcher'
2
3
 
3
4
  class MongoLiteDB
4
- def initialize(filename="db.nsl")
5
- @filename = filename
6
- if not File.exists?(@filename)
7
- open(@filename, 'w'){|f| f.write(
8
- {
9
- "max_index" => 0,
10
- "objects" => []
11
- }.to_json
12
- )}
13
- end
5
+ def initialize(filename="db.nsl")
6
+ @filename = filename
7
+ if not File.exists?(@filename)
8
+ open(@filename, 'w'){|f| f.write(
9
+ {
10
+ "max_index" => 0,
11
+ "objects" => []
12
+ }.to_json
13
+ )}
14
14
  end
15
- def insert(objects)
16
- if not objects.kind_of?(Array)
17
- objects = [objects]
18
- end
19
- write_to_disk do |db|
20
- objects.each do |object|
21
- object_copy = object.clone
22
- object_copy["id"] = db["max_index"]
23
- db["max_index"] += 1
24
- db["objects"] << object_copy
25
- end
26
- end
15
+ end
16
+ def insert(objects)
17
+ if not objects.kind_of?(Array)
18
+ objects = [objects]
27
19
  end
28
- def find(query)
29
- entries = []
30
- load_from_disk do |db|
31
- each_match(db, query) do |obj|
32
- entries << obj
33
- end
34
- end
35
- return entries
20
+ write_to_disk do |db|
21
+ objects.each do |object|
22
+ object_copy = object.clone
23
+ object_copy["id"] = db["max_index"]
24
+ db["max_index"] += 1
25
+ db["objects"] << object_copy
26
+ end
36
27
  end
37
-
38
- def update(query, attr)
39
- write_to_disk do |db|
40
- each_match(db, query) do |obj|
41
- obj.update(attr)
42
- end
43
- end
28
+ end
29
+ def find(query)
30
+ entries = []
31
+ load_from_disk do |db|
32
+ each_match(db, query) do |obj|
33
+ entries << obj
34
+ end
44
35
  end
45
- def delete(query)
46
- write_to_disk do |db|
47
- each_match(db, query) do |obj|
48
- db["objects"].delete(obj)
49
- end
50
- end
36
+ return entries
37
+ end
38
+ def update(query, attr)
39
+ write_to_disk do |db|
40
+ each_match(db, query) do |obj|
41
+ obj.update(attr)
42
+ end
43
+ end
44
+ end
45
+ def delete(query)
46
+ write_to_disk do |db|
47
+ each_match(db, query) do |obj|
48
+ db["objects"].delete(obj)
49
+ end
51
50
  end
51
+ end
52
52
 
53
- private
54
- def write_to_disk
55
- f = open(@filename, 'r+')
56
- f.flock(File::LOCK_EX)
57
- db = JSON.parse f.read
58
- yield db
59
- ensure
60
- if f
61
- if db
62
- f.rewind
63
- f.write db.to_json
64
- f.flush
65
- f.truncate f.pos
66
- end
67
- f.close
68
- end
53
+ private
54
+ def write_to_disk
55
+ f = open(@filename, 'r+')
56
+ f.flock(File::LOCK_EX)
57
+ db = JSON.parse f.read
58
+ yield db
59
+ ensure
60
+ if f
61
+ if db
62
+ f.rewind
63
+ f.write db.to_json
64
+ f.flush
65
+ f.truncate f.pos
66
+ end
67
+ f.close
69
68
  end
69
+ end
70
70
 
71
- def load_from_disk
72
- f = open(@filename, 'r+')
73
- f.flock(File::LOCK_SH)
74
- db = JSON.parse f.read
75
- yield db
76
- ensure
77
- if f
78
- f.close
79
- end
80
- end
71
+ def load_from_disk
72
+ f = open(@filename, 'r+')
73
+ f.flock(File::LOCK_SH)
74
+ db = JSON.parse f.read
75
+ yield db
76
+ ensure
77
+ if f
78
+ f.close
79
+ end
80
+ end
81
81
 
82
- def each_match(db, query)
83
- db["objects"].clone.each do |obj|
84
- yield(obj) unless not match(obj, query)
85
- end
82
+ def each_match(db, query)
83
+ db["objects"].clone.each do |obj|
84
+ yield(obj) unless not match(obj, query)
86
85
  end
86
+ end
87
87
 
88
- def match(obj, query)
89
- # query is either an array in the form of [key, value] or a hash
90
- # if query is an Array, key is a string, value can be anything
91
- # if value is an array, we should expect a keyword for key
92
- # if value is an hash, we should expect it's only key to be a keyword
93
- # if value is a string or FixNum , we should check for attribute match
94
- # if query is Hash, then we break it into individual queries and recursively call them (as arrays)
95
- if query.kind_of? Array
96
- if query[1].kind_of? Array
97
- case query[0]
98
- when "$or"
99
- match = false
100
- query[1].each do |attr|
101
- is_a_match = match(obj, attr)
102
- match ||= is_a_match
103
- end
104
- return match
105
- else
106
- raise NotImplementedError
107
- end
108
- elsif query[1].kind_of? Hash
109
- match = true
110
- query[1].each do |k,v|
111
- case k
112
- when "$in"
113
- local_match = false
114
- v.each do |value|
115
- is_a_match = match(obj, [query[0], value])
116
- local_match ||= is_a_match
117
- end
118
- match &&= local_match
119
- when "$exists"
120
- match &&= (not obj[query[0]].nil?) == v
121
- when "$nin"
122
- local_match = true
123
- v.each do |value|
124
- is_a_match = match(obj, [query[0], value])
125
- local_match &&= (not is_a_match)
126
- end
127
- match &&= local_match
128
- when "$gt"
129
- return obj[query[0]] > v
130
- when "$gte"
131
- return obj[query[0]] >= v
132
- when "$lt"
133
- return obj[query[0]] < v
134
- when "$lte"
135
- return obj[query[0]] <= v
136
- when "$ne"
137
- return obj[query[0]] != v
138
- when "$mod"
139
- return obj[query[0]] % v[0] == v[1]
140
- else
141
- raise NotImplementedError
142
- end
143
- end
144
- return match
145
- else
146
- match = (obj[query[0]] == query[1])
147
- return match
148
- end
149
- elsif query.kind_of? Hash
150
- match = true
151
- query.to_a.each do |attr|
152
- is_a_match = match(obj, attr)
153
- match &&= is_a_match
154
- end
155
- return match
156
- else
157
- raise NotImplementedError
158
- end
159
- end
88
+ def match(obj, query)
89
+ matcher = Matcher.new(query)
90
+ return matcher.match(obj)
91
+ end
160
92
  end
@@ -0,0 +1,45 @@
1
+ class PredicateMatcher
2
+ def initialize(predicate)
3
+ @predicate = predicate
4
+ end
5
+ def match(value)
6
+ if @predicate.length > 1
7
+ matcher = AndPredicateMatcher.new(@predicate)
8
+ return matcher.match(value)
9
+ end
10
+ case @predicate.keys.first
11
+ when "$exists"
12
+ return @predicate.values.first == !value.nil?
13
+ when "$in"
14
+ return @predicate.values.first.include?(value)
15
+ when "$nin"
16
+ return !@predicate.values.first.include?(value)
17
+ when "$gt"
18
+ return value > @predicate.values.first
19
+ when "$gte"
20
+ return value >= @predicate.values.first
21
+ when "$lt"
22
+ return value < @predicate.values.first
23
+ when "$lte"
24
+ return value <= @predicate.values.first
25
+ when "$ne"
26
+ return value != @predicate.values.first
27
+ when "$mod"
28
+ return value % @predicate.values.first[0] == @predicate.values.first[1]
29
+ else
30
+ raise NotImplementedError
31
+ end
32
+ end
33
+ end
34
+
35
+ class AndPredicateMatcher < PredicateMatcher
36
+ def match(value)
37
+ does_it_match = true
38
+ @predicate.each do |k,v|
39
+ matcher = PredicateMatcher.new({k => v})
40
+ does_it_match &&= matcher.match(value)
41
+ end
42
+ return does_it_match
43
+ end
44
+ end
45
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongolitedb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Hamilton
@@ -17,6 +17,8 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - lib/mongolitedb.rb
20
+ - lib/matcher.rb
21
+ - lib/predicate_matcher.rb
20
22
  homepage: https://github.com/hamiltop/MongoLiteDB
21
23
  licenses: []
22
24
  metadata: {}
@@ -36,7 +38,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
36
38
  version: '0'
37
39
  requirements: []
38
40
  rubyforge_project:
39
- rubygems_version: 2.0.2
41
+ rubygems_version: 2.0.3
40
42
  signing_key:
41
43
  specification_version: 4
42
44
  summary: MongoLiteDB embedded database