zermelo 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +10 -0
  4. data/.travis.yml +27 -0
  5. data/Gemfile +20 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +512 -0
  8. data/Rakefile +1 -0
  9. data/lib/zermelo/associations/association_data.rb +24 -0
  10. data/lib/zermelo/associations/belongs_to.rb +115 -0
  11. data/lib/zermelo/associations/class_methods.rb +244 -0
  12. data/lib/zermelo/associations/has_and_belongs_to_many.rb +128 -0
  13. data/lib/zermelo/associations/has_many.rb +120 -0
  14. data/lib/zermelo/associations/has_one.rb +109 -0
  15. data/lib/zermelo/associations/has_sorted_set.rb +124 -0
  16. data/lib/zermelo/associations/index.rb +50 -0
  17. data/lib/zermelo/associations/index_data.rb +18 -0
  18. data/lib/zermelo/associations/unique_index.rb +44 -0
  19. data/lib/zermelo/backends/base.rb +115 -0
  20. data/lib/zermelo/backends/influxdb_backend.rb +178 -0
  21. data/lib/zermelo/backends/redis_backend.rb +281 -0
  22. data/lib/zermelo/filters/base.rb +235 -0
  23. data/lib/zermelo/filters/influxdb_filter.rb +162 -0
  24. data/lib/zermelo/filters/redis_filter.rb +558 -0
  25. data/lib/zermelo/filters/steps/base_step.rb +22 -0
  26. data/lib/zermelo/filters/steps/diff_range_step.rb +17 -0
  27. data/lib/zermelo/filters/steps/diff_step.rb +17 -0
  28. data/lib/zermelo/filters/steps/intersect_range_step.rb +17 -0
  29. data/lib/zermelo/filters/steps/intersect_step.rb +17 -0
  30. data/lib/zermelo/filters/steps/limit_step.rb +17 -0
  31. data/lib/zermelo/filters/steps/offset_step.rb +17 -0
  32. data/lib/zermelo/filters/steps/sort_step.rb +17 -0
  33. data/lib/zermelo/filters/steps/union_range_step.rb +17 -0
  34. data/lib/zermelo/filters/steps/union_step.rb +17 -0
  35. data/lib/zermelo/locks/no_lock.rb +16 -0
  36. data/lib/zermelo/locks/redis_lock.rb +221 -0
  37. data/lib/zermelo/records/base.rb +62 -0
  38. data/lib/zermelo/records/class_methods.rb +127 -0
  39. data/lib/zermelo/records/collection.rb +14 -0
  40. data/lib/zermelo/records/errors.rb +24 -0
  41. data/lib/zermelo/records/influxdb_record.rb +35 -0
  42. data/lib/zermelo/records/instance_methods.rb +224 -0
  43. data/lib/zermelo/records/key.rb +19 -0
  44. data/lib/zermelo/records/redis_record.rb +27 -0
  45. data/lib/zermelo/records/type_validator.rb +20 -0
  46. data/lib/zermelo/version.rb +3 -0
  47. data/lib/zermelo.rb +102 -0
  48. data/spec/lib/zermelo/associations/belongs_to_spec.rb +6 -0
  49. data/spec/lib/zermelo/associations/has_many_spec.rb +6 -0
  50. data/spec/lib/zermelo/associations/has_one_spec.rb +6 -0
  51. data/spec/lib/zermelo/associations/has_sorted_set.spec.rb +6 -0
  52. data/spec/lib/zermelo/associations/index_spec.rb +6 -0
  53. data/spec/lib/zermelo/associations/unique_index_spec.rb +6 -0
  54. data/spec/lib/zermelo/backends/influxdb_backend_spec.rb +0 -0
  55. data/spec/lib/zermelo/backends/moneta_backend_spec.rb +0 -0
  56. data/spec/lib/zermelo/filters/influxdb_filter_spec.rb +0 -0
  57. data/spec/lib/zermelo/filters/redis_filter_spec.rb +0 -0
  58. data/spec/lib/zermelo/locks/redis_lock_spec.rb +170 -0
  59. data/spec/lib/zermelo/records/influxdb_record_spec.rb +258 -0
  60. data/spec/lib/zermelo/records/key_spec.rb +6 -0
  61. data/spec/lib/zermelo/records/redis_record_spec.rb +1426 -0
  62. data/spec/lib/zermelo/records/type_validator_spec.rb +6 -0
  63. data/spec/lib/zermelo/version_spec.rb +6 -0
  64. data/spec/lib/zermelo_spec.rb +6 -0
  65. data/spec/spec_helper.rb +67 -0
  66. data/spec/support/profile_all_formatter.rb +44 -0
  67. data/spec/support/uncolored_doc_formatter.rb +74 -0
  68. data/zermelo.gemspec +30 -0
  69. metadata +174 -0
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+ require 'zermelo/records/influxdb_record'
3
+
4
+ describe Zermelo::Records::InfluxDBRecord, :influxdb => true do
5
+
6
+ module Zermelo
7
+ class InfluxDBExample
8
+ include Zermelo::Records::InfluxDBRecord
9
+
10
+ define_attributes :name => :string,
11
+ :email => :string,
12
+ :active => :boolean
13
+
14
+ validates :name, :presence => true
15
+
16
+ has_many :children, :class_name => 'Zermelo::InfluxDBExampleChild'
17
+
18
+ end
19
+
20
+ class InfluxDBExampleChild
21
+ include Zermelo::Records::InfluxDBRecord
22
+
23
+ define_attributes :name => :string,
24
+ :important => :boolean
25
+
26
+ belongs_to :example, :class_name => 'Zermelo::InfluxDBExample', :inverse_of => :children
27
+
28
+ validates :name, :presence => true
29
+ end
30
+ end
31
+
32
+ def create_example(attrs = {})
33
+ Zermelo.influxdb.write_point("influx_db_example/#{attrs[:id]}", attrs)
34
+ end
35
+
36
+ let(:influxdb) { Zermelo.influxdb }
37
+
38
+ it "is invalid without a name" do
39
+ example = Zermelo::InfluxDBExample.new(:id => '1',
40
+ :email => 'jsmith@example.com', :active => true)
41
+ expect(example).not_to be_valid
42
+
43
+ errs = example.errors
44
+ expect(errs).not_to be_nil
45
+ expect(errs[:name]).to eq(["can't be blank"])
46
+ end
47
+
48
+ it "adds a record's attributes to influxdb" do
49
+ begin
50
+ data = Zermelo.influxdb.query("select * from /influx_db_example\\/1/")['influx_db_example/1']
51
+ expect(data).to be_nil
52
+ rescue InfluxDB::Error => ide
53
+ # only happens occasionally, with an empty time series by that name
54
+ raise unless /^Couldn't look up columns$/ === ide.message
55
+ end
56
+
57
+ example = Zermelo::InfluxDBExample.new(:id => '1', :name => 'John Smith',
58
+ :email => 'jsmith@example.com', :active => true)
59
+ expect(example).to be_valid
60
+ expect(example.save).to be_truthy
61
+
62
+ data = Zermelo.influxdb.query("select * from /influx_db_example\\/1/")['influx_db_example/1']
63
+ expect(data).to be_an(Array)
64
+ expect(data.size).to eql(1)
65
+ record = data.first
66
+ expect(record).to be_a(Hash)
67
+ # FIXME boolean is stringified as redis needs it to be like that --
68
+ # should probably make this backend-dependent
69
+ expect(record).to include("name"=>"John Smith",
70
+ "email"=>"jsmith@example.com", "active"=>"true", "id"=>"1")
71
+ end
72
+
73
+ it "finds a record by id in influxdb" do
74
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
75
+ :active => 'true')
76
+
77
+ example = Zermelo::InfluxDBExample.find_by_id('1')
78
+ expect(example).not_to be_nil
79
+
80
+ expect(example).to respond_to(:name)
81
+ expect(example.name).to eql('Jane Doe')
82
+ expect(example).to respond_to(:email)
83
+ expect(example.email).to eql('jdoe@example.com')
84
+ expect(example).to respond_to(:active)
85
+ expect(example.active).to be true
86
+ end
87
+
88
+ it "can update a value in influxdb" do
89
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
90
+ :active => 'true')
91
+
92
+ example = Zermelo::InfluxDBExample.find_by_id('1')
93
+ expect(example).not_to be_nil
94
+
95
+ example.name = 'John Smith'
96
+ example.save
97
+
98
+ other_example = Zermelo::InfluxDBExample.find_by_id('1')
99
+ expect(other_example).not_to be_nil
100
+ expect(other_example.name).to eq('John Smith')
101
+ end
102
+
103
+ it "destroys a single record from influxdb" do
104
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
105
+ :active => 'true')
106
+
107
+ example = Zermelo::InfluxDBExample.find_by_id('1')
108
+ example.destroy
109
+ example_chk = Zermelo::InfluxDBExample.find_by_id('1')
110
+ expect(example_chk).to be_nil
111
+ end
112
+
113
+ it "resets changed state on refresh" do
114
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
115
+ :active => 'true')
116
+ example = Zermelo::InfluxDBExample.find_by_id('1')
117
+
118
+ example.name = "King Henry VIII"
119
+ expect(example.changed).to include('name')
120
+ expect(example.changes).to eq({'name' => ['Jane Doe', 'King Henry VIII']})
121
+
122
+ example.refresh
123
+ expect(example.changed).to be_empty
124
+ expect(example.changes).to be_empty
125
+ end
126
+
127
+ context 'filters' do
128
+
129
+ it "returns all record ids" do
130
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
131
+ :active => 'true')
132
+ create_example(:id => '2', :name => 'John Smith',
133
+ :email => 'jsmith@example.com', :active => 'false')
134
+
135
+ examples = Zermelo::InfluxDBExample.ids
136
+ expect(examples).not_to be_nil
137
+ expect(examples).to be_an(Array)
138
+ expect(examples.size).to eq(2)
139
+ expect(examples).to contain_exactly('2', '1')
140
+ end
141
+
142
+ it "returns a count of records" do
143
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
144
+ :active => 'true')
145
+ create_example(:id => '2', :name => 'John Smith',
146
+ :email => 'jsmith@example.com', :active => 'false')
147
+
148
+ example_count = Zermelo::InfluxDBExample.count
149
+ expect(example_count).not_to be_nil
150
+ expect(example_count).to be_an(Integer)
151
+ expect(example_count).to eq(2)
152
+ end
153
+
154
+ it "returns all records" do
155
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
156
+ :active => 'true')
157
+ create_example(:id => '2', :name => 'John Smith',
158
+ :email => 'jsmith@example.com', :active => 'false')
159
+
160
+ examples = Zermelo::InfluxDBExample.all
161
+ expect(examples).not_to be_nil
162
+ expect(examples).to be_an(Array)
163
+ expect(examples.size).to eq(2)
164
+ expect(examples.map(&:id)).to contain_exactly('2', '1')
165
+ end
166
+
167
+ it "filters all class records by attribute values" do
168
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
169
+ :active => 'true')
170
+ create_example(:id => '2', :name => 'John Smith',
171
+ :email => 'jsmith@example.com', :active => 'false')
172
+
173
+ example = Zermelo::InfluxDBExample.intersect(:active => true).all
174
+ expect(example).not_to be_nil
175
+ expect(example).to be_an(Array)
176
+ expect(example.size).to eq(1)
177
+ expect(example.map(&:id)).to eq(['1'])
178
+ end
179
+
180
+ it "chains two intersect filters together" do
181
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
182
+ :active => 'true')
183
+ create_example(:id => '2', :name => 'John Smith',
184
+ :email => 'jsmith@example.com', :active => 'false')
185
+ create_example(:id => '3', :name => 'Fred Bloggs',
186
+ :email => 'fbloggs@example.com', :active => 'true')
187
+
188
+ example = Zermelo::InfluxDBExample.intersect(:active => true).
189
+ intersect(:name => 'Jane Doe').all
190
+ expect(example).not_to be_nil
191
+ expect(example).to be_an(Array)
192
+ expect(example.size).to eq(1)
193
+ expect(example.map(&:id)).to eq(['1'])
194
+ end
195
+
196
+ it "chains an intersect and a union filter together" do
197
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
198
+ :active => 'true')
199
+ create_example(:id => '2', :name => 'John Smith',
200
+ :email => 'jsmith@example.com', :active => 'false')
201
+ create_example(:id => '3', :name => 'Fred Bloggs',
202
+ :email => 'fbloggs@example.com', :active => 'false')
203
+
204
+ example = Zermelo::InfluxDBExample.intersect(:active => true).union(:name => 'Fred Bloggs').all
205
+ expect(example).not_to be_nil
206
+ expect(example).to be_an(Array)
207
+ expect(example.size).to eq(2)
208
+ expect(example.map(&:id)).to contain_exactly('3', '1')
209
+ end
210
+
211
+ it "chains an intersect and a diff filter together" do
212
+ create_example(:id => '1', :name => 'Jane Doe', :email => 'jdoe@example.com',
213
+ :active => 'true')
214
+ create_example(:id => '2', :name => 'John Smith',
215
+ :email => 'jsmith@example.com', :active => 'false')
216
+ create_example(:id => '3', :name => 'Fred Bloggs',
217
+ :email => 'fbloggs@example.com', :active => 'false')
218
+
219
+ example = Zermelo::InfluxDBExample.intersect(:active => false).diff(:name => 'Fred Bloggs').all
220
+ expect(example).not_to be_nil
221
+ expect(example).to be_an(Array)
222
+ expect(example.size).to eq(1)
223
+ expect(example.map(&:id)).to eq(['2'])
224
+ end
225
+
226
+ end
227
+
228
+ context 'has_many association' do
229
+
230
+ # def create_child(attrs = {})
231
+ # Zermelo.influxdb.write_point('influx_db_example_child', attrs)
232
+ # end
233
+
234
+ it "sets a parent/child has_many relationship between two records in influxdb" do
235
+ create_example(:id => '8', :name => 'John Jones',
236
+ :email => 'jjones@example.com', :active => 'true')
237
+
238
+ child = Zermelo::InfluxDBExampleChild.new(:id => '3', :name => 'Abel Tasman')
239
+ expect(child.save).to be_truthy
240
+
241
+ example = Zermelo::InfluxDBExample.find_by_id('8')
242
+
243
+ children = example.children.all
244
+
245
+ expect(children).to be_an(Array)
246
+ expect(children).to be_empty
247
+
248
+ example.children << child
249
+
250
+ children = example.children.all
251
+
252
+ expect(children).to be_an(Array)
253
+ expect(children.size).to eq(1)
254
+ end
255
+
256
+ end
257
+
258
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'zermelo/records/key'
3
+
4
+ describe Zermelo::Records::Key do
5
+
6
+ end