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
@@mutex =
Mutex.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

Methods included from Conversions

#to_key, #to_param, #to_partial_path

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.



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
170
171
172
173
174
# File 'lib/base.rb', line 101

def initialize attributes = {}, opts = {}
	logger.progname = "ActiveOrient::Base#initialize"
	@metadata = Hash.new # HashWithIndifferentAccess.new
	@d =  nil if RUBY_PLATFORM == 'java' && attributes.is_a?( Document )
	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



278
279
# File 'lib/base.rb', line 278

def self.attr_accessible *args
end

.attr_protected(*args) ⇒ Object

Noop methods mocking ActiveRecord::Base macros



275
276
# File 'lib/base.rb', line 275

def self.attr_protected *args
end

.belongs_to(model, *args) ⇒ Object

ActiveRecord::Base association API mocks



283
284
285
# File 'lib/base.rb', line 283

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

.display_ridObject



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

def self.display_rid
  @@rid_store
end

.exclude_the_following_properties(*args) ⇒ Object

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



306
307
308
309
310
# File 'lib/base.rb', line 306

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



56
57
58
59
# File 'lib/base.rb', line 56

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

.has_many(models, *args) ⇒ Object

:nodoc:



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

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:



287
288
289
# File 'lib/base.rb', line 287

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



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

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

.reset_rid_storeObject



61
62
63
# File 'lib/base.rb', line 61

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

.serialize(*properties) ⇒ Object

ActiveRecord::Base misc



313
314
# File 'lib/base.rb', line 313

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



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/base.rb', line 72

def self.store_rid obj

	@@mutex.synchronize do 
		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
			obj 
		end
	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


210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/base.rb', line 210

def [] key

	iv = attributes[key]
	if ( key: key) == "t"
		# needed in case of 
		#  obj.date =  {some-date}
		#  --> perfrom an action on the date without saving prior
		case iv
		when String
		iv =~ /00:00:00/ ? Date.parse(iv) : DateTime.parse(iv) 
		when Date, DateTime
	    iv
		else
		raise "incompatable type used: #{iv} (#{iv.class}) -- Date or DateTime required"	 
		end
	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



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/base.rb', line 244

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 ){ key_to_sym }
														 else
															 OrientSupport::Array.new(work_on: self, work_with: val ){ key_to_sym }
														 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



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

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

#attributes=(attrs) ⇒ Object



187
188
189
# File 'lib/base.rb', line 187

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

ActiveModel API (for serialization)



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

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



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/base.rb', line 191

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:



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

def to_model   # :nodoc:
  self
end

#update_attribute(key, value) ⇒ Object



265
266
267
# File 'lib/base.rb', line 265

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