active-orient 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Gemfile +8 -3
  4. data/Guardfile +12 -4
  5. data/README.md +221 -201
  6. data/VERSION +1 -1
  7. data/active-orient.gemspec +3 -2
  8. data/bin/active-orient-console +35 -0
  9. data/config/boot.rb +84 -16
  10. data/config/config.yml +10 -0
  11. data/config/connect.yml +6 -2
  12. data/create_project +19 -0
  13. data/examples/books.rb +86 -39
  14. data/examples/createTime.rb +91 -0
  15. data/examples/streets.rb +85 -84
  16. data/examples/test_commands.rb +92 -0
  17. data/examples/test_commands_2.rb +54 -0
  18. data/examples/test_commands_3.rb +48 -0
  19. data/examples/test_commands_4.rb +28 -0
  20. data/examples/time_graph/Gemfile +21 -0
  21. data/examples/time_graph/Guardfile +26 -0
  22. data/examples/time_graph/README.md +129 -0
  23. data/examples/time_graph/bin/active-orient-console +35 -0
  24. data/examples/time_graph/config/boot.rb +119 -0
  25. data/examples/time_graph/config/config.yml +8 -0
  26. data/examples/time_graph/config/connect.yml +17 -0
  27. data/examples/time_graph/config/init_db.rb +59 -0
  28. data/examples/time_graph/createTime.rb +51 -0
  29. data/examples/time_graph/lib/createTime.rb +82 -0
  30. data/examples/time_graph/model/day_of.rb +3 -0
  31. data/examples/time_graph/model/e.rb +6 -0
  32. data/examples/time_graph/model/edge.rb +53 -0
  33. data/examples/time_graph/model/monat.rb +19 -0
  34. data/examples/time_graph/model/stunde.rb +16 -0
  35. data/examples/time_graph/model/tag.rb +29 -0
  36. data/examples/time_graph/model/time_base.rb +6 -0
  37. data/examples/time_graph/model/time_of.rb +4 -0
  38. data/examples/time_graph/model/v.rb +3 -0
  39. data/examples/time_graph/model/vertex.rb +32 -0
  40. data/examples/time_graph/spec/lib/create_time_spec.rb +50 -0
  41. data/examples/time_graph/spec/rest_helper.rb +37 -0
  42. data/examples/time_graph/spec/spec_helper.rb +46 -0
  43. data/lib/active-orient.rb +56 -6
  44. data/lib/base.rb +149 -147
  45. data/lib/base_properties.rb +40 -41
  46. data/lib/class_utils.rb +301 -0
  47. data/lib/database_utils.rb +97 -0
  48. data/lib/init.rb +35 -0
  49. data/lib/java-api.rb +437 -0
  50. data/lib/jdbc.rb +211 -0
  51. data/lib/model/edge.rb +53 -0
  52. data/lib/model/model.rb +77 -0
  53. data/lib/model/the_class.rb +480 -0
  54. data/lib/model/the_record.rb +310 -0
  55. data/lib/model/vertex.rb +32 -0
  56. data/lib/orient.rb +113 -50
  57. data/lib/orientdb_private.rb +48 -0
  58. data/lib/other.rb +280 -0
  59. data/lib/query.rb +71 -73
  60. data/lib/rest/change.rb +124 -0
  61. data/lib/rest/create.rb +474 -0
  62. data/lib/rest/delete.rb +133 -0
  63. data/lib/rest/operations.rb +150 -0
  64. data/lib/rest/read.rb +150 -0
  65. data/lib/rest/rest.rb +111 -0
  66. data/lib/rest_disabled.rb +24 -0
  67. data/lib/support.rb +387 -296
  68. data/old_lib_functions/two_general_class.rb +139 -0
  69. data/usecase.md +49 -36
  70. data/usecase_oo.md +59 -0
  71. metadata +73 -9
  72. data/lib/model.rb +0 -461
  73. data/lib/rest.rb +0 -1036
  74. data/test.rb +0 -4
@@ -1,7 +1,8 @@
1
1
  module ActiveOrient
2
2
  require 'active_model'
3
- #
4
- # Base class for tableless IB data Models, extends ActiveModel API
3
+
4
+ # Base class for tableless IB data Models, extends ActiveModel API
5
+
5
6
  class Base
6
7
  extend ActiveModel::Naming
7
8
  extend ActiveModel::Callbacks
@@ -9,212 +10,213 @@ module ActiveOrient
9
10
  include ActiveModel::Serialization
10
11
  include ActiveModel::Serializers::Xml
11
12
  include ActiveModel::Serializers::JSON
12
-
13
+ include OrientDB
14
+
15
+ define_model_callbacks :initialize
13
16
 
14
- ##Every Rest::Base-Object is stored in the @@rid_store
15
- ## The Objects are just references to the @@rid_store.
16
- ## any Change of the Object is thus synchonized to any allocated variable
17
- #
18
- @@rid_store = Hash.new
17
+ # ActiveRecord::Base callback API mocks
18
+ define_model_callbacks :initialize, :only => :after
19
+ mattr_accessor :logger
19
20
 
20
- def self.display_riid
21
+ # Used to read the metadata
22
+ attr_reader :metadata
23
+
24
+ =begin
25
+ Every Rest::Base-Object is stored in the @@rid_store
26
+ The Objects are just references to the @@rid_store.
27
+ Any Change of the Object is thus synchonized to any allocated variable.
28
+ =end
29
+ @@rid_store = Hash.new
30
+
31
+ def self.display_rid
21
32
  @@rid_store
22
33
  end
23
- def self.remove_riid obj
24
- @@rid_store[obj.riid]=nil
34
+
35
+ def self.remove_rid obj
36
+ @@rid_store.delete obj.rid
25
37
  end
26
- def self.get_riid link
27
38
 
39
+ def self.get_rid rid
40
+ rid = rid[1..-1] if rid[0]=='#'
41
+ @@rid_store[rid]
28
42
  end
29
- def self.store_riid obj
30
- if obj.rid.present? && obj.riid.all?{|x| x.present? && x>=0} # only positive values are stored
31
- ## return the presence of a stored object as true by the block
32
- ## the block is only executed if the presence is confirmed
33
- ## Nothing is returned from the class-method
34
- if @@rid_store[obj.riid].present?
35
- yield if block_given?
36
- end
37
- @@rid_store[obj.riid] = obj
38
- @@rid_store[obj.riid] # return_value
43
+
44
+ def self.store_rid obj
45
+ if obj.rid.present? && obj.rid.rid?
46
+ # return the presence of a stored object as true by the block
47
+ # the block is only executed if the presence is confirmed
48
+ # Nothing is returned from the class-method
49
+ if @@rid_store[obj.rid].present?
50
+ yield if block_given?
51
+ end
52
+ @@rid_store[obj.rid] = obj
53
+ @@rid_store[obj.rid] # return_value
39
54
  else
40
- obj # no rid-value: just return the obj
55
+ obj # no rid-value: just return the obj
41
56
  end
42
57
  end
43
58
 
59
+ def document
60
+ @d
61
+ end
44
62
 
45
- define_model_callbacks :initialize
63
+ =begin
64
+ If a opts hash is given, keys are taken as attribute names, values as data.
65
+ The model instance fields are then set automatically from the opts Hash.
66
+ =end
46
67
 
47
- mattr_accessor :logger
48
- # If a opts hash is given, keys are taken as attribute names, values as data.
49
- # The model instance fields are then set automatically from the opts Hash.
50
- def initialize attributes={}, opts={}
51
- logger.progname= "ActiveOrient::Base#initialize"
52
- #possible_link_array_candidates = link_candidates = Hash.new
68
+ def initialize attributes = {}, opts = {}
69
+ logger.progname = "ActiveOrient::Base#initialize"
53
70
  @metadata = HashWithIndifferentAccess.new
54
- # @edges = HashWithIndifferentAccess.new
55
-
71
+ @d = nil
56
72
  run_callbacks :initialize do
57
- # puts "initialize::attributes: #{attributes.inspect}"
58
-
59
- attributes.keys.each do | att |
60
- unless att[0] == "@" # @ identifies Metadata-attributes
61
- att = att.to_sym if att.is_a?(String)
62
- unless self.class.instance_methods.detect{|x| x == att }
63
- self.class.define_property att, nil
64
- # logger.debug { "property #{att.to_s} assigned to #{self.class.to_s}" }
73
+ if RUBY_PLATFORM == 'java' && attributes.is_a?( Document )
74
+ @d = attributes
75
+ attributes = @d.values
76
+ @metadata[:class] = @d.class_name
77
+ @metadata[:version] = @d.version
78
+ @metadata[:cluster], @metadata[:record] = @d.rid[1,@d.rid.size].split(':')
79
+
80
+
81
+
82
+ end
83
+ attributes.keys.each do |att|
84
+ unless att[0] == "@" # @ identifies Metadata-attributes
85
+ att = att.to_sym if att.is_a?(String)
86
+ unless self.class.instance_methods.detect{|x| x == att}
87
+ self.class.define_property att, nil
65
88
  else
66
- # logger.info{ "property #{att.to_s} NOT assigned " }
89
+ #logger.info{"Property #{att.to_s} NOT assigned"}
67
90
  end
68
91
  end
69
92
  end
70
93
 
71
- if attributes['@type'] == 'd' # document
72
- @metadata[ :type ] = attributes.delete '@type'
73
- @metadata[ :class ] = attributes.delete '@class'
74
- @metadata[ :version ] = attributes.delete '@version'
75
- @metadata[ :fieldTypes ] = attributes.delete '@fieldTypes'
76
- if attributes.has_key?( '@rid' )
77
- rid = attributes.delete '@rid'
78
- cluster, record = rid[1,rid.size].split(':')
79
- @metadata[ :cluster ] = cluster.to_i
80
- @metadata[ :record ] = record.to_i
94
+ if attributes['@type'] == 'd' # document via REST
95
+ @metadata[:type] = attributes.delete '@type'
96
+ @metadata[:class] = attributes.delete '@class'
97
+ @metadata[:version] = attributes.delete '@version'
98
+ @metadata[:fieldTypes] = attributes.delete '@fieldTypes'
99
+ if attributes.has_key?('@rid')
100
+ rid = attributes.delete '@rid'
101
+ cluster, record = rid[1,rid.size].split(':')
102
+ @metadata[:cluster] = cluster.to_i
103
+ @metadata[:record] = record.to_i
81
104
  end
82
105
 
83
- #### edges -- remove in_ and out_ and de-capitalize the remaining edge
84
- if @metadata[ :fieldTypes ].present? && (@metadata[ :fieldTypes ] =~ /=g/)
106
+ if @metadata[:fieldTypes ].present? && (@metadata[:fieldTypes] =~ /=g/)
85
107
  edges = @metadata['fieldTypes'].split(',').find_all{|x| x=~/=g/}.map{|x| x.split('=').first}
86
108
  edges.each do |edge|
87
- operator, *base_edge = edge.split('_')
109
+ operator, *base_edge = edge.split('_')
88
110
  base_edge = base_edge.join('_')
89
- unless self.class.instance_methods.detect{|x| x == base_edge }
90
- ## define two methods: out_{Edge}/{in_Edge} -> edge.
91
- self.class.define_property base_edge, nil
92
- self.class.send :alias_method, base_edge.underscore, edge #
93
- # logger.debug { "#{link}:: edge #{edge} assigned to #{self.class.to_s} and remaped to #{base_edge.underscore}" }
94
-
111
+ unless self.class.instance_methods.detect{|x| x == base_edge}
112
+ ## define two methods: out_{Edge}/in_{Edge} -> edge.
113
+ self.class.define_property base_edge, nil
114
+ self.class.send :alias_method, base_edge.underscore, edge
95
115
  end
96
116
  end
97
117
  end
98
118
  end
99
-
100
-
101
- self.attributes = attributes # set_attribute_defaults is now after_init callback
102
- end
103
- ActiveOrient::Base.store_riid self
119
+ self.attributes = attributes # set_attribute_defaults is now after_init callback
104
120
  end
121
+ # puts "Storing #{self.rid} to rid-store"
122
+ ActiveOrient::Base.store_rid self
123
+ end
105
124
 
106
- # ActiveModel API (for serialization)
125
+ # ActiveModel API (for serialization)
107
126
 
108
127
  def attributes
109
128
  @attributes ||= HashWithIndifferentAccess.new
110
129
  end
111
130
 
112
131
  def attributes= attrs
113
- attrs.keys.each { |key| self.send("#{key}=", attrs[key]) }
132
+ attrs.keys.each{|key| self.send("#{key}=", attrs[key])}
114
133
  end
115
134
 
116
- # ActiveModel-style read/write_attribute accessors
117
- # Here we define the autoload mechanism
118
- def [] key
135
+ =begin
136
+ ActiveModel-style read/write_attribute accessors
137
+ Autoload mechanism and data conversion are defined in the method "from_orient" of each class
138
+ =end
119
139
 
120
- iv= attributes[key.to_sym]
121
- # iv.from_orient unless iv.nil?
122
- if iv.is_a?(String) && iv.rid? #&& @metadata[:fieldTypes].present? && @metadata[:fieldTypes].include?( key.to_s+"=x" )
123
- # puts "autoload: #{iv}"
124
- ActiveOrient::Model.autoload_object iv
125
- elsif iv.is_a?(Array) # && @metadata[:fieldTypes].present? && @metadata[:fieldTypes].match( key.to_s+"=[znmgx]" )
126
- # puts "autoload: #{iv.inspect}"
127
- OrientSupport::Array.new self, *iv.map{|y| (y.is_a?(String) && y.rid?) ? ActiveOrient::Model.autoload_object( y ) : y }
140
+ def [] key
141
+ iv = attributes[key.to_sym]
142
+ if @metadata[:fieldTypes].present? && @metadata[:fieldTypes].include?(key.to_s+"=t")
143
+ iv =~ /00:00:00/ ? Date.parse(iv) : DateTime.parse(iv)
144
+ elsif iv.is_a? Array
145
+ OrientSupport::Array.new( work_on: self, work_with: iv.from_orient){ key.to_sym }
146
+ elsif iv.is_a? Hash
147
+ OrientSupport::Hash.new( self, iv){ key.to_sym }
148
+ # elsif iv.is_a? RecordMap
149
+ # iv
150
+ # puts "RecordSet detected"
128
151
  else
129
-
130
- iv
152
+ iv.from_orient
131
153
  end
132
154
  end
133
155
 
134
- def update_attribute key, value
135
- @attributes[key] = value
136
- end
137
- =begin
138
- Here we define how the attributes are initialized
139
- Key and val are set by the RestCliend
140
- =end
141
156
  def []= key, val
142
- val = val.rid if val.is_a? ActiveOrient::Model
143
- # if val.is_a?(Array) # && @metadata[:fieldTypes].present? && @metadata[:fieldTypes].include?( key.to_s+"=n" )
144
- # if @metadata[ :fieldTypes ] =~ /out=x,in=x/
145
- # puts "VAL is a ARRAY"
146
- # else
147
- # puts "METADATA: #{ @metadata[ :fieldTypes ]} "
148
- # end
149
- # val# = val.map{|x| if val.is_a? ActiveOrient::Model then val.rid else val end }
150
- # end
157
+ val = val.rid if val.is_a?( ActiveOrient::Model ) && val.rid.rid?
151
158
  attributes[key.to_sym] = case val
152
- when Array
153
- if val.first.is_a?(Hash)
154
- v=val.map do |x|
155
- if x.is_a?( Hash )
156
- HashWithIndifferentAccess.new(x)
157
- else
158
- x
159
- end
160
- end
161
- OrientSupport::Array.new( self, *v )
162
- else
163
- OrientSupport::Array.new( self, *val )
164
- end
165
- when Hash
166
- HashWithIndifferentAccess.new(val)
167
- else
168
- val
169
- end
170
-
159
+ when Array
160
+ if val.first.is_a?(Hash)
161
+ v = val.map do |x|
162
+ if x.is_a?(Hash)
163
+ HashWithIndifferentAccess.new(x)
164
+ else
165
+ x
166
+ end
167
+ end
168
+ OrientSupport::Array.new(work_on: self, work_with: v )
169
+ else
170
+ OrientSupport::Array.new(work_on: self, work_with: val )
171
+ end
172
+ when Hash
173
+ HashWithIndifferentAccess.new(val)
174
+ else
175
+ val
176
+ end
177
+ end
178
+
179
+ def update_attribute key, value
180
+ @attributes[key] = value
171
181
  end
172
182
 
173
183
  def to_model
174
184
  self
175
185
  end
176
186
 
187
+ # Noop methods mocking ActiveRecord::Base macros
177
188
 
178
-
179
- ### Noop methods mocking ActiveRecord::Base macros
180
-
181
189
  def self.attr_protected *args
182
190
  end
183
191
 
184
192
  def self.attr_accessible *args
185
193
  end
186
194
 
187
- ### ActiveRecord::Base association API mocks
188
-
189
- def self.belongs_to model, *args
190
- attr_accessor model
191
- end
192
-
193
- def self.has_one model, *args
194
- attr_accessor model
195
- end
196
-
197
- def self.has_many models, *args
198
- attr_accessor models
199
-
200
- define_method(models) do
201
- self.instance_variable_get("@#{models}") ||
202
- self.instance_variable_set("@#{models}", [])
203
- end
204
- end
205
-
206
- def self.find *args
207
- []
208
- end
209
-
210
- ### ActiveRecord::Base callback API mocks
211
-
212
- define_model_callbacks :initialize, :only => :after
213
-
214
- ### ActiveRecord::Base misc
195
+ # ActiveRecord::Base association API mocks
196
+ #
197
+ # def self.belongs_to model, *args
198
+ # attr_accessor model
199
+ # end
200
+ #
201
+ # def self.has_one model, *args
202
+ # attr_accessor model
203
+ # end
204
+ #
205
+ # def self.has_many models, *args
206
+ # attr_accessor models
207
+ # define_method(models) do
208
+ # self.instance_variable_get("@#{models}") || self.instance_variable_set("@#{models}", [])
209
+ # end
210
+ # end
211
+ #
212
+ # def self.find *args
213
+ # []
214
+ # end
215
+ #
216
+ # ActiveRecord::Base misc
215
217
 
216
218
  def self.serialize *properties
217
219
  end
218
220
 
219
221
  end # Model
220
- end # module
222
+ end # module
@@ -3,83 +3,83 @@ require 'active_support/concern'
3
3
  require 'active_support/hash_with_indifferent_access'
4
4
 
5
5
  module ActiveOrient
6
-
7
- # Module adds prop Macro and
8
6
  module BaseProperties
9
7
  extend ActiveSupport::Concern
10
8
 
11
- ### Instance methods
9
+ # Default presentation of ActiveOrient::Model-Objects
12
10
 
13
- # Default presentation
14
11
  def to_human
15
12
  "<#{self.class.to_s.demodulize}: " + content_attributes.map do |attr, value|
16
- "#{attr}: #{value}" unless value.nil?
17
- end.compact.sort.join(' ') + ">"
13
+ v= case value
14
+ when ActiveOrient::Model
15
+ "< #{self.class.to_.demodulize} : #{value.rrid} >"
16
+ else
17
+ value.from_orient
18
+ end
19
+ "%s : %s" % [ attr, v] unless v.nil?
20
+ end.compact.sort.join(', ') + ">".gsub('"' , ' ')
18
21
  end
19
22
 
20
- # Comparison support
21
- def content_attributes
23
+ # Comparison support
24
+
25
+ def content_attributes # :nodoc:
22
26
  HashWithIndifferentAccess[attributes.reject do |(attr, _)|
23
- attr.to_s =~ /(_count)\z/ ||
24
- [:created_at, :updated_at, :type,
25
- :id, :order_id, :contract_id].include?(attr.to_sym)
27
+ attr.to_s =~ /(_count)\z/ || [:created_at, :updated_at, :type, :id, :order_id, :contract_id].include?(attr.to_sym)
26
28
  end]
27
29
  end
28
30
 
29
- # Update nil attributes from given Hash or model
30
- def update_missing attrs
31
- attrs = attrs.content_attributes unless attrs.kind_of?(Hash)
31
+ # Update nil attributes from given Hash or model
32
32
 
33
- attrs.each { |attr, val| send "#{attr}=", val if send(attr).blank? }
33
+ def update_missing attrs # :nodoc:
34
+ attrs = attrs.content_attributes unless attrs.kind_of?(Hash)
35
+ attrs.each{|attr, val| send "#{attr}=", val if send(attr).blank?}
34
36
  self # for chaining
35
37
  end
36
38
 
37
- # Default Model comparison
38
- def == other
39
+ # Default Model comparison
40
+
41
+ def == other # :nodoc:
39
42
  case other
40
43
  when String # Probably a link or a rid
41
- link == other || rid == other
44
+ "##{rid}" == other || rid == other
45
+ when ActiveOrient::Model
46
+ rid == other.rid
42
47
  else
43
- content_attributes.keys.inject(true) { |res, key|
44
- res && other.respond_to?(key) && (send(key) == other.send(key)) }
48
+ content_attributes.keys.inject(true){ |res, key|
49
+ res && other.respond_to?(key) && (send(key) == other.send(key))
50
+ }
45
51
  end
46
52
  end
47
53
 
48
- ### Default attributes support
54
+ # Default attributes support
49
55
 
50
56
  def default_attributes
51
57
  {:created_at => Time.now,
52
- :updated_at => Time.now,
53
- }
58
+ :updated_at => Time.now}
54
59
  end
55
60
 
56
- def set_attribute_defaults
61
+ def set_attribute_defaults # :nodoc:
57
62
  default_attributes.each do |key, val|
58
63
  self.send("#{key}=", val) if self.send(key).nil?
59
- # self.send("#{key}=", val) if self[key].nil? # Problems with association defaults
60
64
  end
61
65
  end
62
66
 
63
67
  included do
64
-
65
68
  after_initialize :set_attribute_defaults
66
69
 
67
- ### Class macros
70
+ # Class macros
68
71
 
69
- def self.prop *properties
72
+ def self.prop *properties # :nodoc:
70
73
  prop_hash = properties.last.is_a?(Hash) ? properties.pop : {}
71
-
72
74
  properties.each { |names| define_property names, nil }
73
75
  prop_hash.each { |names, type| define_property names, type }
74
76
  end
75
77
 
76
- def self.define_property names, body
78
+ def self.define_property names, body # :nodoc:
77
79
  aliases = [names].flatten
78
80
  name = aliases.shift
79
81
  instance_eval do
80
-
81
82
  define_property_methods name, body
82
-
83
83
  aliases.each do |ali|
84
84
  alias_method "#{ali}", name
85
85
  alias_method "#{ali}=", "#{name}="
@@ -87,8 +87,7 @@ module ActiveOrient
87
87
  end
88
88
  end
89
89
 
90
- def self.define_property_methods name, body={}
91
- #p name, body
90
+ def self.define_property_methods name, body={} # :nodoc:
92
91
  case body
93
92
  when '' # default getter and setter
94
93
  define_property_methods name
@@ -100,23 +99,24 @@ module ActiveOrient
100
99
  :validate => body[2]
101
100
 
102
101
  when Hash # recursion base case
102
+ # puts "NAME: "+name.to_S
103
+ # puts "BODY::"+body.inspect
103
104
  getter = case # Define getter
104
105
  when body[:get].respond_to?(:call)
105
106
  body[:get]
106
107
  when body[:get]
107
- proc { self[name].send "to_#{body[:get]}" }
108
+ proc{self[name].send "to_#{body[:get]}"}
108
109
  else
109
- proc { self[name] }
110
+ proc{self[name]}
110
111
  end
111
112
  define_method name, &getter if getter
112
-
113
113
  setter = case # Define setter
114
114
  when body[:set].respond_to?(:call)
115
115
  body[:set]
116
116
  when body[:set]
117
- proc { |value| self[name] = value.send "to_#{body[:set]}" }
117
+ proc{|value| self[name] = value.send "to_#{body[:set]}"}
118
118
  else
119
- proc { |value| self[name] = value } # p name, value;
119
+ proc{|value| self[name] = value} # p name, value;
120
120
  end
121
121
  define_method "#{name}=", &setter if setter
122
122
 
@@ -130,14 +130,13 @@ module ActiveOrient
130
130
  end
131
131
  end
132
132
 
133
- # TODO define self[:name] accessors for :virtual and :flag properties
133
+ # todo define self[:name] accessors for :virtual and :flag properties
134
134
 
135
135
  else # setter given
136
136
  define_property_methods name, :set => body, :get => body
137
137
  end
138
138
  end
139
139
 
140
- # Timestamps in lightweight models
141
140
  unless defined?(ActiveRecord::Base) && ancestors.include?(ActiveRecord::Base)
142
141
  prop :created_at, :updated_at
143
142
  end