zermelo 1.0.1 → 1.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.travis.yml +3 -5
  4. data/CHANGELOG.md +8 -2
  5. data/lib/zermelo/associations/belongs_to.rb +3 -3
  6. data/lib/zermelo/associations/has_and_belongs_to_many.rb +3 -3
  7. data/lib/zermelo/associations/has_many.rb +3 -3
  8. data/lib/zermelo/associations/has_one.rb +3 -3
  9. data/lib/zermelo/associations/has_sorted_set.rb +4 -4
  10. data/lib/zermelo/associations/index.rb +1 -2
  11. data/lib/zermelo/associations/unique_index.rb +1 -2
  12. data/lib/zermelo/backends/base.rb +1 -1
  13. data/lib/zermelo/backends/influxdb_backend.rb +29 -18
  14. data/lib/zermelo/backends/redis_backend.rb +106 -6
  15. data/lib/zermelo/filters/base.rb +34 -57
  16. data/lib/zermelo/filters/influxdb_filter.rb +22 -70
  17. data/lib/zermelo/filters/redis_filter.rb +35 -482
  18. data/lib/zermelo/filters/steps/list_step.rb +79 -0
  19. data/lib/zermelo/filters/steps/set_step.rb +176 -0
  20. data/lib/zermelo/filters/steps/sort_step.rb +85 -0
  21. data/lib/zermelo/filters/steps/sorted_set_step.rb +156 -0
  22. data/lib/zermelo/records/class_methods.rb +16 -4
  23. data/lib/zermelo/records/influxdb_record.rb +2 -0
  24. data/lib/zermelo/records/instance_methods.rb +4 -4
  25. data/lib/zermelo/records/key.rb +2 -0
  26. data/lib/zermelo/version.rb +1 -1
  27. data/lib/zermelo.rb +9 -1
  28. data/spec/lib/zermelo/records/influxdb_record_spec.rb +186 -10
  29. data/spec/lib/zermelo/records/redis_record_spec.rb +11 -4
  30. data/spec/spec_helper.rb +12 -10
  31. metadata +5 -11
  32. data/lib/zermelo/filters/steps/diff_range_step.rb +0 -17
  33. data/lib/zermelo/filters/steps/diff_step.rb +0 -17
  34. data/lib/zermelo/filters/steps/intersect_range_step.rb +0 -17
  35. data/lib/zermelo/filters/steps/intersect_step.rb +0 -17
  36. data/lib/zermelo/filters/steps/limit_step.rb +0 -17
  37. data/lib/zermelo/filters/steps/offset_step.rb +0 -17
  38. data/lib/zermelo/filters/steps/union_range_step.rb +0 -17
  39. data/lib/zermelo/filters/steps/union_step.rb +0 -17
  40. data/lib/zermelo/records/collection.rb +0 -14
@@ -10,7 +10,7 @@ module Zermelo
10
10
 
11
11
  def _exists?(id)
12
12
  return if id.nil?
13
- @steps << Zermelo::Filters::Steps::IntersectStep.new({}, {:id => id})
13
+ @steps << Zermelo::Filters::Steps::SetStep.new({:op => :intersect}, {:id => id})
14
14
  resolve_steps(:count) > 0
15
15
  end
16
16
 
@@ -27,46 +27,6 @@ module Zermelo
27
27
  resolve_steps(:count)
28
28
  end
29
29
 
30
- def resolve_step(step)
31
- query = ''
32
-
33
- options = step.options || {}
34
- values = step.attributes
35
-
36
- case step
37
- when Zermelo::Filters::Steps::IntersectStep,
38
- Zermelo::Filters::Steps::UnionStep
39
-
40
- query += values.collect {|k, v|
41
- op, value = case v
42
- when String
43
- ["=~", "/^#{Regexp.escape(v).gsub(/\\\\/, "\\")}$/"]
44
- else
45
- ["=", "'#{v}'"]
46
- end
47
-
48
- "#{k} #{op} #{value}"
49
- }.join(' AND ')
50
-
51
- when Zermelo::Filters::Steps::DiffStep
52
-
53
- query += values.collect {|k, v|
54
- op, value = case v
55
- when String
56
- ["!~", "/^#{Regexp.escape(v).gsub(/\\\\/, "\\")}$/"]
57
- else
58
- ["!=", "'#{v}'"]
59
- end
60
-
61
- "#{k} #{op} #{value}"
62
- }.join(' AND ')
63
- else
64
- raise "Unhandled filter operation '#{step_type}'"
65
- end
66
-
67
- query
68
- end
69
-
70
30
  def escaped_id(id)
71
31
  if id.is_a?(Numeric)
72
32
  id
@@ -76,64 +36,56 @@ module Zermelo
76
36
  end
77
37
 
78
38
  def resolve_steps(result_type)
39
+ class_key = @associated_class.send(:class_key)
40
+
79
41
  query = case result_type
80
42
  when :ids
81
- "SELECT id FROM /#{@associated_class.send(:class_key)}\\/.*/"
43
+ "SELECT id FROM /#{class_key}\\/.*/"
82
44
  when :count
83
- "SELECT COUNT(id) FROM /#{@associated_class.send(:class_key)}\\/.*/"
45
+ "SELECT COUNT(id) FROM /#{class_key}\\/.*/"
84
46
  end
85
47
 
86
- unless @initial_set.id.nil?
48
+ unless @initial_key.id.nil?
87
49
  query += ' WHERE '
88
50
 
89
- ii_query = "SELECT #{@initial_set.name} FROM \"#{@initial_set.klass}/#{@initial_set.id}\" " +
51
+ initial_class_key = @initial_key.klass.send(:class_key)
52
+
53
+ ii_query = "SELECT #{@initial_key.name} FROM \"#{initial_class_key}/#{@initial_key.id}\" " +
90
54
  "LIMIT 1"
91
55
 
92
56
  begin
93
57
  initial_id_data =
94
- Zermelo.influxdb.query(ii_query)["#{@initial_set.klass}/#{@initial_set.id}"]
58
+ Zermelo.influxdb.query(ii_query)["#{initial_class_key}/#{@initial_key.id}"]
95
59
  rescue InfluxDB::Error => ide
96
60
  raise unless
97
- /^Field #{@initial_set.name} doesn't exist in series #{@initial_set.klass}\/#{@initial_set.id}$/ === ide.message
61
+ /^Field #{@initial_key.name} doesn't exist in series #{initial_class_key}\/#{@initial_key.id}$/ === ide.message
98
62
 
99
63
  initial_id_data = nil
100
64
  end
101
65
 
102
66
  return [] if initial_id_data.nil?
103
67
 
104
- inital_ids = initial_id_data.first[@initial_set.name]
68
+ initial_ids = initial_id_data.first[@initial_key.name]
105
69
 
106
- if inital_ids.nil? || inital_ids.empty?
70
+ if initial_ids.nil? || initial_ids.empty?
107
71
  # make it impossible for the query to return anything
108
72
  query += '(1 = 0)'
109
73
  else
110
- query += '((' + inital_ids.collect {|id|
74
+ query += '((' + initial_ids.collect {|id|
111
75
  "id = #{escaped_id(id)}"
112
76
  }.join(') OR (') + '))'
113
77
  end
114
78
  end
115
79
 
116
80
  unless @steps.empty?
117
- query += (@initial_set.id.nil? ? ' WHERE ' : ' AND ') +
81
+ query += (@initial_key.id.nil? ? ' WHERE ' : ' AND ') +
118
82
  ('(' * @steps.size)
119
83
 
120
- @steps.each_with_index do |step, idx|
121
- if idx > 0
122
- case step
123
- when Zermelo::Filters::Steps::IntersectStep,
124
- Zermelo::Filters::Steps::DiffStep
125
- query += ' AND '
126
- when Zermelo::Filters::Steps::UnionStep
127
- query += ' OR '
128
- else
129
- raise "Unhandled filter operation '#{step.class.name}'"
130
- end
131
- end
132
-
133
- query += resolve_step(step)
134
-
135
- query += ")"
136
- end
84
+ first_step = steps.first
85
+
86
+ query += @steps.collect {|step|
87
+ step.resolve(backend, @associated_class, :first => (step == first_step))
88
+ }.join("")
137
89
  end
138
90
 
139
91
  query += " LIMIT 1"
@@ -145,11 +97,11 @@ module Zermelo
145
97
  result = {}
146
98
  end
147
99
 
148
- data_keys = result.keys.select {|k| k =~ /^#{@associated_class.send(:class_key)}\// }
100
+ data_keys = result.keys.select {|k| k =~ /^#{class_key}\// }
149
101
 
150
102
  case result_type
151
103
  when :ids
152
- data_keys.empty? ? [] : data_keys.collect {|k| k =~ /^#{@associated_class.send(:class_key)}\/(.+)$/; $1 }
104
+ data_keys.empty? ? [] : data_keys.collect {|k| k =~ /^#{class_key}\/(.+)$/; $1 }
153
105
  when :count
154
106
  data_keys.empty? ? 0 : data_keys.inject(0) do |memo, k|
155
107
  memo += result[k].first['count']