rffdb 0.0.8 → 0.1.0

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: 2ac408fa55b4135737e2c26d4d1ebdb208951278
4
- data.tar.gz: 362c818f4cd7435d248f9ccbe5ce85c602f494de
3
+ metadata.gz: b46b42ee1876f919030207416134f7cf94b4250a
4
+ data.tar.gz: 9c232c54e21b2939b651bfb8c758dff486fbe107
5
5
  SHA512:
6
- metadata.gz: c0fe51088853821a6a109b91386fc68f3ebae4e596304b14151179293d1976ebb5949d8f7d9e649d67784d327325c5d7d42f95e05e93b891afb0136d05fc06bf
7
- data.tar.gz: b8412b293f6b541c728f1ce6bdf479a32a1482e15a154d5d40d09a489cade1340bd81150d702a7d7c2509e36e0c26686ecf75b5f3394c620a60af72d618d7e8a
6
+ metadata.gz: bbef6842d8e3b86a1317dca7e5a0a5f2ff4453a45abd382210511780ae2d349c1870045f1fae38c31779303572ab4cd7bb8f9e41488bbc567807e4a5fc02389c
7
+ data.tar.gz: 6d326d41d2daade93ffe1da82d043fb18385bda30ac80e4605edf0c1377f970ef685fc0522d3ac690eead523e17f92bb8464fb34204242c2fff7c4fcfd548b8f
@@ -36,7 +36,9 @@ module RubyFFDB
36
36
  def commit
37
37
  @read_lock.synchronize do
38
38
  @write_lock.synchronize do
39
- storage.store(self.class, @id, @data.dup) unless @saved
39
+ unless @saved
40
+ storage.store(self.class, @id, @data.dup)
41
+ end
40
42
  @saved = true
41
43
  end
42
44
  end
@@ -115,6 +117,8 @@ module RubyFFDB
115
117
  options.key?(:validate) ? [*options[:validate]] : []
116
118
  @structure[name.to_sym][:unique] =
117
119
  options.key?(:unique) == true ? true : false
120
+ @structure[name.to_sym][:index] =
121
+ options.key?(:index) == true ? true : false
118
122
  end
119
123
 
120
124
  # This DSL method is used to setup the backend {StorageEngine} class and
@@ -199,7 +203,14 @@ module RubyFFDB
199
203
  # Query for Documents based on an attribute
200
204
  # @see DocumentCollection#where
201
205
  def self.where(attribute, value, comparison_method = '==')
202
- all.where(attribute, value, comparison_method)
206
+ if comparison_method.to_s == '==' && indexed_column?(attribute)
207
+ DocumentCollection.new(
208
+ storage.index(self, attribute).get(value).collect { |did| load(did) },
209
+ self
210
+ )
211
+ else
212
+ all.where(attribute, value, comparison_method)
213
+ end
203
214
  end
204
215
 
205
216
  # Compare two documents
@@ -207,6 +218,17 @@ module RubyFFDB
207
218
  id <=> other.id
208
219
  end
209
220
 
221
+ # Should this column be indexed?
222
+ # @return [Boolean]
223
+ def self.indexed_column?(column)
224
+ csym = column.to_sym
225
+ structure.key?(csym) && structure[csym][:index] == true
226
+ end
227
+
228
+ def indexed_column?(column)
229
+ self.class.send('indexed_column?'.to_sym, column)
230
+ end
231
+
210
232
  # Uses the defined schema to setup getter and setter methods. Runs
211
233
  # validations, format checking, and type checking on setting methods.
212
234
  # @todo refactor and comment better
@@ -237,9 +259,14 @@ module RubyFFDB
237
259
  @read_lock.synchronize { committed? }
238
260
  @read_lock.synchronize do
239
261
  @write_lock.synchronize do
240
- @data[key.to_s] = args.last if valid
262
+ if valid
263
+ storage.index(self.class, key).delete(@data[key.to_s], id) if indexed_column?(key)
264
+ @data[key.to_s] = args.last
265
+ storage.index(self.class, key).put(args.last, id) if indexed_column?(key)
266
+ end
241
267
  end
242
268
  end
269
+ commit if indexed_column?(key) # indexed columns always cause commits
243
270
  else
244
271
  fail Exceptions::InvalidInput
245
272
  end
@@ -282,5 +309,6 @@ module RubyFFDB
282
309
  end
283
310
  end
284
311
  end
312
+
285
313
  end
286
314
  end
@@ -0,0 +1,53 @@
1
+ module RubyFFDB
2
+ class Index
3
+ def initialize(type, column)
4
+ @type = type
5
+ @column = column
6
+ FileUtils.mkdir_p(File.dirname(file_path))
7
+ GDBM.open(file_path, 0664, GDBM::WRCREAT) do
8
+ # Index initialized
9
+ end
10
+ end
11
+
12
+ def file_path
13
+ File.join(
14
+ DB_DATA,
15
+ @type.to_s.gsub('::', '__'),
16
+ 'indexes',
17
+ @column.to_s + '.index'
18
+ )
19
+ end
20
+
21
+ def get(key)
22
+ GDBM.open(file_path, 0664, GDBM::READER) do |index|
23
+ Marshal.load index.fetch(key.to_s, Marshal.dump([]))
24
+ end
25
+ end
26
+
27
+ def put(key, value)
28
+ previous = get(key)
29
+ GDBM.open(file_path, 0664, GDBM::WRCREAT) do |index|
30
+ index[key.to_s] = Marshal.dump((previous + [value]).uniq)
31
+ end
32
+ end
33
+
34
+ def delete(key, value)
35
+ previous = get(key)
36
+ GDBM.open(file_path, 0664, GDBM::WRCREAT) do |index|
37
+ index[key.to_s] = Marshal.dump((previous - [value]).uniq)
38
+ end
39
+ end
40
+
41
+ def truncate(key)
42
+ GDBM.open(file_path, 0664, GDBM::WRCREAT) do |index|
43
+ index.delete(key.to_s)
44
+ end
45
+ end
46
+
47
+ def keys
48
+ GDBM.open(file_path, 0664, GDBM::READER) do |index|
49
+ index.keys
50
+ end
51
+ end
52
+ end
53
+ end
@@ -130,5 +130,14 @@ module RubyFFDB
130
130
  @caches ||= {}
131
131
  @caches[type] ||= CacheProviders::LRUCache.new
132
132
  end
133
+
134
+ # Allows direct access to an index for a Document type and column
135
+ # @param type [Document] the document type
136
+ # @param column [String,Symbol] the column / attribute for the index
137
+ def self.index(type, column)
138
+ @indexes ||= {}
139
+ @indexes[type] ||= {}
140
+ @indexes[type][column.to_sym] ||= Index.new(type, column.to_sym)
141
+ end
133
142
  end
134
143
  end
data/lib/rffdb/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RubyFFDB
2
- VERSION = [0, 0, 8].join('.')
2
+ VERSION = [0, 1, 0].join('.')
3
3
  end
data/lib/rffdb.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'ostruct'
2
+ require 'gdbm'
2
3
  require 'rffdb/version'
3
4
  require 'rffdb/constants'
4
5
  require 'rffdb/exception'
@@ -6,6 +7,7 @@ require 'rffdb/exceptions/cache_exceptions'
6
7
  require 'rffdb/exceptions/document_exceptions'
7
8
  require 'rffdb/cache_provider'
8
9
  require 'rffdb/cache_providers/lru_cache'
10
+ require 'rffdb/index'
9
11
  require 'rffdb/storage_engine'
10
12
  require 'rffdb/storage_engines/yaml_engine'
11
13
  require 'rffdb/document'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rffdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Gnagy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-30 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -42,6 +42,7 @@ files:
42
42
  - lib/rffdb/exception.rb
43
43
  - lib/rffdb/exceptions/cache_exceptions.rb
44
44
  - lib/rffdb/exceptions/document_exceptions.rb
45
+ - lib/rffdb/index.rb
45
46
  - lib/rffdb/storage_engine.rb
46
47
  - lib/rffdb/storage_engines/json_engine.rb
47
48
  - lib/rffdb/storage_engines/yaml_engine.rb