orientdb 0.0.8-jruby → 0.0.9-jruby

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.8
1
+ 0.0.9
data/lib/orientdb.rb CHANGED
@@ -26,4 +26,5 @@ require 'orientdb/database'
26
26
  require 'orientdb/record'
27
27
  require 'orientdb/document'
28
28
  require 'orientdb/sql_query'
29
+ require 'orientdb/sql'
29
30
  require 'orientdb/oclass'
@@ -16,7 +16,7 @@ module OrientDB
16
16
  RemoteStorage = com.orientechnologies.orient.client.remote.OStorageRemote
17
17
  Schema = com.orientechnologies.orient.core.metadata.schema.OSchema
18
18
  SchemaType = com.orientechnologies.orient.core.metadata.schema.OType
19
- SQLQuery = com.orientechnologies.orient.core.sql.query.OSQLSynchQuery
19
+ SQLSynchQuery = com.orientechnologies.orient.core.sql.query.OSQLSynchQuery
20
20
  SQLCommand = com.orientechnologies.orient.core.sql.OCommandSQL
21
21
  User = com.orientechnologies.orient.core.metadata.security.OUser
22
22
 
@@ -31,9 +31,6 @@ class OrientDB::Database
31
31
  native_query sql_query
32
32
  end
33
33
 
34
- alias :find :query
35
- alias :all :query
36
-
37
34
  def first(sql_query = nil)
38
35
  sql_query = prepare_sql_query(sql_query).setLimit(1)
39
36
  query(sql_query).first
@@ -42,57 +39,17 @@ class OrientDB::Database
42
39
  def prepare_sql_query(sql_query)
43
40
  return if sql_query.nil?
44
41
  case sql_query
45
- when com.orientechnologies.orient.core.sql.query.OSQLSynchQuery
42
+ when OrientDB::SQLSynchQuery
46
43
  sql_query
44
+ when OrientDB::SQL::Query
45
+ sql_query.to_sql_synch_query
47
46
  when String
48
- com.orientechnologies.orient.core.sql.query.OSQLSynchQuery.new sql_query
49
- when Hash
50
- com.orientechnologies.orient.core.sql.query.OSQLSynchQuery.new sql_query_from_hash(sql_query)
47
+ OrientDB::SQLSynchQuery.new(sql_query)
51
48
  else
52
49
  raise "Unknown query type"
53
50
  end
54
51
  end
55
52
 
56
- def sql_query_from_hash(options = {})
57
- target = options.delete :oclass
58
- raise "Missing oclass name" unless target
59
-
60
- columns = options.delete(:columns) || '*'
61
- order = options.delete :order
62
- order_sql = order ? " ORDER BY #{order}" : ''
63
- limit = options.delete :limit
64
- limit_sql = limit ? " LIMIT #{limit}" : ''
65
- range_low = options.delete(:range_low) || options.delete(:range)
66
- range_high = options.delete :range_high
67
- range_sql = range_low ? " RANGE #{range_low}#{range_high ? ",#{range_high}" : ''}" : ''
68
- fields = options.map { |field, value| "#{field} #{operator_for(value)} #{quote(value)}" }
69
- where_sql = fields.size > 0 ? " WHERE #{fields.join(' AND ')}" : ''
70
-
71
- "SELECT #{columns} FROM #{target}" + where_sql + order_sql + limit_sql + range_sql
72
- end
73
-
74
- def operator_for(value)
75
- case value
76
- when Integer, Float, Symbol
77
- "="
78
- when String
79
- value.index('%') ? "LIKE" : "="
80
- when Array
81
- "IN"
82
- end
83
- end
84
-
85
- def quote(value)
86
- case value
87
- when Integer, Float, Symbol
88
- value.to_s
89
- when String
90
- "'#{value}'"
91
- when Array
92
- "[" + value.map { |x| quote(x) }.join(", ") + "]"
93
- end
94
- end
95
-
96
53
  def schema
97
54
  metadata.schema
98
55
  end
@@ -58,7 +58,6 @@ module OrientDB
58
58
  alias_method :native_new, :new
59
59
 
60
60
  def new(db, klass_name, fields = {})
61
- puts "new : #{db} : #{klass_name} : #{fields.inspect}"
62
61
  obj = native_new db, klass_name.to_s
63
62
  fields.each do |name, value|
64
63
  obj.field name.to_s, value
@@ -4,13 +4,13 @@ module OrientDB
4
4
 
5
5
  def type_for(value)
6
6
  type = case value
7
- when SchemaType
7
+ when OrientDB::SchemaType, OrientDB::OClass
8
8
  value
9
9
  when Symbol
10
10
  FIELD_TYPES[value]
11
11
  else
12
12
  FIELD_TYPES[value.to_s.to_sym]
13
- end
13
+ end
14
14
  raise "Uknown schema type for [#{value}]" unless type
15
15
  type
16
16
  end
@@ -74,12 +74,10 @@ module OrientDB
74
74
  class << self
75
75
 
76
76
  def create(db, name, fields = {})
77
- puts "create [#{name}], #{fields.inspect}"
78
77
  name = name.to_s
79
78
  add_cluster = fields.delete :add_cluster
80
79
  add_cluster = true if add_cluster.nil?
81
80
  use_cluster = fields.delete :use_cluster
82
- puts "use_cluster : #{use_cluster}"
83
81
 
84
82
  if db.schema.exists_class? name
85
83
  klass = db.get_class name
@@ -87,15 +85,12 @@ module OrientDB
87
85
  if use_cluster
88
86
  cluster = db.storage.get_cluster use_cluster
89
87
  klass = db.schema.create_class name, use_cluster
90
- puts "created and used cluster [#{cluster}] for [#{klass}]"
91
88
  elsif add_cluster && !db.storage.cluster_names.include?(name.downcase)
92
89
  cluster = db.storage.add_cluster name.downcase, STORAGE_TYPES[:physical]
93
90
  klass = db.schema.create_class name, cluster
94
- puts "created and added cluster [#{cluster}] for [#{klass}]"
95
91
  else
96
92
  klass = db.schema.create_class name
97
93
  cluster = db.storage.get_cluster klass.cluster_ids.first
98
- puts "created and got cluster [#{cluster}] for [#{klass}]"
99
94
  end
100
95
  end
101
96
 
@@ -0,0 +1,277 @@
1
+ require 'orientdb/sql_ext'
2
+
3
+ module OrientDB
4
+ module SQL
5
+
6
+ class ConditionExpression
7
+
8
+ attr_reader :conditions
9
+
10
+ def initialize(type)
11
+ @type = type
12
+ @conditions = []
13
+ add(conds) if conds
14
+ end
15
+
16
+ def type
17
+ @type.to_s.upcase.gsub('_', ' ')
18
+ end
19
+
20
+ def add(*conds)
21
+ puts "add : #{conds.inspect}"
22
+ conds.each do |cond|
23
+ case cond
24
+ when ConditionExpression
25
+ puts "ConditionExpression : #{cond.class.name} : #{cond.inspect}"
26
+ conditions << cond.to_s
27
+ when Hash
28
+ puts "Hash : #{cond.class.name} : #{cond.inspect}"
29
+ cond.each { |k, v| conditions << "#{k} = #{Query.quote(v)}" }
30
+ when Array
31
+ puts "Array : #{cond.class.name} : #{cond.inspect}"
32
+ cond.each { |x| conditions << x.to_s }
33
+ else
34
+ puts "else : #{cond.class.name} : #{cond.inspect}"
35
+ conditions << cond.to_s
36
+ end
37
+ end
38
+ end
39
+
40
+ def clear
41
+ @conditions = []
42
+ end
43
+
44
+ def conditions_str
45
+ conditions.join(' AND ')
46
+ end
47
+
48
+ def parens_conditions_str
49
+ conditions.size > 1 ? "(#{conditions_str})" : conditions_str
50
+ end
51
+
52
+ def to_s
53
+ "#{type} #{parens_conditions_str} "
54
+ end
55
+ end
56
+
57
+ class Query
58
+
59
+ attr_reader :projections, :targets, :conditions, :order, :limit, :lower_range, :upper_range, :plan
60
+
61
+ def initialize
62
+ @projections = []
63
+ @targets = []
64
+ @conditions = []
65
+ @order = []
66
+ @limit = nil
67
+ @lower_range = nil
68
+ @upper_range = nil
69
+ @plan = nil
70
+ end
71
+
72
+ def select(*args)
73
+ args.each do |arg|
74
+ case arg
75
+ when String, Symbol, Integer
76
+ arg = select_single_string(arg)
77
+ @projections << arg
78
+ when Hash
79
+ arg.each { |k, v| @projections << "#{k} AS #{v}" }
80
+ when Array
81
+ if arg.size == 2
82
+ @projections << "#{arg.first} AS #{arg.last}"
83
+ else
84
+ arg.each { |x| @projections << select_single_string(x) }
85
+ end
86
+ end
87
+ end
88
+ self
89
+ end
90
+
91
+ alias :columns :select
92
+
93
+ def select!(*args)
94
+ @projections = []
95
+ select *args
96
+ end
97
+
98
+ def from(*args)
99
+ args.each { |x| @targets << x.to_s }
100
+ self
101
+ end
102
+
103
+ def from!(*args)
104
+ @targets = []
105
+ from *args
106
+ end
107
+
108
+ def where(*args)
109
+ @conditions << ConditionExpression.new(:and) if @conditions.empty?
110
+ @conditions.last.add *args
111
+ self
112
+ end
113
+
114
+ def where!(*args)
115
+ @conditions = []
116
+ where *args
117
+ end
118
+
119
+ def and(*args)
120
+ @conditions << ConditionExpression.new(:and)
121
+ @conditions.last.add *args
122
+ self
123
+ end
124
+
125
+ def or(*args)
126
+ @conditions << ConditionExpression.new(:or)
127
+ @conditions.last.add *args
128
+ self
129
+ end
130
+
131
+ def and_not(*args)
132
+ @conditions << ConditionExpression.new(:and_not)
133
+ @conditions.last.add *args
134
+ self
135
+ end
136
+
137
+ def or_not(*args)
138
+ @conditions << ConditionExpression.new(:or_not)
139
+ @conditions.last.add *args
140
+ self
141
+ end
142
+
143
+ def order(*args)
144
+ args.each do |arg|
145
+ case arg
146
+ when Hash
147
+ arg.each { |k, v| @order << "#{k} #{order_direction_for(v)}" }
148
+ when Array
149
+ case arg.size
150
+ when 2
151
+ @order << "#{arg[0]} #{order_direction_for(arg[1])}"
152
+ else
153
+ arg.each { |x| @order << x.to_s }
154
+ end
155
+ else
156
+ @order << arg.to_s
157
+ end
158
+ end
159
+ self
160
+ end
161
+
162
+ def order!(*args)
163
+ @order = []
164
+ order *args
165
+ end
166
+
167
+ def limit(max_records)
168
+ @limit = max_records.to_s.to_i
169
+ self
170
+ end
171
+
172
+ alias :limit! :limit
173
+
174
+ def range(lower_rid, upper_rid = nil)
175
+ @lower_range = lower_rid.to_s
176
+ @upper_range = upper_rid ? upper_rid.to_s : nil
177
+ self
178
+ end
179
+
180
+ alias :range! :range
181
+
182
+ def to_s
183
+ (select_sql + target_sql + conditions_sql + order_sql + limit_sql + range_sql).strip
184
+ end
185
+
186
+ def to_sql_synch_query
187
+ OrientDB::SQLSynchQuery.new to_s
188
+ end
189
+
190
+ def self.quote(value)
191
+ case value
192
+ when Numeric, Symbol
193
+ value.to_s
194
+ when String
195
+ quote_string(value)
196
+ when Array
197
+ "[" + value.map { |x| quote(x) }.join(", ") + "]"
198
+ when Regexp
199
+ quote_regexp(value)
200
+ end
201
+ end
202
+
203
+ def self.quote_string(str)
204
+ str = str.dup
205
+ return str if str[0, 1] == "'" && str[-1, 1] == "'"
206
+ last_pos = 0
207
+ while (pos = str.index("'", last_pos))
208
+ str.insert(pos, "\\") if pos > 0 && str[pos - 1, 1] != "\\"
209
+ last_pos = pos + 1
210
+ end
211
+ "'#{str}'"
212
+ end
213
+
214
+ def self.quote_regexp(regexp)
215
+ regexp = regexp.inspect
216
+ left_index = regexp.index('/') + 1
217
+ right_index = regexp.rindex('/') - 1
218
+ str = regexp[left_index..right_index]
219
+ "'#{str}'"
220
+ end
221
+
222
+ def quote(value)
223
+ self.class.quote value
224
+ end
225
+
226
+ private
227
+
228
+ def select_sql
229
+ str = @projections.empty? ? '' : @projections.map { |x| x.to_s }.join(', ') + ' '
230
+ "SELECT #{str}"
231
+ end
232
+
233
+ def target_sql
234
+ case @targets.size
235
+ when 0
236
+ "FROM "
237
+ when 1
238
+ "FROM #{@targets.first} "
239
+ else
240
+ "FROM [#{@targets.map { |x| x.to_s }.join(", ")}] "
241
+ end
242
+ end
243
+
244
+ def conditions_sql
245
+ case @conditions.size
246
+ when 0
247
+ ''
248
+ when 1
249
+ "WHERE #{@conditions.first.conditions_str} "
250
+ else
251
+ "WHERE #{@conditions.first.parens_conditions_str} #{@conditions[1..-1].map { |x| x.to_s }.join('')}"
252
+ end
253
+ end
254
+
255
+ def order_sql
256
+ @order.empty? ? '' : "ORDER BY #{@order.map { |x| x.to_s }.join(', ')} "
257
+ end
258
+
259
+ def limit_sql
260
+ @limit.nil? ? '' : "LIMIT #{@limit} "
261
+ end
262
+
263
+ def range_sql
264
+ @lower_range.nil? ? '' : "RANGE #{@lower_range}#{@upper_range ? ", #{@upper_range}" : ''} "
265
+ end
266
+
267
+ def select_single_string(arg)
268
+ arg.to_s.split('___').join(' AS ').split('__').join('.')
269
+ end
270
+
271
+ def order_direction_for(value)
272
+ value.to_s.strip.downcase == 'desc' ? 'DESC' : 'ASC'
273
+ end
274
+
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,240 @@
1
+ module OrientDB
2
+ module SQL
3
+
4
+ def monkey_patched
5
+ @monkey_patched ||= []
6
+ end
7
+
8
+ module_function :monkey_patched
9
+
10
+ def monkey_patched?(name)
11
+ monkey_patched.include? name.to_s.downcase.to_sym
12
+ end
13
+
14
+ module_function :monkey_patched?
15
+
16
+ # Extend strings and/or symbols to create queries easier
17
+ def monkey_patch!(*args)
18
+ args = %w{ symbol string } if args.empty?
19
+ args.each do |arg|
20
+ case arg.to_s.downcase.to_sym
21
+ when :symbol
22
+ if monkey_patched?(:symbol)
23
+ puts "Symbol has already been monkey patched!"
24
+ false
25
+ else
26
+ Symbol.send :include, OrderExtension
27
+ Symbol.send :include, ConditionalExtension
28
+ Symbol.send :include, FieldOperatorExtension
29
+ Symbol.send :include, BundledFunctionExtension
30
+ monkey_patched << :symbol
31
+ true
32
+ end
33
+ when :string
34
+ if monkey_patched?(:string)
35
+ puts "String has already been monkey patched!"
36
+ false
37
+ else
38
+ String.send :include, OrderExtension
39
+ String.send :include, ConditionalExtension
40
+ String.send :include, FieldOperatorExtension
41
+ String.send :include, BundledFunctionExtension
42
+ monkey_patched << :string
43
+ true
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ module_function :monkey_patch!
50
+
51
+ module OrderExtension
52
+ def asc
53
+ "#{to_s} ASC"
54
+ end
55
+
56
+ def desc
57
+ "#{to_s} DESC"
58
+ end
59
+ end
60
+
61
+ module ConditionalExtension
62
+ def like(value)
63
+ "#{to_s} LIKE #{Query.quote(value)}"
64
+ end
65
+
66
+ def eq(value)
67
+ "#{to_s} = #{Query.quote(value)}"
68
+ end
69
+
70
+ def lt(value)
71
+ "#{to_s} < #{Query.quote(value)}"
72
+ end
73
+
74
+ def lte(value)
75
+ "#{to_s} <= #{Query.quote(value)}"
76
+ end
77
+
78
+ def gt(value)
79
+ "#{to_s} > #{Query.quote(value)}"
80
+ end
81
+
82
+ def gte(value)
83
+ "#{to_s} >= #{Query.quote(value)}"
84
+ end
85
+
86
+ def ne(value)
87
+ "#{to_s} <> #{Query.quote(value)}"
88
+ end
89
+
90
+ def is_null
91
+ "#{to_s} IS null"
92
+ end
93
+
94
+ def is_not_null
95
+ "#{to_s} IS NOT null"
96
+ end
97
+
98
+ def in(*values)
99
+ "#{to_s} IN #{Query.quote(values)}"
100
+ end
101
+
102
+ def contains(field, value)
103
+ "#{to_s} contains (#{field} = #{Query.quote(value)})"
104
+ end
105
+
106
+ def contains_all(field, value)
107
+ "#{to_s} containsAll (#{field} = #{Query.quote(value)})"
108
+ end
109
+
110
+ def contains_key(value)
111
+ "#{to_s} containsKey #{Query.quote(value)}"
112
+ end
113
+
114
+ def contains_value(value)
115
+ "#{to_s} containsValue #{Query.quote(value)}"
116
+ end
117
+
118
+ def contains_text(value)
119
+ "#{to_s} containsText #{Query.quote(value)}"
120
+ end
121
+
122
+ def matches(value)
123
+ "#{to_s} matches #{Query.quote(value)}"
124
+ end
125
+ end
126
+
127
+ module FieldOperatorExtension
128
+ # Avoided overriding the native method
129
+ def odb_length
130
+ "#{to_s}.length()"
131
+ end
132
+
133
+ # Avoided overriding the native method
134
+ def odb_trim
135
+ "#{to_s}.trim()"
136
+ end
137
+
138
+ def to_upper_case
139
+ "#{to_s}.toUpperCase()"
140
+ end
141
+
142
+ def to_lower_case
143
+ "#{to_s}.toLowerCase()"
144
+ end
145
+
146
+ # Avoided overriding the native method
147
+ def odb_left(length)
148
+ "#{to_s}.left(#{Query.quote(length)})"
149
+ end
150
+
151
+ # Avoided overriding the native method
152
+ def odb_right(length)
153
+ "#{to_s}.right(#{Query.quote(length)})"
154
+ end
155
+
156
+ def sub_string(start, length = nil)
157
+ "#{to_s}.subString(#{Query.quote(start)}#{length ? ", #{Query.quote(length)}" : ''})"
158
+ end
159
+
160
+ def char_at(pos)
161
+ "#{to_s}.charAt(#{Query.quote(pos)})"
162
+ end
163
+
164
+ def index_of(string, start = nil)
165
+ "#{to_s}.indexOf(#{Query.quote(string)}#{start ? ", #{Query.quote(start)}" : ''})"
166
+ end
167
+
168
+ # Avoided overriding the native method
169
+ def odb_format(frmt)
170
+ "#{to_s}.format(#{Query.quote(frmt)})"
171
+ end
172
+
173
+ # Avoided overriding the native method
174
+ def odb_size
175
+ "#{to_s}.size()"
176
+ end
177
+
178
+ def as_string
179
+ "#{to_s}.asString()"
180
+ end
181
+
182
+ def as_integer
183
+ "#{to_s}.asInteger()"
184
+ end
185
+
186
+ def as_float
187
+ "#{to_s}.asFloat()"
188
+ end
189
+
190
+ def as_date
191
+ "#{to_s}.asDate()"
192
+ end
193
+
194
+ def as_date_time
195
+ "#{to_s}.asDateTime()"
196
+ end
197
+
198
+ def as_boolean
199
+ "#{to_s}.asBoolean()"
200
+ end
201
+ end
202
+
203
+ module BundledFunctionExtension
204
+
205
+ # Avoided overriding the native method
206
+ def odb_count
207
+ "count(#{to_s})"
208
+ end
209
+
210
+ # Avoided overriding the native method
211
+ def odb_min
212
+ "min(#{to_s})"
213
+ end
214
+
215
+ # Avoided overriding the native method
216
+ def odb_max
217
+ "max(#{to_s})"
218
+ end
219
+
220
+ # Avoided overriding the native method
221
+ def odb_avg
222
+ "avg(#{to_s})"
223
+ end
224
+
225
+ # Avoided overriding the native method
226
+ def odb_sum
227
+ "sum(#{to_s})"
228
+ end
229
+
230
+ def sysdate
231
+ "sysdate('#{to_s}')"
232
+ end
233
+
234
+ # Avoided overriding the native method
235
+ def odb_format_str(*args)
236
+ "format('#{to_s}', #{args.map{|x| Query.quote(x)}.join(', ')})"
237
+ end
238
+ end
239
+ end
240
+ end