poros 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae72d23c993aa92ac6dddd554b07d75019e914a1e0edc703de4fd6259712a1f3
4
- data.tar.gz: 9168cac5343f7c9ca7c49dc8dbc9d5d926b15912e26175b75dc09a235932952a
3
+ metadata.gz: 73a30daa683b2b3f91f9c1145d8a2c663431789e96c5007f1b768358dc984490
4
+ data.tar.gz: bb1a9241edf4c85b0b5029f5a8aedb9f5dc19338ea65bfdbe179c0087654f961
5
5
  SHA512:
6
- metadata.gz: cc3136fe7ad7558e3a4c06b30c2a964a35270c1fc6da66c8720eda6e224b74b339d8f1cbfa8a9ba6f47cd081085869e6d75f009fb00ca4a478982ec96ab7698b
7
- data.tar.gz: c4635bb7871ea244cd378d06e111f5a509bcd82434f56635bfc8da071b8be2a5816191e96eb8e491d3cd9580441b4c28953fa0d24b86fc46acf774c49fa00f1b
6
+ metadata.gz: d4dc72766c3e755d7d8f60a28b9df09ee0dcd9caba027fb1d518daf796e9a9a2afe99b940b1876358e3712b5aad6e275e3b0450c9a10e34dd737195ccb032fe0
7
+ data.tar.gz: d0b24230f41db3041e993b52a79c52fdc4971024b259fb6b95f934924b8d116bca73ebea5f65cbee55021a3714938b8ae86c50e609177503003124a41da961dc
data/.travis.yml CHANGED
@@ -6,4 +6,5 @@ rvm:
6
6
  - 2.3.6
7
7
  - 2.4.3
8
8
  - 2.5.1
9
+ - ruby-head
9
10
  before_install: gem install bundler
data/lib/poros.rb CHANGED
@@ -1,218 +1,16 @@
1
1
  require 'yaml'
2
2
  require 'securerandom'
3
3
 
4
+ require 'poros/instance_methods'
5
+ require 'poros/class_methods'
6
+
4
7
  module Poros
5
- attr_accessor :uuid
8
+ include Poros::InstanceMethods
9
+ include Poros::ClassMethods
10
+
6
11
  def self.included(base)
7
12
  base.class_eval do
8
13
  extend ClassMethods
9
14
  end
10
15
  end
11
-
12
- def uuid
13
- @uuid ||= SecureRandom.uuid
14
- end
15
-
16
- def poros
17
- @poros ||= PorosInfo.new(self)
18
- end
19
-
20
- def destroy
21
- File.delete(poros.file_path)
22
- self.class.remove_from_index(self)
23
- self
24
- end
25
-
26
- def save
27
- File.write(poros.file_path, poros.to_h.to_yaml)
28
- self.class.data_changed = true
29
- self.class.update_index(self)
30
- self
31
- end
32
-
33
- class PorosInfo
34
- def initialize(object)
35
- @object = object
36
- end
37
-
38
- def file_path
39
- @object.class.file_path(@object.uuid)
40
- end
41
-
42
- def to_h
43
- @object.class.poro_attrs.map { |column|
44
- [column, @object.send(column.to_s)]
45
- }.to_h
46
- end
47
- end
48
-
49
- module ClassMethods
50
- attr_accessor :in_transaction, :data_changed
51
-
52
- def poro_attr(*attrs)
53
- @poro_attrs = [:uuid] | attrs
54
- attrs.each { |column|
55
- class_eval "attr_accessor :#{column}"
56
- }
57
- end
58
-
59
- def poro_attrs
60
- @poro_attrs ||= []
61
- end
62
-
63
- def poro_index(*attrs)
64
- @poro_indexes ||= []
65
- @poro_indexes += attrs
66
- end
67
-
68
- def poro_indexes
69
- @poro_indexes ||= []
70
- end
71
-
72
- def find(uuid)
73
- attrs = YAML.load(File.read(file_path(uuid)))
74
- attrs.delete(:uuid)
75
-
76
- object = new(attrs)
77
- object.uuid = uuid
78
- object
79
- end
80
-
81
- def file_path(uuid)
82
- FileUtils.mkdir_p(data_directory) unless File.exist?(data_directory)
83
- File.join(data_directory, file_name(uuid))
84
- end
85
-
86
- def data_directory
87
- "./db/#{self}/"
88
- end
89
-
90
- def file_name(uuid)
91
- "#{uuid}.yml"
92
- end
93
-
94
- def index_file
95
- File.join(data_directory, "indexes.yml")
96
- end
97
-
98
- def all
99
- Dir.glob(File.join(data_directory, '*.yml')).map { |file|
100
- next if file == index_file
101
- data = YAML.load(File.read(file))
102
- find(data[:uuid])
103
- }.compact
104
- end
105
-
106
- def where(query)
107
- indexed, table_scan = query.partition { |index, key| poro_indexes.include?(index) }
108
-
109
- indexed_results = indexed.map { |key, value|
110
- case value
111
- when Regexp
112
- index_data[key].keys.flat_map { |value_name|
113
- index_data[key][value_name] if value =~ value_name
114
- }.compact
115
- when Array
116
- value.flat_map { |value_name| index_data[key][value_name] }
117
- when Proc
118
- index_data[key].keys.flat_map { |value_name|
119
- index_data[key][value_name] if value.call(value_name)
120
- }.compact
121
- else
122
- index_data[key].has_key?(value) ?
123
- index_data[key][value] : []
124
- end
125
- }.inject(:&)
126
-
127
- if table_scan.size > 0
128
- scanned_results = Dir.glob(File.join(data_directory, '*.yml')).map { |file|
129
- next if file == index_file
130
- data = YAML.load(File.read(file))
131
- data[:uuid] if table_scan.all? { |key, value|
132
- case value
133
- when Regexp
134
- value =~ data[key]
135
- when Array
136
- value.include?(data[key])
137
- when Proc
138
- value.call(data[key])
139
- else
140
- data[key] == value
141
- end
142
- }
143
- }.compact
144
- end
145
-
146
- if indexed.size > 0 && table_scan.size > 0
147
- results = indexed_results & scanned_results
148
- elsif indexed.size > 0
149
- results = indexed_results
150
- else
151
- results = scanned_results
152
- end
153
-
154
- results.map { |uuid| find(uuid) }
155
- end
156
-
157
- def index_data
158
- return @index_data if @index_data
159
-
160
- data = File.exist?(index_file) ? YAML.load(File.read(index_file)) : {}
161
- # Make sure we always have every index as a key
162
- poro_indexes.each do |index|
163
- data[index] = {} unless data.has_key?(index)
164
- end
165
-
166
- @index_data = data
167
- end
168
-
169
- def write_index_data
170
- File.write(index_file, @index_data.to_yaml)
171
- end
172
-
173
- def update_index(object)
174
- remove_from_index(object, false)
175
-
176
- index_data
177
-
178
- poro_indexes.each do |index|
179
- @index_data[index] = {} unless @index_data.has_key?(index)
180
- value = object.send(index)
181
- @index_data[index][value] ||= []
182
- @index_data[index][value] = @index_data[index][value] | [object.uuid]
183
- end
184
-
185
- write_index_data unless @in_transaction
186
- end
187
-
188
- def remove_from_index(object, perist = true)
189
- index_data
190
-
191
- poro_indexes.each do |index|
192
- @index_data[index] = {} unless @index_data.has_key?(index)
193
- @index_data[index].keys.each do |value|
194
- @index_data[index][value] ||= []
195
- @index_data[index][value] -= [object.uuid]
196
- end
197
- end
198
- write_index_data if !@in_transaction && perist
199
- end
200
-
201
- def rebuild_indexes
202
- transaction do
203
- @data_changed = true
204
- @index_data = {}
205
- File.delete(index_file) if File.exist?(index_file)
206
- all.each { |object| update_index(object) }
207
- end
208
- end
209
-
210
- def transaction(&block)
211
- @in_transaction = true
212
- @data_changed = false
213
- block.call
214
- @in_transaction = false
215
- write_index_data if @data_changed
216
- end
217
- end
218
16
  end
@@ -0,0 +1,169 @@
1
+ module Poros::ClassMethods
2
+ attr_accessor :in_transaction, :data_changed
3
+
4
+ def poro_attr(*attrs)
5
+ @poro_attrs = [:uuid] | attrs
6
+ attrs.each { |column|
7
+ class_eval "attr_accessor :#{column}"
8
+ }
9
+ end
10
+
11
+ def poro_attrs
12
+ @poro_attrs ||= []
13
+ end
14
+
15
+ def poro_index(*attrs)
16
+ @poro_indexes ||= []
17
+ @poro_indexes += attrs
18
+ end
19
+
20
+ def poro_indexes
21
+ @poro_indexes ||= []
22
+ end
23
+
24
+ def find(uuid)
25
+ attrs = YAML.load(File.read(file_path(uuid)))
26
+ attrs.delete(:uuid)
27
+
28
+ object = new(attrs)
29
+ object.uuid = uuid
30
+ object
31
+ end
32
+
33
+ def file_path(uuid)
34
+ FileUtils.mkdir_p(data_directory) unless File.exist?(data_directory)
35
+ File.join(data_directory, file_name(uuid))
36
+ end
37
+
38
+ def data_directory
39
+ "./db/#{self}/"
40
+ end
41
+
42
+ def file_name(uuid)
43
+ "#{uuid}.yml"
44
+ end
45
+
46
+ def index_file
47
+ File.join(data_directory, "indexes.yml")
48
+ end
49
+
50
+ def all
51
+ Dir.glob(File.join(data_directory, '*.yml')).map { |file|
52
+ next if file == index_file
53
+ data = YAML.load(File.read(file))
54
+ find(data[:uuid])
55
+ }.compact
56
+ end
57
+
58
+ def where(query)
59
+ indexed, table_scan = query.partition { |index, key| poro_indexes.include?(index) }
60
+
61
+ indexed_results = indexed.map { |key, value|
62
+ case value
63
+ when Regexp
64
+ index_data[key].keys.flat_map { |value_name|
65
+ index_data[key][value_name] if value =~ value_name
66
+ }.compact
67
+ when Array
68
+ value.flat_map { |value_name| index_data[key][value_name] }
69
+ when Proc
70
+ index_data[key].keys.flat_map { |value_name|
71
+ index_data[key][value_name] if value.call(value_name)
72
+ }.compact
73
+ else
74
+ index_data[key].has_key?(value) ?
75
+ index_data[key][value] : []
76
+ end
77
+ }.inject(:&)
78
+
79
+ if table_scan.size > 0
80
+ scanned_results = Dir.glob(File.join(data_directory, '*.yml')).map { |file|
81
+ next if file == index_file
82
+ data = YAML.load(File.read(file))
83
+ data[:uuid] if table_scan.all? { |key, value|
84
+ case value
85
+ when Regexp
86
+ value =~ data[key]
87
+ when Array
88
+ value.include?(data[key])
89
+ when Proc
90
+ value.call(data[key])
91
+ else
92
+ data[key] == value
93
+ end
94
+ }
95
+ }.compact
96
+ end
97
+
98
+ if indexed.size > 0 && table_scan.size > 0
99
+ results = indexed_results & scanned_results
100
+ elsif indexed.size > 0
101
+ results = indexed_results
102
+ else
103
+ results = scanned_results
104
+ end
105
+
106
+ results.map { |uuid| find(uuid) }
107
+ end
108
+
109
+ def index_data
110
+ return @index_data if @index_data
111
+
112
+ data = File.exist?(index_file) ? YAML.load(File.read(index_file)) : {}
113
+ # Make sure we always have every index as a key
114
+ poro_indexes.each do |index|
115
+ data[index] = {} unless data.has_key?(index)
116
+ end
117
+
118
+ @index_data = data
119
+ end
120
+
121
+ def write_index_data
122
+ File.write(index_file, @index_data.to_yaml)
123
+ end
124
+
125
+ def update_index(object)
126
+ remove_from_index(object, false)
127
+
128
+ index_data
129
+
130
+ poro_indexes.each do |index|
131
+ @index_data[index] = {} unless @index_data.has_key?(index)
132
+ value = object.send(index)
133
+ @index_data[index][value] ||= []
134
+ @index_data[index][value] = @index_data[index][value] | [object.uuid]
135
+ end
136
+
137
+ write_index_data unless @in_transaction
138
+ end
139
+
140
+ def remove_from_index(object, perist = true)
141
+ index_data
142
+
143
+ poro_indexes.each do |index|
144
+ @index_data[index] = {} unless @index_data.has_key?(index)
145
+ @index_data[index].keys.each do |value|
146
+ @index_data[index][value] ||= []
147
+ @index_data[index][value] -= [object.uuid]
148
+ end
149
+ end
150
+ write_index_data if !@in_transaction && perist
151
+ end
152
+
153
+ def rebuild_indexes
154
+ transaction do
155
+ @data_changed = true
156
+ @index_data = {}
157
+ File.delete(index_file) if File.exist?(index_file)
158
+ all.each { |object| update_index(object) }
159
+ end
160
+ end
161
+
162
+ def transaction(&block)
163
+ @in_transaction = true
164
+ @data_changed = false
165
+ block.call
166
+ @in_transaction = false
167
+ write_index_data if @data_changed
168
+ end
169
+ end
data/lib/poros/info.rb ADDED
@@ -0,0 +1,16 @@
1
+ class Poros::Info
2
+ def initialize(object)
3
+ @object = object
4
+ end
5
+
6
+ def file_path
7
+ @object.class.file_path(@object.uuid)
8
+ end
9
+
10
+ def to_h
11
+ @object.class.poro_attrs.map { |column|
12
+ [column, @object.send(column.to_s)]
13
+ }.to_h
14
+ end
15
+ end
16
+
@@ -0,0 +1,25 @@
1
+ require 'poros/info'
2
+
3
+ module Poros::InstanceMethods
4
+ attr_accessor :uuid
5
+ def uuid
6
+ @uuid ||= SecureRandom.uuid
7
+ end
8
+
9
+ def poros
10
+ @poros ||= Poros::Info.new(self)
11
+ end
12
+
13
+ def destroy
14
+ File.delete(poros.file_path)
15
+ self.class.remove_from_index(self)
16
+ self
17
+ end
18
+
19
+ def save
20
+ File.write(poros.file_path, poros.to_h.to_yaml)
21
+ self.class.data_changed = true
22
+ self.class.update_index(self)
23
+ self
24
+ end
25
+ end
data/lib/poros/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Poros
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poros
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Ross Earle
@@ -66,6 +66,9 @@ files:
66
66
  - README.md
67
67
  - Rakefile
68
68
  - lib/poros.rb
69
+ - lib/poros/class_methods.rb
70
+ - lib/poros/info.rb
71
+ - lib/poros/instance_methods.rb
69
72
  - lib/poros/version.rb
70
73
  - poros.gemspec
71
74
  homepage: https://github.com/HellRok/YAMLCache