active-orient 0.6 → 0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gemfile +4 -10
  4. data/Guardfile +4 -12
  5. data/README.md +198 -261
  6. data/VERSION +1 -1
  7. data/active-orient-0.4.gem +0 -0
  8. data/active-orient-0.41.gem +0 -0
  9. data/active-orient.gemspec +5 -6
  10. data/config/boot.rb +0 -84
  11. data/config/connect.yml +4 -8
  12. data/examples/books.rb +39 -86
  13. data/examples/streets.rb +84 -85
  14. data/lib/active-orient.rb +9 -57
  15. data/lib/base.rb +145 -172
  16. data/lib/base_properties.rb +44 -40
  17. data/lib/model.rb +468 -0
  18. data/lib/orient.rb +60 -114
  19. data/lib/query.rb +73 -71
  20. data/lib/rest.rb +1059 -0
  21. data/lib/support.rb +319 -386
  22. data/test.rb +4 -0
  23. data/usecase.md +91 -0
  24. metadata +20 -65
  25. data/bin/active-orient-console +0 -38
  26. data/config/config.yml +0 -10
  27. data/create_project +0 -19
  28. data/examples/test_commands.rb +0 -92
  29. data/examples/test_commands_2.rb +0 -54
  30. data/examples/test_commands_3.rb +0 -48
  31. data/examples/test_commands_4.rb +0 -28
  32. data/examples/time_graph.md +0 -162
  33. data/gratefuldeadconcerts.md +0 -94
  34. data/lib/class_utils.rb +0 -300
  35. data/lib/database_utils.rb +0 -106
  36. data/lib/init.rb +0 -45
  37. data/lib/java-api.rb +0 -437
  38. data/lib/jdbc.rb +0 -211
  39. data/lib/model/edge.rb +0 -55
  40. data/lib/model/model.rb +0 -91
  41. data/lib/model/the_class.rb +0 -500
  42. data/lib/model/the_record.rb +0 -322
  43. data/lib/model/vertex.rb +0 -136
  44. data/lib/orientdb_private.rb +0 -48
  45. data/lib/other.rb +0 -330
  46. data/lib/rest/change.rb +0 -137
  47. data/lib/rest/create.rb +0 -488
  48. data/lib/rest/delete.rb +0 -134
  49. data/lib/rest/operations.rb +0 -160
  50. data/lib/rest/read.rb +0 -150
  51. data/lib/rest/rest.rb +0 -112
  52. data/lib/rest_disabled.rb +0 -24
  53. data/linkmap.md +0 -75
  54. data/namespace.md +0 -111
  55. data/old_lib_functions/two_general_class.rb +0 -139
  56. data/rails.md +0 -125
  57. data/rails/activeorient.rb +0 -53
  58. data/rails/config.yml +0 -10
  59. data/rails/connect.yml +0 -17
  60. data/usecase_oo.md +0 -61
@@ -1,134 +0,0 @@
1
- module RestDelete
2
-
3
- ######### DATABASE ##########
4
-
5
- =begin
6
- Deletes the database and returns true on success
7
- After the removal of the database, the working-database might be empty
8
- =end
9
-
10
- def delete_database database:
11
- logger.progname = 'RestDelete#DeleteDatabase'
12
- old_ds = ActiveOrient.database
13
- change_database database
14
- begin
15
- response = @res["/database/#{ActiveOrient.database}"].delete
16
- if database == old_ds
17
- change_database 'temp'
18
- logger.info{"Working database deleted, switched to temp"}
19
- else
20
- change_database old_ds
21
- logger.info{"Database #{database} deleted, working database is still #{ActiveOrient.database}"}
22
- end
23
- rescue RestClient::InternalServerError => e
24
- change_database old_ds
25
- logger.info{"Database #{database} NOT deleted, working database is still #{ActiveOrient.database}"}
26
- end
27
- !response.nil? && response.code == 204 ? true : false
28
- end
29
-
30
- ######### CLASS ##########
31
-
32
- =begin
33
- Deletes the specified class and returns true on success
34
- todo: remove all instances of the class
35
- =end
36
-
37
- def delete_class o_class
38
- cl = classname(o_class)
39
- return if cl.nil?
40
- logger.progname = 'RestDelete#DeleteClass'
41
-
42
- begin
43
- ## to do: if cl contains special characters, enclose with backticks
44
- response = @res["/class/#{ActiveOrient.database}/#{cl}"].delete
45
- if response.code == 204
46
- logger.info{"Class #{cl} deleted."}
47
- ActiveOrient.database_classes.delete(cl)
48
- end
49
- rescue RestClient::InternalServerError => e
50
- sentence= JSON.parse( e.response)['errors'].last['content']
51
- if database_classes(requery: true).include?(cl)
52
- logger.error{"Class #{cl} still present."}
53
- logger.error{ sentence }
54
- false
55
- else
56
- logger.error{e.inspect}
57
- true
58
- end
59
- rescue Exception => e
60
- logger.error{e.message}
61
- logger.error{e.inspect}
62
- end
63
- end
64
-
65
- ############## RECORD #############
66
-
67
- =begin
68
- Deletes a single Record when providing a single rid-link (#00:00) or a record
69
- Deletes multible Records when providing a list of rid-links or a record
70
- Todo: implement delete_edges after querying the database in one statement
71
-
72
- Example:
73
- record = Vertex.create_document attributes: { something: 'something' }
74
- Vertex.delete_record record
75
-
76
- records= (1..100).map{|x| Vertex.create_document attributes: { something: x } }
77
- Vertex.delete_record *records
78
-
79
- delete_records provides the removal of datasets after quering the database.
80
- =end
81
-
82
- def delete_record *rid
83
- logger.progname = "ActiveOrient::RestDelete#DeleteRecord"
84
- ridvec= rid.map( &:to_orient).flatten
85
- unless ridvec.empty?
86
- ridvec.map do |rid|
87
- begin
88
- ActiveOrient::Base.remove_rid( ActiveOrient::Base.get_rid(rid) )
89
- @res["/document/#{ActiveOrient.database}/#{rid[1..-1]}"].delete
90
- rescue RestClient::InternalServerError => e
91
- logger.error{"Record #{rid} NOT deleted"}
92
- rescue RestClient::ResourceNotFound
93
- logger.error{"Record #{rid} does not exist in the database"}
94
- else
95
- logger.info{"Record #{rid} deleted"}
96
- end
97
- end
98
- else
99
- logger.info{"No record deleted."}
100
- return nil
101
- end
102
- end
103
- alias delete_document delete_record
104
-
105
- =begin
106
- Deletes records. They are defined by a query. All records which match the attributes are deleted.
107
- An Array with freed index-values is returned
108
- =end
109
-
110
- def delete_records o_class, where: {}
111
- logger.progname = 'RestDelete#DeleteRecords'
112
- records_to_delete = get_records(from: o_class, where: where)
113
- if records_to_delete.empty?
114
- logger.info{"No record found"}
115
- else
116
- delete_record records_to_delete
117
- end
118
- end
119
- alias delete_documents delete_records
120
-
121
- ################ PROPERTY #############
122
-
123
- def delete_property o_class, field
124
- logger.progname = 'RestDelete#DeleteProperty'
125
- begin
126
- response = @res["/property/#{ActiveOrient.database}/#{classname(o_class)}/#{field}"].delete
127
- true if response.code == 204
128
- rescue RestClient::InternalServerError => e
129
- logger.error{"Property #{field} in class #{classname(o_class)} NOT deleted" }
130
- false
131
- end
132
- end
133
-
134
- end
@@ -1,160 +0,0 @@
1
- module RestOperations
2
-
3
- # Execute a predefined Function
4
-
5
- # untested
6
- def call_function *args
7
- # puts "uri:#{function_uri { args.join('/') } }"
8
- begin
9
- term = args.join('/')
10
- @res["/function/#{@database}/#{term}"].post ''
11
- rescue RestClient::InternalServerError => e
12
- puts JSON.parse(e.http_body)
13
- end
14
- end
15
-
16
- # Used to count the Records in relation of the arguments
17
- #
18
- # Overwritten by Model#Count
19
- def count **args
20
- logger.progname = 'RestOperations#CountRecords'
21
- query = OrientSupport::OrientQuery.new args
22
- query.projection << 'COUNT (*)'
23
- result = get_records raw: true, query: query
24
- result.first['COUNT'] rescue 0 # return_value
25
- end
26
-
27
- ## historic method
28
- # def manipulate_relation record, method, array, items # :nodoc: #
29
- # execute_array = Array.new
30
- # method = method.to_s.upcase
31
- #
32
- # add_2_execute_array = -> (it) do
33
- # command = "UPDATE ##{record.rid} #{method} #{array} = #{it.to_or } " #updating}"
34
- # command.gsub!(/\"/,"") if it.is_a? Array
35
- # puts "COMMAND:: #{command}"
36
- # execute_array << {type: "cmd", language: "sql", command: command}
37
- # end
38
- #
39
- # items.to_a.each{|x| add_2_execute_array[x] }
40
- ## puts "******************"
41
- ## puts record.inspect
42
- ## puts "-----"
43
- ## puts execute_array.join('\n')
44
- # r= execute{ execute_array }
45
- # puts record.inspect
46
- # puts r.inspect
47
- ## puts "******************"
48
- # if r.present?
49
- # case method
50
- # when 'ADD'
51
- # items.each{|x| record.attributes[array] << x}
52
- # when 'REMOVE'
53
- # items.map{|x| record.attributes[array].delete x}
54
- # else
55
- # end
56
- # record.increment_version
57
- # end
58
- # end
59
- =begin
60
- Executes a list of commands and returns the result-array (if present)
61
-
62
- (External use)
63
-
64
- If soley a string is provided in the block, a minimal database-console is realized.
65
- i.e.
66
-
67
- ORD.execute{ 'select from #25:0' }
68
-
69
- (Internal Use)
70
-
71
- Structure of the provided block:
72
- [{type: "cmd", language: "sql", command: "create class Person extends V"}, (...)]
73
- --
74
- It was first used by ActiveOrient::Query.execute_queries
75
- Later I (topofocus) discovered that some Queries are not interpretated correctly by #GetRecords but are submitted without Error via batch-processing.
76
- For instance, this valid query
77
- select expand(first_list[5].second_list[9]) from base where label = 9
78
- can only be submitted via batch
79
- ++
80
- Parameters:
81
-
82
- transaction: true|false Perform the batch as transaction
83
- tolerate_error_code: /a regular expression/
84
- Statements to execute are provided via block
85
- These statements are translated to json and transmitted to the database. Example:
86
-
87
- { type: "cmd",
88
- language: 'sql',
89
- command: "CREATE EDGE #{classname(o_class)} FROM #{from.to_orient} TO #{to.to_orient}"}
90
-
91
- Multible statements are transmitted at once if the Block provides an Array of statements.
92
-
93
-
94
- =end
95
-
96
- def execute transaction: true, tolerated_error_code: nil, process_error: true, raw: nil # Set up for classes
97
- batch = {transaction: transaction, operations: yield}
98
- logger.progname= "Execute"
99
- # puts "batch: #{batch[:operations]}"
100
- unless batch[:operations].blank?
101
- batch[:operations] = {:type=>"cmd", :language=>"sql", :command=> batch[:operations]} if batch[:operations].is_a? String
102
- batch[:operations] = [batch[:operations]] unless batch[:operations].is_a? Array
103
- batch[:operations].compact!
104
- # transaction is true only for multible statements
105
- # batch[:transaction] = transaction & batch[:operations].size >1
106
- begin
107
- logger.debug{ batch[:operations].map{|y|y[:command]}.join("; ") }
108
- response = @res["/batch/#{ActiveOrient.database}"].post batch.to_json
109
- rescue RestClient::BadRequest => f
110
- # extract the misspelled query in logfile and abort
111
- sentence= JSON.parse( f.response)['errors'].last['content']
112
- logger.fatal{ " BadRequest --> #{sentence.split("\n")[1]} " }
113
- puts "Query not recognized"
114
- puts sentence
115
- raise
116
- rescue RestClient::InternalServerError => e
117
- logger.progname = 'RestOperations#Execute'
118
- sentence= JSON.parse( e.response)['errors'].last['content']
119
- if tolerated_error_code.present? && e.response =~ tolerated_error_code
120
- logger.info{ "tolerated_error::#{e.message}"}
121
- else
122
- if process_error
123
- # puts batch.to_json
124
- # logger.error{e.response}
125
- logger.error{sentence}
126
- logger.error{ e.backtrace.map {|l| " #{l}\n"}.join }
127
- # logger.error{e.message.to_s}
128
- else
129
- raise
130
- end
131
- end
132
- rescue Errno::EADDRNOTAVAIL => e
133
- sleep(2)
134
- retry
135
- end
136
- if response.present? && response.code == 200
137
- if response.body['result'].present?
138
- result=JSON.parse(response.body)['result']
139
- return result if raw.present?
140
- result.map do |x|
141
- if x.is_a? Hash
142
- if x.has_key?('@class')
143
- ActiveOrient::Model.orientdb_class(name: x['@class'], superclass: :find_ME ).new x
144
- elsif x.has_key?('value')
145
- x['value']
146
- else # create a dummy class and fill with attributes from result-set
147
- ActiveOrient::Model.orientdb_class(name: 'query' ).new x
148
- end
149
- end
150
- end.compact # return_value
151
- else
152
- response.body
153
- end
154
- else
155
- nil
156
- end
157
- end
158
- end
159
-
160
- end
@@ -1,150 +0,0 @@
1
- module RestRead
2
-
3
- ############# DATABASE #############
4
-
5
- # Returns an Array with available Database-Names as Elements
6
-
7
- def get_databases
8
- JSON.parse(@res["/listDatabases"].get.body)['databases']
9
- end
10
-
11
- =begin
12
- Returns an Array with (unmodified) Class-attribute-hash-Elements
13
-
14
- get_classes 'name', 'superClass' returns
15
- [ {"name"=>"E", "superClass"=>""},
16
- {"name"=>"OFunction", "superClass"=>""},
17
- {"name"=>"ORole", "superClass"=>"OIdentity"}
18
- (...) ]
19
- =end
20
-
21
- def get_classes *attributes
22
- begin
23
- response = @res["/database/#{ActiveOrient.database}"].get
24
- if response.code == 200
25
- classes = JSON.parse(response.body)['classes']
26
- unless attributes.empty?
27
- classes.map{|y| y.select{|v,_| attributes.include?(v)}}
28
- else
29
- classes
30
- end
31
- else
32
- []
33
- end
34
- rescue Exception => e
35
- logger.progname = 'RestRead#GetClasses'
36
- logger.error{e.message}
37
- end
38
- end
39
-
40
-
41
- ############### CLASS ################
42
-
43
- # Return a JSON of the property of a class
44
-
45
- def get_class_properties o_class
46
- JSON.parse(@res["/class/#{ActiveOrient.database}/#{classname(o_class)}"].get)
47
- rescue => e
48
- logger.error e.message
49
- nil
50
- end
51
-
52
-
53
- def print_class_properties o_class
54
- puts "Detected Properties for class #{classname(o_class)}"
55
- rp = get_class_properties o_class
56
- n = rp['name']
57
- if rp['properties'].nil?
58
- puts "No property available"
59
- else
60
- puts rp['properties'].map{|x| "\t"+[n+'.'+x['name'], x['type'],x['linkedClass']].compact.join("\t-> ")}.join("\n")
61
- end
62
- rescue NoMethodError
63
- puts "Class #{o_class} not present in database"
64
- end
65
-
66
- ############## OBJECT #################
67
-
68
- =begin
69
- Retrieves a Record from the Database as ActiveOrient::Model::{class}
70
- The argument can either be a rid (#[x}:{y}) or a link({x}:{y})
71
- If no Record is found, nil is returned
72
- =end
73
-
74
- def get_record rid
75
- begin
76
- logger.progname = 'RestRead#GetRecord'
77
- if rid.rid?
78
- rid = rid[1..rid.length] if rid[0]=='#'
79
- response = @res["/document/#{ActiveOrient.database}/#{rid}"].get
80
- raw_data = JSON.parse(response.body) #.merge( "#no_links" => "#no_links" )
81
- ActiveOrient::Model.orientdb_class(name: raw_data['@class'], superclass: :find_ME).new raw_data
82
- else
83
- logger.error { "Wrong parameter #{rid.inspect}. " }
84
- nil
85
- end
86
- rescue RestClient::InternalServerError => e
87
- if e.http_body.split(':').last =~ /was not found|does not exist in database/
88
- nil
89
- else
90
- logger.error { "Something went wrong" }
91
- logger.error { e.http_body.inspect }
92
- raise
93
- end
94
- rescue RestClient::ResourceNotFound => e
95
- logger.error { "Not data found" }
96
- logger.error { e.message }
97
- rescue Exception => e
98
- logger.error { "Something went wrong" }
99
- logger.error { "RID: #{rid} - #{e.message}" }
100
- end
101
- end
102
- alias get_document get_record
103
-
104
- =begin
105
- Retrieves Records from a query
106
- If raw is specified, the JSON-Array is returned, e.g.
107
- {"@type"=>"d", "@rid"=>"#15:1", "@version"=>1, "@class"=>"DocumebntKlasse10", "con_id"=>343, "symbol"=>"EWTZ"}
108
- Otherwise a ActiveModel-Instance of o_class is created and returned
109
- =end
110
-
111
- def get_records raw: false, query: nil, **args
112
- query = OrientSupport::OrientQuery.new(args) if query.nil?
113
- begin
114
- logger.progname = 'RestRead#GetRecords'
115
- url = "/query/#{ActiveOrient.database}/sql/" + query.compose(destination: :rest) + "/#{query.get_limit}"
116
- # puts "REST_READ#GET_RECORDS.URL"
117
- # puts query.compose( destination: :rest).to_s
118
- # puts url.to_s
119
- response = @res[URI.encode(url)].get
120
- JSON.parse(response.body)['result'].map do |record|
121
- if raw
122
- record
123
- # query returns an anonymus class: Use the provided Block or the Dummy-Model MyQuery
124
- elsif record['@class'].blank?
125
- # puts "RECORD:\n"+record.inspect
126
- block_given? ? yield.new(record) : ActiveOrient::Model.orientdb_class(name: 'query' ).new( record )
127
- else
128
- ActiveOrient::Model.orientdb_class(name: record['@class'], superclass: :find_ME).new record
129
- end
130
- end
131
- # returns the JSON-Object
132
-
133
-
134
- rescue RestClient::InternalServerError => e
135
- response = JSON.parse(e.response)['errors'].pop
136
- logger.error{ "Interbak Server ERROR" }
137
- logger.error{response['content'].split(':').last}
138
- rescue URI::InvalidURIError => e
139
- logger.error{"Invalid URI detected"}
140
- logger.error query.to_s
141
- logger.info{"Trying batch processing"}
142
- sql_cmd = -> (command){{type: "cmd", language: "sql", command: command}}
143
- response = execute{[sql_cmd[query.to_s]]}
144
- logger.info{"Success: to avoid this delay use ActiveOrient::Model#query_database instead"}
145
- response
146
- end
147
- end
148
- alias get_documents get_records
149
-
150
- end
@@ -1,112 +0,0 @@
1
- require_relative "read.rb" # manage get
2
- require_relative "create.rb" # manage create
3
- require_relative "change.rb" # manage update
4
- require_relative "operations.rb" # manage count, functions and execute
5
- require_relative "delete.rb" # manage delete
6
- require 'cgi'
7
- require 'rest-client'
8
-
9
- module ActiveOrient
10
-
11
- =begin
12
- OrientDB performs queries to a OrientDB-Database
13
- The communication is based on the ActiveOrient-API.
14
- The OrientDB-Server is specified in config/connect.yml
15
- A Sample:
16
- :orientdb:
17
- :server: localhost
18
- :port: 2480
19
- :database: working-database
20
- :admin:
21
- :user: admin-user
22
- :pass: admin-password
23
- =end
24
-
25
- class OrientDB
26
- include OrientSupport::Support
27
- include OrientDbPrivate
28
- include DatabaseUtils
29
- include ClassUtils
30
- include RestRead
31
- include RestCreate
32
- include RestChange
33
- include RestOperations
34
- include RestDelete
35
-
36
- mattr_accessor :logger # borrowed from active_support
37
- attr_reader :database # Used to read the working database
38
-
39
- #### INITIALIZATION ####
40
-
41
- =begin
42
- Contructor: OrientDB is conventionally initialized.
43
- Thus several instances pointing to the same or different databases can coexist
44
-
45
- A simple
46
- xyz = ActiveOrient::OrientDB.new
47
- uses the database specified in the yaml-file »config/connect.yml« and connects
48
- xyz = ActiveOrient::OrientDB.new database: my_fency_database
49
- accesses the database »my_fency_database«. The database is created if its not existing.
50
-
51
- *USECASE*
52
- xyz = ActiveOrient::Model.orientdb = ActiveOrient::OrientDB.new
53
- initialises the Database-Connection and publishes the Instance to any ActiveOrient::Model-Object
54
- =end
55
-
56
- def initialize database: nil, connect: true, preallocate: true, model_dir: nil
57
- self.logger = Logger.new('/dev/stdout') unless logger.present?
58
- # self.default_server = {
59
- # :server => 'localhost',
60
- # :port => 2480,
61
- # :protocol => 'http',
62
- # :user => 'root',
63
- # :password => 'root',
64
- # :database => 'temp'
65
- # }.merge default_server.presence || {}
66
- # @res = get_resource
67
- ActiveOrient.database = database if database.present?
68
- @res = get_resource
69
- connect() if connect
70
- database_classes # initialize @classes-array
71
- ActiveOrient::Model.orientdb = self
72
- ActiveOrient::Model.db = self
73
- ActiveOrient::Model.keep_models_without_file ||= nil
74
- preallocate_classes(model_dir) if preallocate
75
-
76
- end
77
-
78
- def get_resource
79
- login = [ActiveOrient.default_server[:user].to_s , ActiveOrient.default_server[:password].to_s]
80
- server_adress = "http://#{ActiveOrient.default_server[:server]}:#{ActiveOrient.default_server[:port]}"
81
- RestClient::Resource.new(server_adress, *login)
82
- end
83
-
84
- # Used to connect to the database
85
-
86
- def connect
87
- first_tentative = true
88
- begin
89
- database = ActiveOrient.database
90
- logger.progname = 'OrientDB#Connect'
91
- r = @res["/connect/#{database}"].get
92
- if r.code == 204
93
- logger.info{"Connected to database #{database}"}
94
- true
95
- else
96
- logger.error{"Connection to database #{database} could NOT be established"}
97
- nil
98
- end
99
- rescue RestClient::Unauthorized => e
100
- if first_tentative
101
- logger.info{"Database #{database} NOT present --> creating"}
102
- first_tentative = false
103
- create_database database: database
104
- retry
105
- else
106
- Kernel.exit
107
- end
108
- end
109
- end
110
-
111
- end
112
- end