Class: ActiveOrient::Base

Inherits:
Object show all
Extended by:
ActiveModel::Callbacks, ActiveModel::Naming
Includes:
ActiveModel::Serialization, ActiveModel::Serializers::JSON, ActiveModel::Validations, Conversions, OrientDB
Defined in:
lib/base.rb

Overview

Base class for tableless IB data Models, extends ActiveModel API

Direct Known Subclasses

Model

Constant Summary collapse

@@rid_store =

Every Rest::Base-Object is stored in the @@rid_store

The Objects are just references to the @@rid_store.
Any Change of the Object is thus synchonized to any allocated variable.
Hash.new

Constants included from OrientDB

OrientDB::DocumentDatabase, OrientDB::DocumentDatabasePool, OrientDB::DocumentDatabasePooled, OrientDB::GraphDatabase, OrientDB::IndexType, OrientDB::OClassImpl, OrientDB::OTraverse, OrientDB::PropertyImpl, OrientDB::RemoteStorage, OrientDB::SQLCommand, OrientDB::SQLSynchQuery, OrientDB::Schema, OrientDB::SchemaProxy, OrientDB::SchemaType, OrientDB::ServerAdmin, OrientDB::User, OrientDB::UsingJava

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}, opts = {}) ⇒ Base

If a opts hash is given, keys are taken as attribute names, values as data. The model instance fields are then set automatically from the opts Hash.


96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/base.rb', line 96

def initialize attributes = {}, opts = {}
	logger.progname = "ActiveOrient::Base#initialize"
	@metadata = Hash.new # HashWithIndifferentAccess.new
	@d =  nil
	run_callbacks :initialize do
		if RUBY_PLATFORM == 'java' && attributes.is_a?( Document )
			@d = attributes
			attributes =  @d.values
			@metadata[:class]      = @d.class_name
			@metadata[:version]    = @d.version
			@metadata[:cluster], @metadata[:record] = @d.rid[1,@d.rid.size].split(':')
			puts "Metadata:  #{@metadata}"
		end

		# transform $current to :current and $current.mgr to :mgr
		 transformers = attributes.keys.map{|x|  [x, x[1..-1].split(".").last.to_sym] if x[0] == '$'}.compact
		 # transformers:  [ [original key, modified key] , [] ]
		 transformers.each do |a|
			 attributes[a.last] = attributes[a.first]
			 attributes.delete a.first
		 end

		attributes.keys.each do |att|
			unless att[0] == "@" # @ identifies Metadata-attributes
				unless self.class.instance_methods.detect{|x| x == att.to_sym}
					self.class.define_property att.to_sym, nil
				else
					#logger.info{"Property #{att.to_s} NOT assigned"}
				end
			end
		end
		if attributes['@type'] == 'd'  # document via REST
			@metadata[:type]       = attributes.delete '@type'
			@metadata[:class]      = attributes.delete '@class'
			@metadata[:version]    = attributes.delete '@version'
			@metadata[:fieldTypes] = attributes.delete '@fieldTypes'
			
			if attributes.has_key?('@rid')
				rid = attributes.delete '@rid'
				cluster, record = rid[1 .. -1].split(':')
				@metadata[:cluster] = cluster.to_i
				@metadata[:record]  = record.to_i
			end

			if @metadata[:fieldTypes ].present? && (@metadata[:fieldTypes] =~ /=g/)
				@metadata[:edges] = { :in => [], :out => [] }
				edges = @metadata[:fieldTypes].split(',').find_all{|x| x=~/=g/}.map{|x| x.split('=').first}
				#  puts "Detected EDGES: #{edges.inspect}"
				edges.each do |edge|
					operator, *base_edge = edge.split('_')
					base_edge = base_edge.join('_')
					@metadata[:edges][operator.to_sym] << base_edge
				end
				#    unless self.class.instance_methods.detect{|x| x == base_edge}
				#      ## define two methods: out_{Edge}/in_{Edge} -> edge.
				#      self.class.define_property base_edge, nil
				#      allocate_edge_method = -> (edge)  do
				#        unless (ee=db.get_db_superclass(edge)) == "E"
				#          allocate_edge_method[ee]
				#          self.class.send :alias_method, base_edge.underscore, edge
				#      ## define inherented classes, tooa
				#      

				#    end
				#  end
			end
		end
		self.attributes = attributes # set_attribute_defaults is now after_init callback
	end
	#      puts "Storing #{self.rid} to rid-store"
	#      ActiveOrient::Base.store_rid( self ) do | cache_obj|
	#	 cache_obj.reload! self
	#      end
end

Instance Attribute Details

#metadataObject (readonly)

Used to read the metadata


24
25
26
# File 'lib/base.rb', line 24

def 
  @metadata
end

Class Method Details

.attr_accessible(*args) ⇒ Object


263
264
# File 'lib/base.rb', line 263

def self.attr_accessible *args
end

.attr_protected(*args) ⇒ Object

Noop methods mocking ActiveRecord::Base macros


260
261
# File 'lib/base.rb', line 260

def self.attr_protected *args
end

.belongs_to(model, *args) ⇒ Object

ActiveRecord::Base association API mocks


268
269
270
# File 'lib/base.rb', line 268

def self.belongs_to model, *args # :nodoc:
  attr_accessor model
end

.display_ridObject


33
34
35
# File 'lib/base.rb', line 33

def self.display_rid
  @@rid_store
end

.exclude_the_following_properties(*args) ⇒ Object

Exclude some properties from loading via get, reload!, get_document, get_record


290
291
292
293
294
# File 'lib/base.rb', line 290

def self.exclude_the_following_properties *args
  puts "excluding #{args}"
@excluded =  (@excluded.is_a?( Array))?  @excluded + args : args
  puts "#{self.inspect} --> excluded #{@excluded}"
end

.get_rid(rid) ⇒ Object


54
55
56
57
# File 'lib/base.rb', line 54

def self.get_rid rid
  rid =  rid[1..-1] if rid[0]=='#'
  @@rid_store[rid] 
end

.has_many(models, *args) ⇒ Object

:nodoc:


276
277
278
279
280
281
# File 'lib/base.rb', line 276

def self.has_many models, *args  # :nodoc:
  attr_accessor models
  define_method(models) do
    self.instance_variable_get("@#{models}") || self.instance_variable_set("@#{models}", [])
  end
end

.has_one(model, *args) ⇒ Object

:nodoc:


272
273
274
# File 'lib/base.rb', line 272

def self.has_one model, *args   # :nodoc:
  attr_accessor model
end

.remove_rid(obj) ⇒ Object

removes an Item from the cache

obj has to provide a method #rid

thus a string or a Model-Object is accepted


45
46
47
48
49
50
51
52
# File 'lib/base.rb', line 45

def self.remove_rid obj
	if obj &.rid.present?
    @@rid_store.delete obj.rid     
	else
		logger.error "Cache entry not removed: #{obj} "

	end
end

.reset_rid_storeObject


59
60
61
# File 'lib/base.rb', line 59

def self.reset_rid_store
  @@rid_store = Hash.new
end

.serialize(*properties) ⇒ Object

ActiveRecord::Base misc


297
298
# File 'lib/base.rb', line 297

def self.serialize *properties # :nodoc:
end

.store_rid(obj) ⇒ Object

Stores the obj in the cache.

If the cache-value exists, it is updated by the data provided in obj and the cached obj is returned


70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/base.rb', line 70

def self.store_rid obj
  if obj.rid.present? && obj.rid.rid?
	 if @@rid_store[obj.rid].present?
  @@rid_store[obj.rid].transfer_content from: obj
	  else
		 @@rid_store[obj.rid] =   obj
	  end
	 @@rid_store[obj.rid] 
  else
	nil 
  end
end

Instance Method Details

#[](key) ⇒ Object

ActiveModel-style read/write_attribute accessors

Autoload mechanism and data conversion are defined in the method "from_orient" of each class

205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/base.rb', line 205

def [] key

	iv = attributes[key]
	if ( key: key) == "t"
		iv =~ /00:00:00/ ? Date.parse(iv) : DateTime.parse(iv)
	elsif ( key: key) == "x"
		iv = ActiveOrient::Model.autoload_object iv
	elsif iv.is_a? Array
		OrientSupport::Array.new( work_on: self, work_with: iv.from_orient){ key.to_sym }
	elsif iv.is_a? Hash
#				if iv.keys.include?("@class" )
#				ActiveOrient::Model.orientdb_class( name: iv["@class"] ).new iv
#				else
#					iv
		OrientSupport::Hash.new( self, iv.from_orient){ key.to_sym }
	#			end
		#     elsif iv.is_a? RecordMap 
		#      iv
		#       puts "RecordSet detected"
	else
		iv.from_orient
	end
end

#[]=(key, val) ⇒ Object


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/base.rb', line 229

def []= key, val
	val = val.rid if val.is_a?( ActiveOrient::Model ) && val.rid.rid?
	attributes[key.to_sym] = case val
													 when Array
														 if val.first.is_a?(Hash)
															 v = val.map{ |x| x }
															 OrientSupport::Array.new(work_on: self, work_with: v )
														 else
															 OrientSupport::Array.new(work_on: self, work_with: val )
														 end
													 when Hash
														 if val.keys.include?("@class" )
															 OrientSupport::Array.new( work_on: self, work_with: val.from_orient){ key.to_sym }
														 else
															 OrientSupport::Hash.new( self, val  )
														 end
													 else
														 val
													 end
end

#attributesObject


178
179
180
# File 'lib/base.rb', line 178

def attributes
  @attributes ||= Hash.new # WithIndifferentAccess.new
end

#attributes=(attrs) ⇒ Object


182
183
184
# File 'lib/base.rb', line 182

def attributes= attrs
  attrs.keys.each{|key| self.send("#{key}=", attrs[key])}
end

ActiveModel API (for serialization)


173
174
175
176
# File 'lib/base.rb', line 173

def included_links
  meta= Hash[ @metadata[:fieldTypes].split(',').map{|x| x.split '='} ]
  meta.map{|x,y| x if y=='x'}.compact
end

#my_metadata(key: nil, symbol: nil) ⇒ Object


186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/base.rb', line 186

def  key: nil, symbol: nil
	if @metadata[:fieldTypes].present?  
		meta= Hash[ @metadata[:fieldTypes].split(',').map{|x| x.split '='} ]
		if key.present?
			meta[key.to_s]
		elsif symbol.present?
			meta.map{|x,y| x if y == symbol.to_s }.compact
		else
			meta
		end
	end
end

#to_modelObject

:nodoc:


254
255
256
# File 'lib/base.rb', line 254

def to_model   # :nodoc:
  self
end

#update_attribute(key, value) ⇒ Object


250
251
252
# File 'lib/base.rb', line 250

def update_attribute key, value
  @attributes[key] = value
end