active-orient 0.6 → 0.42

Sign up to get free protection for your applications and to get access to all the features.
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