Class: ActiveOrient::API

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

Overview

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_classes_in_ruby, #classname, #create_class, #create_edge, #delete_edge, #delete_vertex, #update_or_create_records

Methods included from DatabaseUtils

#class_hierarchy, #create_edge_class, #create_vertex_class, #database_classes, #fv, #fx, #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



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/java-api.rb', line 346

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



291
292
293
294
295
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
# File 'lib/java-api.rb', line 291

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



273
274
275
276
277
278
279
280
281
282
283
# File 'lib/java-api.rb', line 273

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



262
263
264
265
266
267
268
269
# File 'lib/java-api.rb', line 262

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



393
394
395
396
397
398
399
400
401
402
403
# File 'lib/java-api.rb', line 393

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



423
424
425
426
427
428
429
430
431
432
433
434
435
# File 'lib/java-api.rb', line 423

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



373
374
375
376
377
378
379
# File 'lib/java-api.rb', line 373

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



410
411
412
413
414
415
416
417
418
419
420
# File 'lib/java-api.rb', line 410

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



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/java-api.rb', line 234

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