orientdb 1.2.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +32 -0
- data/LICENSE +20 -0
- data/README.rdoc +88 -0
- data/Rakefile +58 -0
- data/bin/orientdb_console +23 -0
- data/lib/jars/blueprints-core-2.2.0-SNAPSHOT.jar +0 -0
- data/lib/jars/blueprints-orient-graph-2.2.0-SNAPSHOT.jar +0 -0
- data/lib/jars/orient-commons-1.2.0.jar +0 -0
- data/lib/jars/orientdb-client-1.2.0.jar +0 -0
- data/lib/jars/orientdb-core-1.2.0.jar +0 -0
- data/lib/jars/orientdb-distributed-1.2.0.jar +0 -0
- data/lib/jars/orientdb-enterprise-1.2.0.jar +0 -0
- data/lib/jars/orientdb-graphdb-1.2.0.jar +0 -0
- data/lib/jars/orientdb-server-1.2.0.jar +0 -0
- data/lib/jars/orientdb-tools-1.2.0.jar +0 -0
- data/lib/jars/pipes-2.0.0-SNAPSHOT.jar +0 -0
- data/lib/orientdb.rb +29 -0
- data/lib/orientdb/constants.rb +57 -0
- data/lib/orientdb/database.rb +167 -0
- data/lib/orientdb/document.rb +78 -0
- data/lib/orientdb/ext.rb +13 -0
- data/lib/orientdb/oclass.rb +141 -0
- data/lib/orientdb/property.rb +37 -0
- data/lib/orientdb/record.rb +18 -0
- data/lib/orientdb/rid.rb +46 -0
- data/lib/orientdb/schema.rb +33 -0
- data/lib/orientdb/sql.rb +18 -0
- data/lib/orientdb/sql/common.rb +247 -0
- data/lib/orientdb/sql/delete.rb +23 -0
- data/lib/orientdb/sql/ext.rb +249 -0
- data/lib/orientdb/sql/insert.rb +37 -0
- data/lib/orientdb/sql/query.rb +138 -0
- data/lib/orientdb/sql/update.rb +57 -0
- data/lib/orientdb/storage.rb +51 -0
- data/lib/orientdb/version.rb +3 -0
- data/orientdb.gemspec +96 -0
- data/spec/database_spec.rb +111 -0
- data/spec/document_spec.rb +99 -0
- data/spec/graph_spec.rb +39 -0
- data/spec/orientdb_spec.rb +10 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_basic_helper.rb +25 -0
- data/spec/spec_helper.rb +68 -0
- data/spec/sql_spec.rb +839 -0
- data/spec/tinkerpop_graph_spec.rb +32 -0
- metadata +165 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
module OrientDB
|
2
|
+
|
3
|
+
class Document
|
4
|
+
|
5
|
+
def values
|
6
|
+
field_names.map { |field_name| [field_name, self[field_name]] }
|
7
|
+
end
|
8
|
+
|
9
|
+
alias :db :database
|
10
|
+
|
11
|
+
def [](field_name)
|
12
|
+
field field_name.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(field_name, value)
|
16
|
+
field field_name.to_s, value
|
17
|
+
end
|
18
|
+
|
19
|
+
def field?(name)
|
20
|
+
contains_field(name.to_s) || (schema_class && schema_class.exists_property?(name.to_s))
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to?(method_name)
|
24
|
+
return true if field?(method_name.to_s)
|
25
|
+
match = method_name.to_s.match(/(.*?)([?=!]?)$/)
|
26
|
+
return true if match[2] == '='
|
27
|
+
return true if match[2] == '?' && field?(match[1])
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method_name, *args, &blk)
|
32
|
+
return self[method_name] if field?(method_name)
|
33
|
+
|
34
|
+
match = method_name.to_s.match(/(.*?)([?=!]?)$/)
|
35
|
+
case match[2]
|
36
|
+
when "="
|
37
|
+
self[match[1]] = args.first
|
38
|
+
when "?"
|
39
|
+
field(match[1]) ? !!self[match[1]] : super
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def rid
|
46
|
+
identity.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def inspect
|
50
|
+
props = values.map { |k, v| "#{k}:#{v.inspect}" }.join(' ')
|
51
|
+
%{#<OrientDB::Document:#{class_name}:#{rid}#{props.empty? ? '' : ' ' + props}>}
|
52
|
+
end
|
53
|
+
|
54
|
+
alias :to_s :inspect
|
55
|
+
|
56
|
+
class << self
|
57
|
+
|
58
|
+
alias_method :native_new, :new
|
59
|
+
|
60
|
+
def new(db, klass_name, fields = {})
|
61
|
+
obj = native_new db, klass_name.to_s
|
62
|
+
fields.each do |name, value|
|
63
|
+
obj.field name.to_s, value
|
64
|
+
end
|
65
|
+
obj
|
66
|
+
end
|
67
|
+
|
68
|
+
def create(db, klass_name, fields = {})
|
69
|
+
obj = new db, klass_name, fields
|
70
|
+
obj.save
|
71
|
+
obj
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/lib/orientdb/ext.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
module OrientDB
|
2
|
+
|
3
|
+
class OClassImpl
|
4
|
+
|
5
|
+
def type_for(value)
|
6
|
+
self.class.type_for value, schema
|
7
|
+
end
|
8
|
+
|
9
|
+
def add(property_name, type, options = { })
|
10
|
+
property_name = property_name.to_s
|
11
|
+
if exists_property(property_name)
|
12
|
+
puts "We already have that property name [#{property_name}]"
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
|
16
|
+
type = type.oclass if type.respond_to?(:oclass)
|
17
|
+
case type
|
18
|
+
when SchemaType
|
19
|
+
prop = create_property property_name, type
|
20
|
+
when Symbol
|
21
|
+
prop = create_property property_name, type_for(type)
|
22
|
+
when OClassImpl
|
23
|
+
prop = create_property property_name, type_for(:link), type
|
24
|
+
when Array
|
25
|
+
type, sub_type = type_for(type.first), type_for(type.last)
|
26
|
+
prop = create_property property_name, type, sub_type
|
27
|
+
else
|
28
|
+
raise "ERROR! Unknown type [ #{property_name} | #{type} : #{type.class.name} ]"
|
29
|
+
end
|
30
|
+
|
31
|
+
prop.set_min options[:min].to_s unless options[:min].nil?
|
32
|
+
prop.set_max options[:max].to_s unless options[:max].nil?
|
33
|
+
prop.set_mandatory !!options[:mandatory] unless options[:mandatory].nil?
|
34
|
+
prop.set_not_null options[:not_null] unless options[:not_null].nil?
|
35
|
+
unless options[:index].nil?
|
36
|
+
index_type = options[:index] == true ? INDEX_TYPES[:notunique] : INDEX_TYPES[options[:index]]
|
37
|
+
prop.createIndex index_type
|
38
|
+
end
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_index
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def [](property_name)
|
48
|
+
property_name = property_name.to_s
|
49
|
+
exists_property(property_name) ? get_property(property_name) : nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def db
|
53
|
+
document.database
|
54
|
+
end
|
55
|
+
|
56
|
+
def schema
|
57
|
+
db.metadata.schema
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
props = properties.map { |x| "#{x.name}=#{x.type.name}#{x.is_indexed? ? '(idx)' : ''}" }.join(' ')
|
62
|
+
"#<OrientDB::OClassImpl:" + name +
|
63
|
+
(getSuperClass ? ' super=' + getSuperClass.name : '') +
|
64
|
+
(props.empty? ? '' : ' ' + props) +
|
65
|
+
">"
|
66
|
+
end
|
67
|
+
|
68
|
+
alias :to_s :inspect
|
69
|
+
|
70
|
+
class << self
|
71
|
+
|
72
|
+
def type_for(value, schema)
|
73
|
+
value = value.oclass if value.respond_to?(:oclass)
|
74
|
+
type = case value
|
75
|
+
when OrientDB::SchemaType, OrientDB::OClassImpl
|
76
|
+
value
|
77
|
+
when String
|
78
|
+
if schema.exists_class?(value)
|
79
|
+
schema.get_class(value)
|
80
|
+
else
|
81
|
+
FIELD_TYPES[value.to_sym]
|
82
|
+
end
|
83
|
+
when Symbol
|
84
|
+
FIELD_TYPES[value]
|
85
|
+
else
|
86
|
+
FIELD_TYPES[value.to_s.to_sym]
|
87
|
+
end
|
88
|
+
raise "Uknown schema type for [#{value}] (#{value.class.name})" unless type
|
89
|
+
type
|
90
|
+
end
|
91
|
+
|
92
|
+
def create(db, name, fields = { })
|
93
|
+
name = name.to_s
|
94
|
+
add_cluster = fields.delete :add_cluster
|
95
|
+
add_cluster = true if add_cluster.nil?
|
96
|
+
use_cluster = fields.delete :use_cluster
|
97
|
+
|
98
|
+
if db.schema.exists_class? name
|
99
|
+
klass = db.get_class name
|
100
|
+
else
|
101
|
+
if use_cluster
|
102
|
+
klass = db.schema.create_class name, use_cluster
|
103
|
+
elsif add_cluster && !db.storage.cluster_names.include?(name.downcase)
|
104
|
+
#debugger
|
105
|
+
cluster = db.storage.add_cluster STORAGE_TYPES[:physical], name.downcase, "/tmp/database", 'default', {}
|
106
|
+
klass = db.schema.create_class name, cluster
|
107
|
+
else
|
108
|
+
klass = db.schema.create_class name
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
super_klass = fields.delete :super
|
113
|
+
super_klass = db.get_class(super_klass.to_s) unless super_klass.is_a?(OrientDB::OClassImpl)
|
114
|
+
klass.set_super_class super_klass if super_klass
|
115
|
+
db.schema.save
|
116
|
+
|
117
|
+
unless fields.empty?
|
118
|
+
fields.each do |property_name, type|
|
119
|
+
case type
|
120
|
+
when Symbol, Array, OrientDB::OClassImpl
|
121
|
+
klass.add property_name, type
|
122
|
+
when Hash
|
123
|
+
options = type.dup
|
124
|
+
type = options.delete :type
|
125
|
+
klass.add property_name, type, options
|
126
|
+
else
|
127
|
+
raise "Unknown field options [#{type.inspect}]"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
db.schema.save
|
131
|
+
end
|
132
|
+
|
133
|
+
klass
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module OrientDB
|
2
|
+
class PropertyImpl
|
3
|
+
|
4
|
+
def type_short
|
5
|
+
@type_short ||= OrientDB::FIELD_TYPES.select { |k, v| v.name == getType.name }.first.first
|
6
|
+
end
|
7
|
+
|
8
|
+
def linked_type_short
|
9
|
+
@linked_type_short ||= getLinkedType && OrientDB::FIELD_TYPES.select { |k, v| v.name == getLinkedType.name }.first.first
|
10
|
+
end
|
11
|
+
|
12
|
+
def info
|
13
|
+
{
|
14
|
+
:name => name,
|
15
|
+
:type => type_short,
|
16
|
+
:index => indexed? ? getIndex.name : nil,
|
17
|
+
:min => min,
|
18
|
+
:max => max,
|
19
|
+
:mandatory => is_mandatory?,
|
20
|
+
:not_null => is_not_null?,
|
21
|
+
:linked_type => linked_type_short,
|
22
|
+
:linked_class => linked_type_short ? getLinkedClass.name : nil,
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
"#<OrientDB::Property:#{name} type=#{type_short} " +
|
28
|
+
"#{linked_type_short ? "linked_type=#{linked_type_short} linked_class=#{getLinkedClass.name}" : ''}" +
|
29
|
+
"indexed=#{is_indexed?} mandatory=#{is_mandatory?} not_null=#{is_not_null}" +
|
30
|
+
"#{min ? " min=#{min}" : ''}#{max ? " max=#{max}" : ''}" +
|
31
|
+
">"
|
32
|
+
end
|
33
|
+
|
34
|
+
alias :to_s :inspect
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OrientDB
|
2
|
+
|
3
|
+
class RecordList
|
4
|
+
def inspect
|
5
|
+
"#<OrientDB::RecordList:#{toString}>"
|
6
|
+
end
|
7
|
+
|
8
|
+
alias :to_s :inspect
|
9
|
+
end
|
10
|
+
|
11
|
+
class RecordSet
|
12
|
+
def inspect
|
13
|
+
"#<OrientDB::RecordSet:#{toString}>"
|
14
|
+
end
|
15
|
+
|
16
|
+
alias :to_s :inspect
|
17
|
+
end
|
18
|
+
end
|
data/lib/orientdb/rid.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
class OrientDB::RID
|
2
|
+
|
3
|
+
attr_reader :cluster_id, :document_id
|
4
|
+
|
5
|
+
def initialize(rid = '#-1:-1')
|
6
|
+
parts = rid.to_s.gsub('#', '').split ":"
|
7
|
+
if parts.size == 2
|
8
|
+
self.cluster_id = parts.first.to_i
|
9
|
+
self.document_id = parts.last.to_i
|
10
|
+
else
|
11
|
+
raise "Unknown rid [#{rid}]"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def cluster_id=(value)
|
16
|
+
@cluster_id = value.to_s.strip.to_i
|
17
|
+
end
|
18
|
+
|
19
|
+
def document_id=(value)
|
20
|
+
@document_id = value.to_s.strip.to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect
|
24
|
+
"##{cluster_id}:#{@document_id}"
|
25
|
+
end
|
26
|
+
|
27
|
+
alias :to_s :inspect
|
28
|
+
|
29
|
+
def unsaved?
|
30
|
+
to_s == '#-1:-1'
|
31
|
+
end
|
32
|
+
|
33
|
+
def saved?
|
34
|
+
cluster_id > 0 && document_id >= 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid?
|
38
|
+
saved? || unsaved?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class String
|
43
|
+
def valid_orientdb_rid?
|
44
|
+
OrientDB::RID.new(self).valid?
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module OrientDB
|
2
|
+
|
3
|
+
#class Schema
|
4
|
+
#
|
5
|
+
# def inspect
|
6
|
+
# "#<OrientDB::Schema:#{toString}>"
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# alias :to_s :inspect
|
10
|
+
#
|
11
|
+
#end
|
12
|
+
#
|
13
|
+
#class SchemaProxy
|
14
|
+
#
|
15
|
+
# def inspect
|
16
|
+
# "#<OrientDB::SchemaProxy:#{toString}>"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# alias :to_s :inspect
|
20
|
+
#
|
21
|
+
#end
|
22
|
+
#
|
23
|
+
#class SchemaType
|
24
|
+
#
|
25
|
+
# def inspect
|
26
|
+
# "#<OrientDB::SchemaType:#{name}>"
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# alias :to_s :inspect
|
30
|
+
#
|
31
|
+
#end
|
32
|
+
|
33
|
+
end
|
data/lib/orientdb/sql.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module OrientDB::SQL
|
2
|
+
class SQLSynchQuery
|
3
|
+
|
4
|
+
def inspect
|
5
|
+
%{#<OrientDB::SQLSynchQuery:#{name} text="#{text}">}
|
6
|
+
end
|
7
|
+
|
8
|
+
alias :to_s :inspect
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'orientdb/sql/common'
|
14
|
+
require 'orientdb/sql/ext'
|
15
|
+
require 'orientdb/sql/query'
|
16
|
+
require 'orientdb/sql/insert'
|
17
|
+
require 'orientdb/sql/update'
|
18
|
+
require 'orientdb/sql/delete'
|
@@ -0,0 +1,247 @@
|
|
1
|
+
module OrientDB::SQL
|
2
|
+
|
3
|
+
module UtilsMixin
|
4
|
+
|
5
|
+
def select_single_string(arg)
|
6
|
+
arg.to_s.split('___').join(' AS ').split('__').join('.')
|
7
|
+
end
|
8
|
+
|
9
|
+
def field_name(name)
|
10
|
+
name.to_s.split('__').join('.')
|
11
|
+
end
|
12
|
+
|
13
|
+
def quote(value)
|
14
|
+
case value
|
15
|
+
when Numeric, Symbol
|
16
|
+
value.to_s
|
17
|
+
when String
|
18
|
+
quote_string(value)
|
19
|
+
when Array
|
20
|
+
"[" + value.map { |x| quote(x) }.join(", ") + "]"
|
21
|
+
when Regexp
|
22
|
+
quote_regexp(value)
|
23
|
+
when OrientDB::SQL::LiteralExpression
|
24
|
+
value.to_s
|
25
|
+
else
|
26
|
+
quote value.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def quote_string(str)
|
31
|
+
str = str.dup
|
32
|
+
return str if str[0, 1] == "'" && str[-1, 1] == "'"
|
33
|
+
last_pos = 0
|
34
|
+
while (pos = str.index("'", last_pos))
|
35
|
+
str.insert(pos, "\\") if pos > 0 && str[pos - 1, 1] != "\\"
|
36
|
+
last_pos = pos + 1
|
37
|
+
end
|
38
|
+
"'#{str}'"
|
39
|
+
end
|
40
|
+
|
41
|
+
def quote_regexp(regexp)
|
42
|
+
regexp = regexp.inspect
|
43
|
+
left_index = regexp.index('/') + 1
|
44
|
+
right_index = regexp.rindex('/') - 1
|
45
|
+
str = regexp[left_index..right_index]
|
46
|
+
"'#{str}'"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
module ClassClusterParametersMixin
|
52
|
+
|
53
|
+
def oclass(new_oclass)
|
54
|
+
@oclass = new_oclass.to_s
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
alias :oclass! :oclass
|
59
|
+
|
60
|
+
def cluster(new_cluster)
|
61
|
+
@cluster = new_cluster.to_s
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
alias :cluster! :cluster
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def target_sql(command)
|
70
|
+
command = command.to_s.upcase.gsub('_', ' ')
|
71
|
+
if @oclass
|
72
|
+
"#{command} #{@oclass} "
|
73
|
+
elsif @cluster
|
74
|
+
"#{command} cluster:#{@cluster} "
|
75
|
+
else
|
76
|
+
raise "Missing oclass or cluster"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
module FieldsValuesParametersMixin
|
83
|
+
|
84
|
+
def fields(*args)
|
85
|
+
args.each do |arg|
|
86
|
+
case arg
|
87
|
+
when String, Symbol, Integer
|
88
|
+
@fields << field_name(arg)
|
89
|
+
when Hash
|
90
|
+
arg.each { |k, v| @fields << field_name(k); @values << quote(v) }
|
91
|
+
when Array
|
92
|
+
arg.each { |x| @fields << field_name(x) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
self
|
96
|
+
end
|
97
|
+
|
98
|
+
def fields!(*args)
|
99
|
+
@fields = []
|
100
|
+
@values = []
|
101
|
+
fields *args
|
102
|
+
end
|
103
|
+
|
104
|
+
def values(*args)
|
105
|
+
args.each do |arg|
|
106
|
+
case arg
|
107
|
+
when String, Symbol, Integer
|
108
|
+
arg = quote(arg)
|
109
|
+
@values << arg
|
110
|
+
when Hash
|
111
|
+
arg.each { |k, v| @fields << field_name(k); @values << quote(v) }
|
112
|
+
when Array
|
113
|
+
arg.each { |x| @values << quote(x) }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
def values!(*args)
|
120
|
+
@fields = []
|
121
|
+
@values = []
|
122
|
+
values *args
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
module ConditionsParametersMixin
|
128
|
+
def where(*args)
|
129
|
+
@conditions << ConditionExpression.new(:and) if @conditions.empty?
|
130
|
+
@conditions.last.add *args
|
131
|
+
self
|
132
|
+
end
|
133
|
+
|
134
|
+
def where!(*args)
|
135
|
+
@conditions = []
|
136
|
+
where *args
|
137
|
+
end
|
138
|
+
|
139
|
+
def and(*args)
|
140
|
+
@conditions << ConditionExpression.new(:and)
|
141
|
+
@conditions.last.add *args
|
142
|
+
self
|
143
|
+
end
|
144
|
+
|
145
|
+
def or(*args)
|
146
|
+
@conditions << ConditionExpression.new(:or)
|
147
|
+
@conditions.last.add *args
|
148
|
+
self
|
149
|
+
end
|
150
|
+
|
151
|
+
def and_not(*args)
|
152
|
+
@conditions << ConditionExpression.new(:and_not)
|
153
|
+
@conditions.last.add *args
|
154
|
+
self
|
155
|
+
end
|
156
|
+
|
157
|
+
def or_not(*args)
|
158
|
+
@conditions << ConditionExpression.new(:or_not)
|
159
|
+
@conditions.last.add *args
|
160
|
+
self
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def conditions_sql
|
166
|
+
case @conditions.size
|
167
|
+
when 0
|
168
|
+
''
|
169
|
+
when 1
|
170
|
+
"WHERE #{@conditions.first.conditions_str} "
|
171
|
+
else
|
172
|
+
"WHERE #{@conditions.first.parens_conditions_str} #{@conditions[1..-1].map { |x| x.to_s }.join('')}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
class LiteralExpression
|
179
|
+
|
180
|
+
def initialize(value)
|
181
|
+
@value = value.to_s
|
182
|
+
end
|
183
|
+
|
184
|
+
def to_s
|
185
|
+
@value
|
186
|
+
end
|
187
|
+
|
188
|
+
include Comparable
|
189
|
+
|
190
|
+
def <=>(other)
|
191
|
+
to_s <=> other.to_s
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
class ConditionExpression
|
197
|
+
|
198
|
+
attr_reader :conditions
|
199
|
+
|
200
|
+
def initialize(type)
|
201
|
+
@type = type
|
202
|
+
@conditions = []
|
203
|
+
end
|
204
|
+
|
205
|
+
def type
|
206
|
+
@type.to_s.upcase.gsub('_', ' ')
|
207
|
+
end
|
208
|
+
|
209
|
+
def add(*conds)
|
210
|
+
conds.each do |cond|
|
211
|
+
case cond
|
212
|
+
when ConditionExpression
|
213
|
+
conditions << cond.to_s
|
214
|
+
when Hash
|
215
|
+
cond.each { |k, v| conditions << "#{k} = #{Query.quote(v)}" }
|
216
|
+
when Array
|
217
|
+
cond.each { |x| conditions << x.to_s }
|
218
|
+
else
|
219
|
+
conditions << cond.to_s
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def clear
|
225
|
+
@conditions = []
|
226
|
+
end
|
227
|
+
|
228
|
+
def conditions_str
|
229
|
+
conditions.join(' AND ')
|
230
|
+
end
|
231
|
+
|
232
|
+
def parens_conditions_str
|
233
|
+
conditions.size > 1 ? "(#{conditions_str})" : conditions_str
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_s
|
237
|
+
"#{type} #{parens_conditions_str} "
|
238
|
+
end
|
239
|
+
|
240
|
+
include Comparable
|
241
|
+
|
242
|
+
def <=>(other)
|
243
|
+
to_s <=> other.to_s
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|