Class: ActiveOrient::API

Inherits:
Object show all
Includes:
ClassUtils, DatabaseUtils, OrientDB, OrientDbPrivate, OrientSupport::Support
Defined in:
lib/java-api.rb,
lib/jdbc.rb

Overview

class Date

   def proxy_object
     java.util.Date.new year, month - 1, day, 0, 0, 0 
   end
end
class DateTime
   def proxy_object
     java.util.Date.new year, month - 1, day, hour, min, sec
   end
end

Constant Summary

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

Instance Method Summary collapse

Methods included from ClassUtils

#allocate_class_in_ruby, #classname, #create_class, #create_edge_class, #create_vertex_class, #delete_edge

Methods included from DatabaseUtils

#class_hierarchy, #database_classes, #get_db_superclass, #preallocate_classes, #system_classes

Methods included from OrientSupport::Support

#compose_where, #generate_sql_list

Constructor Details

#initialize(database: nil, connect: true, preallocate: true) ⇒ API

Returns a new instance of API.


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/jdbc.rb', line 24

def initialize database: nil, connect: true, preallocate: true
  self.logger = Logger.new('/dev/stdout') unless logger.present?
  self.default_server = {
    :server => 'localhost',
    :port => 2480,
    :protocol => 'http',
    :user => 'root',
    :password => 'root',
    :database => 'temp'
  }.merge default_server.presence || {}
  @database = database || default_server[:database]
  @all_classes=[]
  #puts   ["remote:#{default_server[:server]}/#{@database}",
#					default_server[:user], default_server[:password] ]
  connect() if connect
#      @db  =   DocumentDatabase.connect("remote:#{default_server[:server]}/#{@database}",
#					default_server[:user], default_server[:password] )
  ActiveOrient::Model.api = self 
  preallocate_classes  if preallocate

end

Instance Attribute Details

#databaseObject (readonly)

Used to read the working database


19
20
21
# File 'lib/jdbc.rb', line 19

def database
  @database
end

Instance Method Details

#connectObject

Used to connect to the database


55
56
57
58
59
60
# File 'lib/jdbc.rb', line 55

def connect

  @db  =   DocumentDatabase.connect("remote:#{default_server[:server]}/#{@database}",
	default_server[:user], default_server[:password] )
  @classes =  get_database_classes
end

#create_classes(classes, &b) ⇒ Object


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/jdbc.rb', line 75

def create_classes classes , &b
  consts = allocate_classes_in_ruby( classes , &b )

  all_classes = consts.is_a?( Array) ? consts.flatten : [consts]
  get_database_classes(requery: true)
  selected_classes =  all_classes.map do | this_class |
	this_class unless get_database_classes(requery: false).include?( this_class.ref_name ) rescue nil
  end.compact.uniq
  command= selected_classes.map do | database_class |
	## improper initialized ActiveOrient::Model-classes lack a ref_name class-variable
	next if database_class.ref_name.blank?  
	c = if database_class.superclass == ActiveOrient::Model || database_class.superclass.ref_name.blank?
   puts "CREATE CLASS #{database_class.ref_name} "
   OClassImpl.create @db, database_class.ref_name 
 else
   puts "CREATE CLASS #{database_class.ref_name} EXTENDS #{database_class.superclass.ref_name}"
   OClassImpl.create @db, superClass: database_class.ref_name 
 end
  end

  # update the internal class hierarchy 
  get_database_classes requery: true
  # return all allocated classes, no matter whether they had to be created in the DB or not.
  #  keep the format of the input-parameter
  consts.shift if block_given? && consts.is_a?( Array) # remove the first element
  # remove traces of superclass-allocations
  if classes.is_a? Hash
	consts =  Hash[ consts ] 
	consts.each_key{ |x| consts[x].delete_if{|y| y == x} if consts[x].is_a? Array  }
  end
  consts
end

#create_index(o_class, name:, on: :automatic, type: :unique) ⇒ Object


175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/jdbc.rb', line 175

def create_index o_class, name:, on: :automatic, type: :unique
  logger.progname = 'JavaApi#CreateIndex'
  begin
	c = @db.get_class( classname( o_class ))
	index = if on == :automatic
nil   # not implemented
		elsif on.is_a? Array
c.createIndex name.to_s, INDEX_TYPES[type],  *on
		else
c.createIndex name.to_s, INDEX_TYPES[type],  on
		end
  end
end

#create_properties(o_class, **all_properties, &b) ⇒ Object

Creates properties and optional an associated index as defined in the provided block

  create_properties(classname or class, properties as hash){index}

The default-case
  create_properties(:my_high_sophisticated_database_class,
		con_id: {type: :integer},
		details: {type: :link, linked_class: 'Contracts'}) do
		  contract_idx: :notunique
		end

A composite index
  create_properties(:my_high_sophisticated_database_class,
		con_id: {type: :integer},
		symbol: {type: :string}) do
	    {name: 'indexname',
			 on: [:con_id, :details]    # default: all specified properties
			 type: :notunique            # default: :unique
	    }
		end

supported types: {

:bool          => "BOOLEAN",
:double        => "BYTE",
:datetime      => "DATE",
:float         => "FLOAT",
:decimal       => "DECIMAL",
:embedded_list => "EMBEDDEDLIST",
:list          => "EMBEDDEDLIST",
:embedded_map  => "EMBEDDEDMAP",
:map           => "EMBEDDEDMAP",
:embedded_set  => "EMBEDDEDSET",
:set           => "EMBEDDEDSET",
:int           => "INTEGER",
:integer       => "INTEGER",
:link_list     => "LINKLIST",
:link_map      => "LINKMAP",
:link_set      => "LINKSET",
}

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
# File 'lib/jdbc.rb', line 136

def create_properties o_class, **all_properties, &b
logger.progname = 'JavaApi#CreateProperties'
ap =  all_properties
created_properties = ap.map do |property, specification | 
	puts "specification:  #{specification.inspect}"
	field_type = ( specification.is_a?( Hash) ?  specification[:type] : specification ).downcase.to_sym rescue :string
	the_other_class =  specification.is_a?(Hash) ?  specification[:other_class] : nil
	other_class = if the_other_class.present? 
			@db.get_class( the_other_class)
  end
	index =  ap.is_a?(Hash) ?  ap[:index] : nil
	if other_class.present?
	  @db.get_class(classname(o_class)).add property,[ field_type, other_class ], { :index => index }
	else
	  @db.get_class(classname(o_class)).add property, field_type, { :index => index }
	end
end
if block_given?
	attr =  yield
  index_parameters = case attr 
	when String, Symbol
	  { name: attr }
	when Hash
	  { name: attr.keys.first , type: attr.values.first, on: all_properties.keys.map(&:to_s) }
	else
	  nil
	end
	create_index o_class, **index_parameters unless index_parameters.blank?
end
created_properties.size # return_value

end

#create_record(o_class, attributes: {}) ⇒ Object Also known as: create_document


189
190
191
192
193
194
195
# File 'lib/jdbc.rb', line 189

def create_record o_class, attributes: {}
  logger.progname = 'HavaApi#CreateRecord'
  attributes = yield if attributes.empty? && block_given?
  new_record = insert_document( o_class, attributes.to_orient )


end

#dbObject


46
47
48
# File 'lib/jdbc.rb', line 46

def db
  @db
end

#delete_class(o_class) ⇒ Object


110
111
112
113
# File 'lib/jdbc.rb', line 110

def delete_class o_class
  @db.schema.drop_class classname(o_class)
  get_database_classes requery: true 
end

#delete_record(*object_or_rid) ⇒ Object


351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/java-api.rb', line 351

def delete_record  *object_or_rid
  object_or_rid.map do |o|
	d= case o
when  String 
  @db.custom "select from #{o}" if o.rid?
when  ActiveOrient::Model
  @db.custom "select from #{o.to_orient}"
when Array
  o.map{|y| delete_record y }
  return o
else
  o
end
	if d.is_a? Java::ComOrientechnologiesOrientCoreSqlQuery::OConcurrentResultSet
	  d.each &:delete      
	else
	  logger.progname = 'JavaApi#DeleteRecord'
	  logger.error{ "Removal Failed: #{d.inspect} " }
	end
  end
end

#execute(transaction: true, tolerated_error_code: nil, process_error: true) ⇒ Object

executes a command as sql-query


296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/java-api.rb', line 296

def execute transaction: true, tolerated_error_code: nil , process_error: true# Set up for classes
  batch = {transaction: transaction, operations: yield}

  logger.progname= "Execute"
  unless batch[:operations].blank?
	unless batch[:operations].is_a? Array
	  batch[:operations] = [batch[:operations]] 	
	  was_array =  true
	else
	  was_array =  false
	end
	answer = batch[:operations].map do |command_record|
	  return if command_record.blank? 
	  begin
	  response = @db.run_command  command_record.is_a?(Hash) ?  command_record[:command] : command_record 
	  rescue Java::ComOrientechnologiesOrientCoreStorage::ORecordDuplicatedException => e
#	    puts e.inspect
#	    puts "GetMESSAGE: "+e.getMessage.split(/\r/).first
#	    puts "GetComponentName: "+e.getComponentName.to_s
#	    puts  e.getMessage =~ tolerated_error_code
#	    puts "----"
 if tolerated_error_code.present? &&  e.getMessage =~ tolerated_error_code
   logger.info{ "tolerated_error::#{ e.get_message.split(/\r/).first }"}
   next
 else
#	    if process_error
   logger.progname = 'JavaApi#Execute'
   logger.error{ e }
#	    else 
#	      puts e.inspect
#	      raise ArgumentError, e, caller
 end
	  end
	  if response.is_a? Fixnum
 response
	  else
 response.map do | r |
   if r.is_a? Document
		if r.rid.rid? 
update_document r 
		else
ActiveOrient::Model.orientdb_class( name: 'query').new  r
		end
   else 
		puts "Strange things happen in execute: #{r.inspect}"
		r.values
   end
 end  # map response
	  end	#  branch response_is_a
	end	# map batch
	answer.pop if answer.size==1 && answer.first.is_a?(Array)
  end	# unless
end

#get_classes(*attributes) ⇒ Object


64
65
66
67
68
69
70
71
72
# File 'lib/jdbc.rb', line 64

def get_classes *attributes
  classes=  @db..schema.classes.map{|x| { 'name' => x.name , 'superClass' => x.get_super_class.nil? ? '': x.get_super_class.name } }
  unless attributes.empty?
	classes.map{|y| y.select{|v,_| attributes.include?(v)}}
  else
	classes
  end

end

#get_properties(o_class) ⇒ Object


169
170
171
# File 'lib/jdbc.rb', line 169

def get_properties o_class
  @db.get_class(classname(o_class)).propertiesMap
end

#get_record(rid) ⇒ Object Also known as: get_document

called by Model.autoload


278
279
280
281
282
283
284
285
286
287
288
# File 'lib/java-api.rb', line 278

def get_record rid
  logger.progname = 'JavaApi#GetRecord'
  rid = "#"+ rid unless rid[0]=='#'
  record = @db.custom "select from #{rid}"
  if record.count.zero?
	logger.error{ "No record found for rid= #{rid}" }
  else
	yield( record[0] ) if block_given?
	update_document record[0]
  end
end

#get_records(raw: false, query: nil, **args) ⇒ Object Also known as: get_documents


267
268
269
270
271
272
273
274
# File 'lib/java-api.rb', line 267

def get_records raw: false, query: nil, **args
  query = OrientSupport::OrientQuery.new(args) if query.nil?
  logger.progname = 'JavaApi#GetRecords'
  result =  @db.custom query.compose
  result.map do |record|
	update_document record
  end
end

#insert_document(o_class, attributes) ⇒ Object

private


398
399
400
401
402
403
404
405
406
407
408
# File 'lib/java-api.rb', line 398

def insert_document o_class, attributes
  d =  Document.create @db, classname(o_class), **attributes
  d.save
  ActiveOrient::Model.get_model_class(classname(o_class)).new attributes.merge( { "@rid" => d.rid,
								  "@version" => d.version,
								  "@type" => 'd',
								  "@class" => classname(o_class) } )



end

#manipulate_relation(record, method, array, items) ⇒ Object


428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'lib/java-api.rb', line 428

def manipulate_relation record,  method, array, items
  java_document = record.document
  method =  method.to_s.downcase.to_sym
  case method 
  when :add
	items.each{|x| java_document[array] << x}
  when :remove
	items.each{|x| java_document[array].delete x}
  else

  end
	java_document.save
end

#update(rid, attributes = nil, version = nil) ⇒ Object

Transfer changes in attributes to document first and save the document No SQL involved


378
379
380
381
382
383
384
# File 'lib/java-api.rb', line 378

def update rid, attributes=nil, version=nil
  record = ActiveOrient::Model.autoload_object rid.rid
  record.document.update_attributes attributes if attributes.present?
  record.document.save
  record.attributes.merge! attributes if attributes.present?
  record # return_value
end

#update_document(java_document) ⇒ Object

returns a valid model-instance


415
416
417
418
419
420
421
422
423
424
425
# File 'lib/java-api.rb', line 415

def update_document java_document
  if java_document.is_a? Document
	o_class =  java_document.class_name
	java_document.save
	d =  java_document
	ActiveOrient::Model.get_model_class(o_class).new  java_document
  else
	logger.progname = 'JavaApi#UpdateDocument'
	logger.error{ "Wrong Parameter: #{java_document.inspect} "}
  end
end

#upsert(o_class, set: {}, where: {}) ⇒ Object


239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/java-api.rb', line 239

def upsert o_class, set: {}, where: {} 
  logger.progname = 'JavaApi#Upsert'
  if where.blank?
	new_record = create_record(o_class, attributes: set)
	yield new_record if block_given?	  # in case if insert execute optional block
	new_record			  # return_value
  else
	specify_return_value =  block_given? ? "" : "return after @this"
	set.merge! where if where.is_a?( Hash ) # copy where attributes to set 
	command = "Update #{classname(o_class)} set #{generate_sql_list( set ){','}} upsert #{specify_return_value}  #{compose_where where}" 
	result =  @db.run_command command

	case result
	when  Java::JavaUtil::ArrayList
	  update_document result[0]
	when ActiveOrient::Model
	  result   # just return the result
	when String, Numeric
	  the_record=  get_records(from: o_class, where: where, limit: 1).pop
	  if result.to_i == 1  # one dataset inserted, block is specified
 yield the_record 	
	  end
	  the_record # return_value
	else
	  logger.error{ "Unexpected result form Query \n  #{command} \n Result: #{result}" }
	end
  end
end