Module: ClassUtils
- Included in:
- ActiveOrient::API, ActiveOrient::OrientDB
- Defined in:
- lib/class_utils.rb
Instance Method Summary collapse
-
#allocate_classes_in_ruby(classes) ⇒ Object
AllocateClassesInRuby acts as a proxy to OrientdbClass, takes a classes-array as argument.
-
#classname(name_or_class) ⇒ Object
Returns a valid database-class name, nil if the class does not exists.
-
#create_class(classname, properties: nil, &b) ⇒ Object
create a single class and provide properties as well.
-
#create_edge(o_class, attributes: {}, from: nil, to: nil, unique: false, batch: nil) ⇒ Object
create_edge connects two vertexes.
-
#delete_edge(*edge) ⇒ Object
Deletes the specified edges and unloads referenced vertices from the cache.
-
#delete_vertex(*vertex) ⇒ Object
Deletes the specified vertices and unloads referenced edges from the cache.
-
#update_or_create_records(o_class, set: {}, where: {}, **args, &b) ⇒ Object
Creating a new Database-Entry (where is omitted) Or updating the Database-Entry (if present).
Instance Method Details
#allocate_classes_in_ruby(classes) ⇒ Object
AllocateClassesInRuby acts as a proxy to OrientdbClass, takes a classes-array as argument
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 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 107 108 109 110 111 112 113 |
# File 'lib/class_utils.rb', line 60 def allocate_classes_in_ruby classes # :nodoc: generate_ruby_object = ->( name, superclass, abstract ) do begin # if the class is predefined, use specs from get_classes or_def = get_classes('name', 'superClass', 'abstract' ).detect{|x| x['name']== name.to_s } superclass, abstract = or_def.reject{|k,v| k=='name'}.values unless or_def.nil? #print "GENERATE_RUBY_CLASS: #{name} / #{superclass} \n" m= ActiveOrient::Model.orientdb_class name: name, superclass: superclass m.abstract = abstract m.ref_name = name.to_s #puts "--> #{m.object_id}" m rescue NoMethodError => w logger.progname = "ClassUtils#AllocateClassesInRuby" logger.error{ w. } logger.error{ w.backtrace.map {|l| " #{l}\n"}.join } nil # raise end end superclass, abstract = if block_given? s = yield if s.is_a? Hash [s[:superclass],s[:abstract]] else [s,false] end else [nil,false] end #superclass_object = generate_ruby_object[superclass,nil,nil] if superclass.present? consts = case classes when Array next_superclass= superclass classes.map do |singleclass| if singleclass.is_a?( String) || singleclass.is_a?( Symbol) next_superclass = generate_ruby_object[singleclass,superclass,abstract] elsif singleclass.is_a?(Array) || singleclass.is_a?(Hash) allocate_classes_in_ruby( singleclass){ {superclass: next_superclass, abstract: abstract}} end end when Hash classes.keys.map do| h_superclass | [ generate_ruby_object[h_superclass,superclass,abstract], allocate_classes_in_ruby(classes[ h_superclass ]){{ superclass: h_superclass, abstract: abstract }} ] end when String, Symbol generate_ruby_object[classes,superclass, abstract] end consts end |
#classname(name_or_class) ⇒ Object
Returns a valid database-class name, nil if the class does not exists
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/class_utils.rb', line 8 def classname name_or_class # :nodoc: name = case name_or_class when ActiveOrient::Model name_or_class.class.ref_name when Class name_or_class.ref_name # name_or_class.to_s.split('::').last else name_or_class.to_s.split(':').last #.to_s.camelcase # capitalize_first_letter end ## 16/5/31 : reintegrating functionality to check wether the classname is # present in the database or not if database_classes.include?(name) name elsif database_classes.include?(name.underscore) name.underscore else logger.progname = 'ClassUtils#Classname' logger.warn{ "Classname #{name_or_class.inspect} ://: #{name} not present in #{ActiveOrient.database}" } nil end end |
#create_class(classname, properties: nil, &b) ⇒ Object
create a single class and provide properties as well
ORB.create_class( the_class_name as String or Symbol (nessesary) ,
properties: a Hash with property- and Index-descriptions (optional)){ {superclass: The name of the superclass as String or Symbol , abstract: true|false } (optional Block provides a Hash ) }
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/class_utils.rb', line 40 def create_class classname, properties: nil, &b the_class= create_classes( classname, &b ) # if multible classes are specified, don't process properties # ( if multible classes need the same properties, consider a nested class-design ) if the_class.is_a?(Array) if the_class.size == 1 the_class = the_class.first else properties = nil end end create_properties( the_class.ref_name , properties ) if properties.present? the_class # return_value end |
#create_edge(o_class, attributes: {}, from: nil, to: nil, unique: false, batch: nil) ⇒ Object
create_edge connects two vertexes
The parameter o_class can be either a class or a string
if batch is specified, the edge-statement is prepared and returned
else the statement is transmitted to the database
The method takes a block as well.
It must provide a Hash with :from and :to- Key's, e.g.
Vertex1, Vertex2 are two vertex-classes and TheEdge is an edge-class
record1 = ( 1 .. 100 ).map{ |y| Vertex1.create( testentry: y } }
record2 = ( :a .. :z ).map{ |y| Vertex2.create( testentry: y } }
edges = ORD.create_edge( TheEdge ) do | attributes |
(‘a’.ord .. ‘z’.ord).map do |o| { from: record1.find{|x| x.testentry == o }, to: record2.find{ |x| x.testentry.ord == o }, attributes: attributes.merge{ key: o.chr } } end
or
edges = ORD.create_edge( TheEdge ) do | attributes |
(‘a’.ord .. ‘z’.ord).map do |o| { from: Vertex1.where( testentry: o ).pop , to: Vertex2.where( testentry.ord => o).pop , attributes: attributes.merge{ key: o.chr } } end
Benefits: The statements are transmitted as batch.
The pure-ruby-solution minimizes traffic to the database-server and is prefered.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 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 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/class_utils.rb', line 180 def create_edge o_class, attributes: {}, from:nil, to:nil, unique: false, batch: nil logger.progname = "ClassUtils#CreateEdge" # ------------------------------- create_command = -> (attr, from, to ) do attr_string = attr.blank? ? "" : "SET #{generate_sql_list attr}" if from.present? && to.present? [from, to].each{|y| remove_record_from_hash y } { type: "cmd", language: 'sql', command: "CREATE EDGE #{classname(o_class)} FROM #{from.to_orient} TO #{to.to_orient} #{attr_string}" } end end # ------------------------------- if block_given? a = yield(attributes) command = if a.is_a? Array batch = nil command= a.map do | record | # puts record.inspect this_attributes = record[:attributes].presence || attributes create_command[ this_attributes, record[:from], record[:to]] end else this_attributes = a[:attributes].presence || attributes command = create_command[ this_attributes, a[:from], a[:to]] end elsif from.is_a?( Array ) && to.is_a?(Array) command = Array.new while from.size >1 this_attributes = attributes.is_a?(Array) ? attributes.shift : attributes command << create_command[ this_attributes, from.shift, to.shift] end elsif from.is_a? Array command = from.map{|f| create_command[ attributes, f, to] } elsif to.is_a? Array command = to.map{|f| create_command[ attributes, from, f] } # puts "COMMAND: #{command.inspect}" elsif from.present? && to.present? # if unique # wwhere = {out: from.to_orient, in: to.to_orient }.merge(attributes.to_orient) # existing_edge = get_records(from: o_class, where: wwhere) # if existing_edge.size >1 # logger.error{ "Unique specified, but there are #{existing_edge.size} Records in the Database. returning the first"} # command = existing_edge.first # batch = true # elsif existing_edge.size ==1 && existing_edge.first.is_a?(ActiveOrient::Model) # #logger.debug {"Reusing edge #{classname(o_class)} from #{from.to_orient} to #{to.to_orient}"} # command= existing_edge.first # batch= true # else command = create_command[ attributes, from, to] # end # #logger.debug {"Creating edge #{classname(o_class)} from #{from.to_orient} to #{to.to_orient}"} # elsif from.to_orient.nil? || to.to_orient.nil? logger.error{ "Parameter :from or :to is missing"} else # for or to are not set return nil end # puts "RUNNING EDGE: #{command.inspect}" if command.present? begin response = execute(transaction: false, tolerated_error_code: /found duplicated key/) do command.is_a?(Array) ? command.flatten.compact : [ command ] end if response.is_a?(Array) && response.size == 1 response.pop # RETURN_VALUE else response # return value (the normal case) end rescue ArgumentError => e puts "ArgumentError " puts e.inspect end # begin end end |
#delete_edge(*edge) ⇒ Object
Deletes the specified edges and unloads referenced vertices from the cache
279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/class_utils.rb', line 279 def delete_edge *edge create_command = -> do { type: "cmd", language: 'sql', command: "DELETE EDGE #{edge.map{|x| x.to_orient }.join(',')} " } end edge.each do |r| [r.in, r.out].each{| e | remove_record_from_hash e} remove_record_from_hash r end execute{ create_command[] } end |
#delete_vertex(*vertex) ⇒ Object
Deletes the specified vertices and unloads referenced edges from the cache
264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/class_utils.rb', line 264 def delete_vertex *vertex create_command = -> do { type: "cmd", language: 'sql', command: "DELETE VERTEX #{vertex.map{|x| x.to_orient }.join(',')} " } end vertex.each{|v| v.edges.each{| e | remove_record_from_hash e} } execute{ create_command[] } end |
#update_or_create_records(o_class, set: {}, where: {}, **args, &b) ⇒ Object
Creating a new Database-Entry (where is omitted)
Or updating the Database-Entry (if present)
The optional Block should provide a hash with attributes (properties). These are used if a new dataset is created.
Based on the query specified in :where records are updated according to :set
Returns an Array of updated documents
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/class_utils.rb', line 124 def update_or_create_records o_class, set: {}, where: {}, **args, &b logger.progname = 'ClassUtils#UpdateOrCreateRecords' if where.blank? [create_record(o_class, attributes: set)] else set.extract!(where.keys) if where.is_a?(Hash) # removes any keys from where in set possible_records = get_records from: classname(o_class), where: where, **args if possible_records.empty? if block_given? more_where = yield # do Preparations prior to the creation of the dataset # if the block returns a Hash, it is merged into the insert_query. where.merge! more_where if more_where.is_a?(Hash) end [create_record(o_class, attributes: set.merge(where))] else possible_records.map{|doc| doc.update(set: set)} unless set.empty? end end end |