Module: ModelClass
- Included in:
- ActiveOrient::Model
- Defined in:
- lib/model/the_class.rb
Instance Method Summary collapse
- #add_edge_link(name:, direction: :out, edge:) ⇒ Object
-
#all ⇒ Object
get all the elements of the class.
- #alter_property(property:, attribute: "DEFAULT", alteration:) ⇒ Object
-
#classname ⇒ Object
GET ###############.
-
#count(**args) ⇒ Object
Used to count of the elements in the class.
-
#create(**attributes) ⇒ Object
Universal method to create a new record.
-
#create_index(name, **attributes) ⇒ Object
Add an Index.
-
#create_properties(argument_hash, &b) ⇒ Object
Create more Properties in the Schema of the Class.
-
#create_property(field, **keyword_arguments, &b) ⇒ Object
Create a Property in the Schema of the Class :call-seq: Model.create_property(field (required), type:‘string’, linked_class: nil, index: nil) do index end.
-
#custom_where(search_string) ⇒ Object
Performs a query on the Class and returns an Array of ActiveOrient:Model-Records.
-
#delete_property(field) ⇒ Object
Delete a property from the class.
-
#delete_record(*rid) ⇒ Object
(also: #delete_document)
Delete a record.
-
#delete_records(where: {}) ⇒ Object
(also: #delete_documents)
Delete a record from the class.
-
#first(where: {}) ⇒ Object
get the first element of the class.
-
#get(rid) ⇒ Object
get elements by rid.
-
#get_model_class(name) ⇒ Object
Retrieves the preallocated class derived from ActiveOrient::Model.
-
#get_properties ⇒ Object
(also: #get_class_properties)
Get the properties of the class.
-
#get_records(**args) ⇒ Object
(also: #get_documents)
Parameter projection: »select« is a method of enumeration, we use »projection:« to specify anything between »select« and »from« in the query-string.
-
#last(where: {}) ⇒ Object
get the last element of the class.
-
#match(where: {}) ⇒ Object
Performs a Match-Query.
-
#naming_convention(name = nil) ⇒ Object
NamingConvention provides a translation from database-names to class-names.
-
#orientdb_class(name:, superclass: nil) ⇒ Object
orientdb_class is used to create or refer a ActiveOrient:Model:class by providing its name.
-
#print_class_properties ⇒ Object
Print the properties of the class.
-
#query_database(query, set_from: true) ⇒ Object
QueryDatabase sends the Query, direct to the database.
-
#remove(attribute, where: {}) ⇒ Object
removes a property from the collection (where given) or the entire class.
-
#require_model_file(dir = nil) ⇒ Object
requires the file specified in the model-dir.
-
#update_all(where: {}, set: {}, **arg) ⇒ Object
Sets a value to certain attributes, overwrites existing entries, creates new attributes if nessesary.
-
#update_or_create_records(set: {}, where: {}, **args, &b) ⇒ Object
(also: #update_or_create_documents)
Create a new Instance of the Class with the applied attributes if does not exists, otherwise update it.
-
#upsert(set: {}, where: {}, &b) ⇒ Object
Creates or updates a record.
- #where(*attributes) ⇒ Object
Instance Method Details
#add_edge_link(name:, direction: :out, edge:) ⇒ Object
483 484 485 486 487 488 |
# File 'lib/model/the_class.rb', line 483 def add_edge_link name:, direction: :out, edge: dir = direction.to_s == "out" ? :out : :in define_method(name.to_sym) do return self["#{dir}_#{edge.classname}"].map{|x| x["in"]} end end |
#all ⇒ Object
get all the elements of the class
270 271 272 |
# File 'lib/model/the_class.rb', line 270 def all db.get_records from: self end |
#alter_property(property:, attribute: "DEFAULT", alteration:) ⇒ Object
494 495 496 |
# File 'lib/model/the_class.rb', line 494 def alter_property property:, attribute: "DEFAULT", alteration: orientdb.alter_property self, property: property, attribute: attribute, alteration: alteration end |
#classname ⇒ Object
GET ###############
258 259 260 |
# File 'lib/model/the_class.rb', line 258 def classname # :nodoc: # ref_name end |
#count(**args) ⇒ Object
Used to count of the elements in the class
287 288 289 |
# File 'lib/model/the_class.rb', line 287 def count **args orientdb.count from: self, **args end |
#create(**attributes) ⇒ Object
Universal method to create a new record. It’s obverloaded to create specific kinds, eg. edges
Example:
ORD.create_class :test
Test.create string_attribute: 'a string', symbol_attribute: :a_symbol, array_attribute: [34,45,67]
Test.create link_attribute: Test.create( :a_new_attribute => 'new' )
175 176 177 178 |
# File 'lib/model/the_class.rb', line 175 def create **attributes attributes.merge :created_at => Time.new db.create_record self, attributes: attributes end |
#create_index(name, **attributes) ⇒ Object
Add an Index
252 253 254 |
# File 'lib/model/the_class.rb', line 252 def create_index name, **attributes orientdb.create_index self, name: name, **attributes end |
#create_properties(argument_hash, &b) ⇒ Object
Create more Properties in the Schema of the Class
246 247 248 |
# File 'lib/model/the_class.rb', line 246 def create_properties argument_hash, &b orientdb.create_properties self, argument_hash, &b end |
#create_property(field, **keyword_arguments, &b) ⇒ Object
Create a Property in the Schema of the Class
:call-seq: Model.create_property(field (required), type:'string', linked_class: nil, index: nil) do
index
end
Examples:
create_property :customer_id, type: integer, index: :unique
create_property :name, type: :string, index: :not_unique
create_property :in, type: :link, linked_class: :V (used by edges)
240 241 242 |
# File 'lib/model/the_class.rb', line 240 def create_property field, **keyword_arguments, &b orientdb.create_property self, field, **keyword_arguments, &b end |
#custom_where(search_string) ⇒ Object
Performs a query on the Class and returns an Array of ActiveOrient:Model-Records.
Example:
Log.where priority: 'high'
--> submited database-request: query/hc_database/sql/select from Log where priority = 'high'/-1
=> [ #<Log:0x0000000480f7d8 @metadata={ ... }, ...
360 361 362 363 364 |
# File 'lib/model/the_class.rb', line 360 def custom_where search_string q = OrientSupport::OrientQuery.new from: self, where: search_string #puts q.compose query_database q end |
#delete_property(field) ⇒ Object
Delete a property from the class
434 435 436 |
# File 'lib/model/the_class.rb', line 434 def delete_property field orientdb.delete_property self, field end |
#delete_record(*rid) ⇒ Object Also known as: delete_document
Delete a record
440 441 442 |
# File 'lib/model/the_class.rb', line 440 def delete_record *rid db.delete_record rid end |
#delete_records(where: {}) ⇒ Object Also known as: delete_documents
Delete a record from the class
447 448 449 |
# File 'lib/model/the_class.rb', line 447 def delete_records where: {} orientdb.delete_records self, where: where end |
#first(where: {}) ⇒ Object
get the first element of the class
276 277 278 |
# File 'lib/model/the_class.rb', line 276 def first where: {} db.get_records(from: self, where: where, limit: 1).pop end |
#get(rid) ⇒ Object
get elements by rid
264 265 266 |
# File 'lib/model/the_class.rb', line 264 def get rid db.get_record rid end |
#get_model_class(name) ⇒ Object
Retrieves the preallocated class derived from ActiveOrient::Model
Only classes noted in the @classes-Array of orientdb are fetched.
112 113 114 115 116 117 118 |
# File 'lib/model/the_class.rb', line 112 def get_model_class name if orientdb.database_classes.include?(name) orientdb_class name: name, superclass: :find_ME else nil end end |
#get_properties ⇒ Object Also known as: get_class_properties
Get the properties of the class
293 294 295 296 |
# File 'lib/model/the_class.rb', line 293 def get_properties object = orientdb.get_class_properties self HashWithIndifferentAccess.new :properties => object['properties'], :indexes => object['indexes'] end |
#get_records(**args) ⇒ Object Also known as: get_documents
Parameter projection:
:some_name –> the result is mapped to ModelInstance.some_name
Parameter Order
Sorts the result-set. If new properties are introduced via select:, distinct: etc. Sorting takes place on these properties
order: :property {property: asc, property: desc}[property, property, .. ](orderdirection is 'asc')
Further supported Parameter:
group_by
skip
limit
unwind
see orientdb- documentation (https://orientdb.com/docs/last/SQL-Query.html)
Parameter query:
Instead of providing the parameter, the OrientSupport::OrientQuery can build and tested before the method-call. The OrientQuery-Object can be provided with the query-parameter. I.e.
q = OrientSupport::OrientQuery.new
ORD.create_class :test_model
q.from TestModel
q.where {name: 'Thomas'}
count = TestModel.count query: q
q.limit 10
0.step(count,10) do |x|
q.skip = x
puts TestModel.get_documents(query: q).map{|x| x.adress }.join('\t')
end
prints a Table with 10 columns.
346 347 348 |
# File 'lib/model/the_class.rb', line 346 def get_records **args db.get_records(from: self, **args){self} end |
#last(where: {}) ⇒ Object
get the last element of the class
282 283 284 |
# File 'lib/model/the_class.rb', line 282 def last where: {} db.get_records(from: self, where: where, order: {"@rid" => 'desc'}, limit: 1).pop end |
#match(where: {}) ⇒ Object
Performs a Match-Query
The Query starts at the given ActiveOrient::Model-Class. The where-cause narrows the sample to certain records. In the simplest version this can be returnd:
Industry.match where:{ name: "Communications" }
=> #<ActiveOrient::Model::Query:0x00000004309608 @metadata={"type"=>"d", "class"=>nil, "version"=>0, "fieldTypes"=>"Industries=x"}, @attributes={"Industries"=>"#21:1", (...)}>
The attributes are the return-Values of the Match-Query. Unless otherwise noted, the pluralized Model-Classname is used as attribute in the result-set.
I.match( where: { name: 'Communications' }).first.Industries
is the same then
Industry.where name: "Communications"
The Match-Query uses this result-set as start for subsequent queries on connected records. These connections are defined in the Block
var = Industry.match do | query |
query.connect :in, count: 2, as: 'Subcategories'
puts query.to_s # print the query send to the database
query # important: block has to return the query
end
=> MATCH {class: Industry, as: Industries} <-- {} <-- { as: Subcategories } RETURN Industries, Subcategories
The result-set has two attributes: Industries and Subcategories, pointing to the filtered datasets.
By using subsequent »connect« and »statement« method-calls even complex Match-Queries can be clearly constructed.
403 404 405 406 407 408 409 410 411 412 413 |
# File 'lib/model/the_class.rb', line 403 def match where: {} query= OrientSupport::OrientQuery.new kind: :match, start:{ class: self.classname } query.match_statements[0].where = where unless where.empty? if block_given? query_database yield(query), set_from: false else logger.progname = 'ActiveOrient::Model#Match' logger.error{ "Query-Details have to be specified in a Block" } end end |
#naming_convention(name = nil) ⇒ Object
NamingConvention provides a translation from database-names to class-names.
Should provide
to_s.capitalize_first_letter
as minimum. Can be overwritten to provide different conventions for different classes, eg. Vertexes or edges.
To overwrite use
class Model < ActiveOrient::Model[:: ...]
def self.naming_convention
( conversion code )
end
end
24 25 26 |
# File 'lib/model/the_class.rb', line 24 def naming_convention name=nil # :nodoc: name.present? ? name.to_s.camelize : ref_name.camelize end |
#orientdb_class(name:, superclass: nil) ⇒ Object
orientdb_class is used to create or refer a ActiveOrient:Model:class by providing its name
Parameter: name: string or symbol
Parameter: superclass: If class, then this is used unmodified
If string or symbol, its used to reference an existing class if :find_ME, its derived from the classes-hash
Attention: If a class is created by orientdb_class, its only allocated in ruby-space.
The class is thus not present in the classes-array, which reflects the database-classes. If a class depending on a superclass is to be created, the superclass is derived from the classes-array. In such a case, the allocation only works, if the class itself is used as parameter “superclass” i.e. ActiveOrient::Model.orientdb_class name: ‘hurra’ AvtiveOrient::Model.orientdb_class name: ‘hip_hip’ , superclass: Hurra
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 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 |
# File 'lib/model/the_class.rb', line 45 def orientdb_class name:, superclass: nil # :nodoc: # public method: autoload_class logger.progname = "ModelClass#OrientDBClass" # @s-class is a cash for actual String -> Class relations self.allocated_classes = HashWithIndifferentAccess.new( V: V, E: E) unless allocated_classes.present? #update_my_array = ->(s) { self.allocated_classes[s.ref_name] = s unless allocated_classes[s.ref_name].present? } update_my_array = ->(s) do if allocated_classes[s.ref_name].present? # puts "found ref_name: #{allocated_classes[s.ref_name]}" else self.allocated_classes[s.ref_name] = s end end get_class = ->(n) { allocated_classes[n] } extract_namespace = -> (n) do if get_class[n].present? separated_class_parts = get_class[n].to_s.split(':') separated_class_parts.size >1 ? separated_class_parts.first.constantize : namespace else namespace end end ref_name = name.to_s klass = if superclass.present? # superclass is parameter, use if class, otherwise transfer to class s= if superclass.is_a? Class extract_namespace[name].send( :const_get, superclass.to_s ) else superclass = orientdb.get_db_superclass( ref_name ) if superclass == :find_ME if superclass.present? extract_namespace[name].send( :const_get, get_class[superclass].to_s ) else self end end Class.new(s) else Class.new(self) end # namespace is defined in config/boot this_namespace = extract_namespace[ref_name] name = klass.naming_convention ref_name # if this_namespace.send :const_defined?, name retrieved_class = this_namespace.send :const_get, name else new_class = this_namespace.send :const_set, name, klass new_class.ref_name = ref_name update_my_array[new_class] # logger.debug{"created:: Class #{new_class} < #{new_class.superclass} "} # logger.debug{"database-table:: #{ref_name} "} new_class # return_value end rescue NameError => e logger.error "ModelClass #{name.inspect} cannot be initialized." logger.error e. logger.error e.backtrace.map {|l| " #{l}\n"}.join nil # return_value #end end |
#print_class_properties ⇒ Object
Print the properties of the class
301 302 303 |
# File 'lib/model/the_class.rb', line 301 def print_class_properties orientdb.print_class_properties self end |
#query_database(query, set_from: true) ⇒ Object
QueryDatabase sends the Query, direct to the database.
The result is not nessessary an Object of self.
However, if the query does not return an array of Active::Model-Objects, then the entries become self
422 423 424 425 426 427 428 |
# File 'lib/model/the_class.rb', line 422 def query_database query, set_from: true query.from self if set_from && query.is_a?(OrientSupport::OrientQuery) && query.from.nil? sql_cmd = -> (command) {{ type: "cmd", language: "sql", command: command }} db.execute do sql_cmd[query.to_s] end end |
#remove(attribute, where: {}) ⇒ Object
removes a property from the collection (where given) or the entire class
223 224 225 |
# File 'lib/model/the_class.rb', line 223 def remove attribute, where:{} db.update_records self, remove: attribute, where: where end |
#require_model_file(dir = nil) ⇒ Object
requires the file specified in the model-dir
In fact, the model-files are loaded instead of required. After recreation of a class (Class.delete_class, ORD.create_class classname) custom methods declared in the model files are present. Required modelfiles are gone, if the class is destroyed, but the interpreter thinks, they have already been required. Rebuilding the class does not reestablish the connection to the required model file.
Actual only a flat directory is supported. However -the Parameter model has the format: [ superclass, class ]. Its possible to extend the method adress a model-tree.
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 |
# File 'lib/model/the_class.rb', line 132 def require_model_file dir=nil logger.progname = 'ModelClass#RequireModelFile' dir = dir.presence || ActiveOrient::Model.model_dir if File.exists?( dir ) model= model.flatten.last if model.is_a?( Array ) filename = dir + "/" + self.to_s.underscore + '.rb' if File.exists?(filename ) if load filename logger.info{ "#{filename} sucessfully loaded" } self #return_value else logger.error{ "#{filename} load error" } nil #return_value end else logger.info{ "model-file not present: #{filename}" } nil #return_value end else logger.info{ "Directory #{ dir } not present " } nil #return_value end rescue TypeError => e puts "TypeError: #{e.message}" puts "Working on #{self.to_s} -> #{self.superclass}" puts "Class_hierarchy: #{orientdb.class_hierarchy.inspect}." print e.backtrace.join("\n") raise # end |
#update_all(where: {}, set: {}, **arg) ⇒ Object
Sets a value to certain attributes, overwrites existing entries, creates new attributes if nessesary
IB::Account.update_all connected: false
IB::Account.update_all where: "account containsText 'F'", set:{ connected: false }
**note: By calling UpdateAll, all records of the Class previously stored in the rid-cache are removed from the cache. Thus autoload gets the updated records.
214 215 216 217 218 219 220 |
# File 'lib/model/the_class.rb', line 214 def update_all where: {} , set: {}, **arg if where.empty? set.merge! arg end db.update_records self, set: set, where: where end |
#update_or_create_records(set: {}, where: {}, **args, &b) ⇒ Object Also known as: update_or_create_documents
Create a new Instance of the Class with the applied attributes if does not exists, otherwise update it. It returns the freshly instantiated Objects
199 200 201 |
# File 'lib/model/the_class.rb', line 199 def update_or_create_records set: {}, where: {}, **args, &b db.update_or_create_records self, set: set, where: where, **args, &b end |
#upsert(set: {}, where: {}, &b) ⇒ Object
Creates or updates a record. Parameter:
set: A hash of attributes to insert or update unconditionally
where: A string or hash as condition which should return just one record.
The where-part should be covered with an unique-index. If :where is omitted, #Upsert becomes #Create, attributes are taken from :set.
returns the affected record
191 192 193 |
# File 'lib/model/the_class.rb', line 191 def upsert set: {}, where: {}, &b db.upsert self, set: set, where: where, &b end |
#where(*attributes) ⇒ Object
365 366 367 368 369 |
# File 'lib/model/the_class.rb', line 365 def where *attributes ## puts "ATTRIBUTES: "+attributes.inspect q = OrientSupport::OrientQuery.new from: self, where: attributes query_database q end |