arcadedb 0.3.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e052fea79d83b5cd35961dcc01af0ba617e80c3e0c26d058c5b69a3733a8edc
4
- data.tar.gz: 92ef4c2900fee458959b01becf8fc2789fce5e87fb39e1cfc25b0f0df1e08d20
3
+ metadata.gz: 1855060886e9837ef486e44f07155ae99cd242f76aceccb8a7bf4c2ab515eca0
4
+ data.tar.gz: d99f2a402eba561fcf851a3838b3bec7eee58f1a788ab9fc7e2ce1208c33611a
5
5
  SHA512:
6
- metadata.gz: f74869fa3afe8f87250e94358b2b18a1fdcfdfa092ec0ef5a0293f970f1976b755463f070f0224aa276f4df3acd5555500d800b389c8463889347f8ef2d10ee7
7
- data.tar.gz: a16c82bf62d9e30898de4e439a7fca37f470944cb92293fa11e4847146eac3a5c066447c1293d3fc73d1a078b348bdcdac21b44b10308ba9c10f141d793f17e2
6
+ metadata.gz: 78936dfe0069d531c1bcfd6191f0269ed84a44cd8e0321a37ef9d569048ff8a20d38d0a221d0b0b93f3e64f39d61a758d2978545beec86d27baf5836c3cdbf4a
7
+ data.tar.gz: 6ff4e9242c74887935074ed60810b144a08ad2dad7a6d3374bc0216f74873abb6a1b6f66428a2ed6e7fa9f49dec3ee07ebbe5cc64488744829f76eb037db286c
data/CHANGELOG.md CHANGED
@@ -12,4 +12,8 @@ All notable changes to this project will be documented in this file.
12
12
  - Support for embedded Dokuments and Maps
13
13
  - iruby support
14
14
 
15
+ ## 0.4.0 - 2023.10.28
16
+ - completely remove pg-stuff
17
+ - substitute typhoreous with HTTPX
18
+ - include dry::monards to process raw-data
15
19
 
data/Gemfile CHANGED
@@ -5,17 +5,12 @@ source "https://rubygems.org"
5
5
  #git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
6
  gemspec
7
7
  gem 'sdoc'
8
- gem 'dry-configurable'
9
- gem 'pry'
10
- #gem 'sequel'
11
-
12
- #gem 'mini_sql' #, path: '../mini_sql/'
13
8
  group :development, :test do
14
9
  gem "awesome_print"
15
10
  gem 'pastel'
16
11
  gem 'zeitwerk'
17
12
  gem 'terminal-table'
18
- gem 'rubocop'
13
+ # gem 'rubocop'
19
14
  gem "rspec"
20
15
  gem 'rspec-legacy_formatters'
21
16
  gem 'rspec-its'
@@ -26,5 +21,5 @@ group :development, :test do
26
21
  gem 'guard'#, :platforms => :ruby
27
22
  gem 'guard-rspec'
28
23
  gem 'rb-inotify'
29
- gem 'pry'
24
+ # gem 'pry'
30
25
  end
data/Gemfile.lock CHANGED
@@ -1,56 +1,63 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- arcadedb (0.3.2)
4
+ arcadedb (0.4)
5
+ dry-configurable
5
6
  dry-core
7
+ dry-monads
6
8
  dry-schema
7
9
  dry-struct
8
- typhoeus
10
+ httpx
9
11
 
10
12
  GEM
11
13
  remote: https://rubygems.org/
12
14
  specs:
13
15
  ast (2.4.2)
14
16
  awesome_print (1.9.2)
17
+ base64 (0.1.1)
15
18
  coderay (1.1.3)
16
- concurrent-ruby (1.1.10)
19
+ concurrent-ruby (1.2.2)
17
20
  diff-lcs (1.5.0)
18
- dry-configurable (0.15.0)
21
+ dry-configurable (1.1.0)
22
+ dry-core (~> 1.0, < 2)
23
+ zeitwerk (~> 2.6)
24
+ dry-core (1.0.1)
19
25
  concurrent-ruby (~> 1.0)
20
- dry-core (~> 0.6)
21
- dry-container (0.11.0)
22
- concurrent-ruby (~> 1.0)
23
- dry-core (0.7.1)
24
- concurrent-ruby (~> 1.0)
25
- dry-inflector (0.3.0)
26
+ zeitwerk (~> 2.6)
27
+ dry-inflector (1.0.0)
26
28
  dry-initializer (3.1.1)
27
- dry-logic (1.2.0)
29
+ dry-logic (1.5.0)
30
+ concurrent-ruby (~> 1.0)
31
+ dry-core (~> 1.0, < 2)
32
+ zeitwerk (~> 2.6)
33
+ dry-monads (1.6.0)
28
34
  concurrent-ruby (~> 1.0)
29
- dry-core (~> 0.5, >= 0.5)
30
- dry-schema (1.10.6)
35
+ dry-core (~> 1.0, < 2)
36
+ zeitwerk (~> 2.6)
37
+ dry-schema (1.13.3)
31
38
  concurrent-ruby (~> 1.0)
32
- dry-configurable (~> 0.13, >= 0.13.0)
33
- dry-core (~> 0.5, >= 0.5)
39
+ dry-configurable (~> 1.0, >= 1.0.1)
40
+ dry-core (~> 1.0, < 2)
34
41
  dry-initializer (~> 3.0)
35
- dry-logic (~> 1.2)
36
- dry-types (~> 1.5)
37
- dry-struct (1.4.0)
38
- dry-core (~> 0.5, >= 0.5)
39
- dry-types (~> 1.5)
42
+ dry-logic (>= 1.4, < 2)
43
+ dry-types (>= 1.7, < 2)
44
+ zeitwerk (~> 2.6)
45
+ dry-struct (1.6.0)
46
+ dry-core (~> 1.0, < 2)
47
+ dry-types (>= 1.7, < 2)
40
48
  ice_nine (~> 0.11)
41
- dry-types (1.5.1)
49
+ zeitwerk (~> 2.6)
50
+ dry-types (1.7.1)
42
51
  concurrent-ruby (~> 1.0)
43
- dry-container (~> 0.3)
44
- dry-core (~> 0.5, >= 0.5)
45
- dry-inflector (~> 0.1, >= 0.1.2)
46
- dry-logic (~> 1.0, >= 1.0.2)
47
- ethon (0.16.0)
48
- ffi (>= 1.15.0)
49
- ffi (1.15.5)
52
+ dry-core (~> 1.0)
53
+ dry-inflector (~> 1.0)
54
+ dry-logic (~> 1.4)
55
+ zeitwerk (~> 2.6)
56
+ ffi (1.16.3)
50
57
  formatador (1.1.0)
51
58
  given_core (3.8.2)
52
59
  sorcerer (>= 0.3.7)
53
- guard (2.18.0)
60
+ guard (2.18.1)
54
61
  formatador (>= 0.2.4)
55
62
  listen (>= 2.7, < 4.0)
56
63
  lumberjack (>= 1.0.12, < 2.0)
@@ -64,44 +71,54 @@ GEM
64
71
  guard (~> 2.1)
65
72
  guard-compat (~> 1.1)
66
73
  rspec (>= 2.99.0, < 4.0)
74
+ http-2-next (1.0.1)
75
+ httpx (1.0.2)
76
+ http-2-next (>= 1.0.1)
67
77
  ice_nine (0.11.2)
68
- listen (3.7.1)
78
+ json (2.6.3)
79
+ language_server-protocol (3.17.0.3)
80
+ listen (3.8.0)
69
81
  rb-fsevent (~> 0.10, >= 0.10.3)
70
82
  rb-inotify (~> 0.9, >= 0.9.10)
71
- lumberjack (1.2.8)
83
+ lumberjack (1.2.9)
72
84
  method_source (1.0.0)
73
85
  nenv (0.3.0)
74
86
  notiffany (0.1.3)
75
87
  nenv (~> 0.1)
76
88
  shellany (~> 0.0)
77
- parallel (1.22.1)
78
- parser (3.1.2.0)
89
+ parallel (1.23.0)
90
+ parser (3.2.2.4)
79
91
  ast (~> 2.4.1)
92
+ racc
80
93
  pastel (0.8.0)
81
94
  tty-color (~> 0.5)
82
- pry (0.14.1)
95
+ pry (0.14.2)
83
96
  coderay (~> 1.1)
84
97
  method_source (~> 1.0)
98
+ psych (5.1.1.1)
99
+ stringio
100
+ racc (1.7.1)
85
101
  rainbow (3.1.1)
86
102
  rake (13.0.6)
87
- rb-fsevent (0.11.1)
103
+ rb-fsevent (0.11.2)
88
104
  rb-inotify (0.10.1)
89
105
  ffi (~> 1.0)
90
- rdoc (6.3.3)
91
- regexp_parser (2.4.0)
92
- rexml (3.2.5)
93
- rspec (3.11.0)
94
- rspec-core (~> 3.11.0)
95
- rspec-expectations (~> 3.11.0)
96
- rspec-mocks (~> 3.11.0)
97
- rspec-collection_matchers (1.2.0)
106
+ rdoc (6.5.0)
107
+ psych (>= 4.0.0)
108
+ regexp_parser (2.8.2)
109
+ rexml (3.2.6)
110
+ rspec (3.12.0)
111
+ rspec-core (~> 3.12.0)
112
+ rspec-expectations (~> 3.12.0)
113
+ rspec-mocks (~> 3.12.0)
114
+ rspec-collection_matchers (1.2.1)
98
115
  rspec-expectations (>= 2.99.0.beta1)
99
116
  rspec-context-private (0.0.1)
100
- rspec-core (3.11.0)
101
- rspec-support (~> 3.11.0)
102
- rspec-expectations (3.11.0)
117
+ rspec-core (3.12.2)
118
+ rspec-support (~> 3.12.0)
119
+ rspec-expectations (3.12.3)
103
120
  diff-lcs (>= 1.2.0, < 2.0)
104
- rspec-support (~> 3.11.0)
121
+ rspec-support (~> 3.12.0)
105
122
  rspec-given (3.8.2)
106
123
  given_core (= 3.8.2)
107
124
  rspec (>= 2.14.0)
@@ -110,34 +127,36 @@ GEM
110
127
  rspec-expectations (>= 3.0.0)
111
128
  rspec-legacy_formatters (1.0.2)
112
129
  rspec (~> 3.0)
113
- rspec-mocks (3.11.1)
130
+ rspec-mocks (3.12.6)
114
131
  diff-lcs (>= 1.2.0, < 2.0)
115
- rspec-support (~> 3.11.0)
116
- rspec-support (3.11.0)
117
- rubocop (1.29.1)
132
+ rspec-support (~> 3.12.0)
133
+ rspec-support (3.12.1)
134
+ rubocop (1.57.1)
135
+ base64 (~> 0.1.1)
136
+ json (~> 2.3)
137
+ language_server-protocol (>= 3.17.0)
118
138
  parallel (~> 1.10)
119
- parser (>= 3.1.0.0)
139
+ parser (>= 3.2.2.4)
120
140
  rainbow (>= 2.2.2, < 4.0)
121
141
  regexp_parser (>= 1.8, < 3.0)
122
142
  rexml (>= 3.2.5, < 4.0)
123
- rubocop-ast (>= 1.17.0, < 2.0)
143
+ rubocop-ast (>= 1.28.1, < 2.0)
124
144
  ruby-progressbar (~> 1.7)
125
- unicode-display_width (>= 1.4.0, < 3.0)
126
- rubocop-ast (1.18.0)
127
- parser (>= 3.1.1.0)
128
- ruby-progressbar (1.11.0)
129
- sdoc (2.3.1)
130
- rdoc (>= 5.0, < 6.4.0)
145
+ unicode-display_width (>= 2.4.0, < 3.0)
146
+ rubocop-ast (1.29.0)
147
+ parser (>= 3.2.1.0)
148
+ ruby-progressbar (1.13.0)
149
+ sdoc (2.6.1)
150
+ rdoc (>= 5.0)
131
151
  shellany (0.0.1)
132
152
  sorcerer (2.0.1)
153
+ stringio (3.0.8)
133
154
  terminal-table (3.0.2)
134
155
  unicode-display_width (>= 1.1.1, < 3)
135
- thor (1.2.1)
156
+ thor (1.3.0)
136
157
  tty-color (0.6.0)
137
- typhoeus (1.4.0)
138
- ethon (>= 0.9.0)
139
- unicode-display_width (2.1.0)
140
- zeitwerk (2.5.4)
158
+ unicode-display_width (2.5.0)
159
+ zeitwerk (2.6.12)
141
160
 
142
161
  PLATFORMS
143
162
  x86_64-linux
@@ -146,7 +165,6 @@ DEPENDENCIES
146
165
  arcadedb!
147
166
  awesome_print
148
167
  bundler (~> 2)
149
- dry-configurable
150
168
  guard
151
169
  guard-rspec
152
170
  pastel
data/arcade.yml CHANGED
@@ -1,8 +1,4 @@
1
1
  ---
2
- ## absolute path to the oetl-script
3
- :pg:
4
- :host: 10.247.8.109 # hierdevel
5
- :port: 5432
6
2
  :environment:
7
3
  :test:
8
4
  dbname: playground
data/arcadedb.gemspec CHANGED
@@ -23,13 +23,10 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 2"
24
24
  spec.add_development_dependency "rake", "~> 13.0"
25
25
  spec.add_development_dependency "rspec", "~> 4.0"
26
- # 'activesupport', '>= 6.0'
27
- # spec.add_dependency 'activemodel'
28
- spec.add_dependency "typhoeus"
26
+ spec.add_dependency "httpx"
29
27
  spec.add_dependency 'dry-schema'
30
28
  spec.add_dependency 'dry-struct'
31
29
  spec.add_dependency 'dry-core'
32
- ## Database-Access via Postgres is not implemented
33
- # spec.add_dependency 'pg'
34
- # spec.add_dependency 'mini_sql'
30
+ spec.add_dependency 'dry-configurable'
31
+ # spec.add_dependency 'dry-monads' # future use
35
32
  end
data/bin/console CHANGED
@@ -11,7 +11,7 @@ require 'terminal-table'
11
11
  require 'zeitwerk'
12
12
  require 'pastel'
13
13
  require 'arcade'
14
- require 'pry'
14
+ #require 'pry'
15
15
  #begin
16
16
 
17
17
 
@@ -118,9 +118,9 @@ DB = Arcade::Init.connect e
118
118
  require 'irb'
119
119
  ARGV.clear
120
120
  #begin
121
- #IRB.start(__FILE__)
121
+ IRB.start(__FILE__)
122
122
  #rescue ArgumentError => e
123
123
  # puts e
124
124
  ## retry
125
125
  #end
126
- Pry.start(__FILE__)
126
+ #Pry.start(__FILE__)
@@ -1,5 +1,6 @@
1
1
  module Arcade
2
2
  module Api
3
+ extend Primitives
3
4
  =begin
4
5
  This is a simple admin interface
5
6
 
@@ -22,44 +23,53 @@ module Arcade
22
23
 
23
24
  =end
24
25
 
26
+ # ------------------------------ Service methods ------------------------------------------------- #
27
+ # ------------------------------ ------------------------------------------------- #
28
+ # ------------------------------ databases ------------------------------------------------- #
29
+ # returns an array of databases present on the database-server #
25
30
 
26
31
  def self.databases
27
32
  get_data 'databases'
28
33
  end
29
34
 
35
+ # ------------------------------ create database ------------------------------------------------- #
36
+ # creates a database if not present #
30
37
  def self.create_database name
31
- unless databases.include?( name.to_s )
32
- payload = { "command" => "create database #{name}" }.to_json
33
- post_data "server", { body: payload }.merge( auth ).merge( json )
34
- end
35
- rescue QueryError => e
38
+ return if databases.include?( name.to_s )
39
+ payload = { "command" => "create database #{name}" }
40
+ post_data "server", payload
41
+ rescue HTTPX::HTTPError => e
36
42
  logger.fatal "Create database #{name} through \"POST create/#{name}\" failed"
37
43
  logger.fatal e
38
44
  raise
39
45
  end
40
46
 
47
+ # ------------------------------ drop database ------------------------------------------------- #
48
+ # deletes the given database #
41
49
  def self.drop_database name
42
- if databases.include?( name.to_s )
43
- payload = { "command" => "drop database #{name}" }.to_json
44
- post_data "server", { body: payload }.merge( auth ).merge( json )
45
- end
50
+ return unless databases.include?( name.to_s )
51
+ payload = {"command" => "drop database #{name}" }
52
+ post_data "server", payload
53
+ rescue HTTPX::HTTPError => e
54
+ logger.fatal "Drop database #{name} through \"POST drop database/#{name}\" failed"
55
+ raise
46
56
  end
47
57
  # ------------------------------ create document ------------------------------------------------- #
48
- # adds a document to the database
58
+ # adds a document to the specified database table
49
59
  #
50
60
  # specify database-fields as hash-type parameters
51
61
  #
52
62
  # i.e Arcade::Api.create_document 'devel', 'documents', name: 'herta meyer', age: 56, sex: 'f'
53
63
  #
54
64
  # returns the rid of the inserted dataset
55
- #
65
+ #
56
66
  def self.create_document database, type, **attributes
57
- payload = { "@type" => type }.merge( attributes ).to_json
67
+ payload = { "@type" => type }.merge( attributes )
58
68
  logger.debug "C: #{payload}"
59
69
  options = if session.nil?
60
- { body: payload }.merge( auth ).merge( json )
70
+ payload
61
71
  else
62
- { body: payload }.merge( auth ).merge( json ).merge( headers: { "arcadedb-session-id" => session })
72
+ payload.merge headers: { "arcadedb-session-id" => session }
63
73
  end
64
74
  post_data "document/#{database}", options
65
75
  end
@@ -71,32 +81,22 @@ module Arcade
71
81
  #
72
82
  # returns an Array of results (if propriate)
73
83
  # i.e
74
- # Arcade::Api.execcute( "devel" ) { 'select from test ' }
84
+ # Arcade::Api.execute( "devel" ) { 'select from test ' }
75
85
  # =y [{"@rid"=>"#57:0", "@type"=>"test", "name"=>"Hugo"}, {"@rid"=>"#60:0", "@type"=>"test", "name"=>"Hubert"}]
76
86
  #
77
- def self.execute database, query=nil
87
+ def self.execute database, query=nil, session_id= nil
78
88
  pl = query.nil? ? provide_payload(yield) : provide_payload(query)
79
- options = { body: pl }.merge( auth ).merge( json )
80
- unless session.nil?
81
- options = options.merge( headers: { "arcadedb-session-id" => session })
89
+ if session_id.nil? && session.nil?
90
+ post_data "command/#{database}" , pl
91
+ else
92
+ post_transaction "command/#{database}" , pl, session_id || session
82
93
  end
83
- post_data "command/#{database}" , options
84
- rescue Arcade::QueryError => e
85
- # puts e.methods
86
- #puts e.exception
87
- # puts e.full_message
88
- if e.message =~ /retry/
89
- retry
90
- else
91
- raise e.message
92
- end
93
94
  end
94
95
 
95
96
  # ------------------------------ query ------------------------------------------------- #
96
97
  # same for idempotent queries
97
98
  def self.query database, query
98
- options = { body: provide_payload(query) }.merge( auth ).merge( json )
99
- post_data "query/#{database}" , options
99
+ post_data "query/#{database}" , provide_payload(query)
100
100
  end
101
101
 
102
102
  # ------------------------------ get_record ------------------------------------------------- #
@@ -114,7 +114,7 @@ module Arcade
114
114
  if rid.rid?
115
115
  get_data "document/#{database}/#{rid}"
116
116
  else
117
- raise Arcade::Error "Get requires a rid input"
117
+ raise Error "Get requires a rid input"
118
118
  end
119
119
  end
120
120
 
@@ -136,10 +136,11 @@ module Arcade
136
136
  begin_transaction database
137
137
  success = args.map do | name, format |
138
138
  r= execute(database) {" create property #{type.to_s}.#{name.to_s} #{format.to_s} " } &.first
139
+ puts "R: #{r.inspect}"
139
140
  if r.nil?
140
141
  false
141
142
  else
142
- r.keys == [ :propertyName, :typeName, :operation ] && r[:operation] == 'create property'
143
+ r[:operation] == 'create property'
143
144
  end
144
145
  end.uniq
145
146
  if success == [true]
@@ -155,45 +156,20 @@ module Arcade
155
156
  # ------------------------------ index ------------------------------------------------- #
156
157
  def self.index database, type, name , *properties
157
158
  properties = properties.map( &:to_s )
158
- unique_requested = "unique" if properties.delete("unique")
159
+ unique_requested = "unique" if properties.delete("unique")
159
160
  unique_requested = "notunique" if properties.delete("notunique" )
160
161
  automatic = true if
161
162
  properties << name if properties.empty?
162
- # puts " create index #{type.to_s}[#{name.to_s}] on #{type} ( #{properties.join(',')} ) #{unique_requested}"
163
+ # puts " create index #{type.to_s}[#{name.to_s}] on #{type} ( #{properties.join(',')} ) #{unique_requested}"
163
164
  # VV 22.10: providing an index-name raises an Error ( Encountered " "(" "( "" at line 1, column 44. Was expecting one of: <EOF> <SCHEMA> ... <NULL_STRATEGY> ... ";" ... "," ... )) )
164
165
  # named indices droped for now
165
- success = execute(database) {" create index on #{type} ( #{properties.join(',')} ) #{unique_requested}" } &.first
166
+ success = execute(database) {" create index IF NOT EXISTS on #{type} (#{properties.join(', ')}) #{unique_requested}" } &.first
166
167
  # puts "success: #{success}"
167
- success && success.keys == [ :totalIndexed, :name, :operation ] && success[:operation] == 'create index'
168
-
169
- end
170
-
171
-
172
- # ------------------------------ transaction ------------------------------------------------- #
173
- #
174
- def self.begin_transaction database
175
- result = Typhoeus.post Arcade::Config.base_uri + "begin/#{database}", auth
176
- @session_id = result.headers["arcadedb-session-id"]
168
+ success[:operation] == 'create index'
177
169
 
178
- # returns the session-id
179
170
  end
180
171
 
181
172
 
182
- # ------------------------------ commit ------------------------------------------------- #
183
- def self.commit database
184
- options = auth.merge( headers: { "arcadedb-session-id" => session })
185
- post_data "commit/#{database}", options
186
- @session_id = nil
187
- end
188
-
189
- # ------------------------------ rollback ------------------------------------------------- #
190
- def self.rollback database, publish_error=true
191
- options = auth.merge( headers: { "arcadedb-session-id" => session })
192
- post_data "rollback/#{database}", options
193
- @session_id = nil
194
- raise Arcade::RollbackError "A Transaction has been rolled back" if publish_error
195
- end
196
-
197
173
  private
198
174
 
199
175
  def self.logger
@@ -235,37 +211,15 @@ module Arcade
235
211
  [ :language, value.to_sym ]
236
212
  end
237
213
  end # case
238
- end .to_h ).to_json # map
239
- end
240
-
241
- def self.get_data command, options = auth
242
- result = Typhoeus.get Arcade::Config.base_uri + command, options
243
- analyse_result(result, command)
214
+ end .to_h ) # map
244
215
  end
245
216
 
246
217
 
247
- def self.post_data command, options = auth
248
- # puts "Post DATA #{command} #{options}" # debug
249
- i = 0; a=""
250
- loop do
251
- result = Typhoeus.post Arcade::Config.base_uri + command, options
252
- # Code: 503 – Service Unavailable
253
- if result.response_code.to_i == 503 # retry two times
254
- i += 1
255
- raise Arcade::QueryError, JSON.parse( result.response_body, symbolize_names: true )[:result] if i > 3
256
- sleep 0.1
257
- else
258
- a= analyse_result(result, command )
259
- break
260
- end
261
- end
262
- a
263
- end
264
218
 
265
- # returns the json-response
219
+ # returns the json-response ## retiered
266
220
  def self.analyse_result r, command
267
221
  if r.success?
268
- return nil if r.response_code == 204 # no content
222
+ return nil if r.status == 204 # no content
269
223
  result = JSON.parse( r.response_body, symbolize_names: true )[:result]
270
224
  if result == [{}]
271
225
  []
@@ -273,14 +227,14 @@ module Arcade
273
227
  result
274
228
  end
275
229
  elsif r.timed_out?
276
- raise Arcade::Error "Timeout Error", caller
230
+ raise Error "Timeout Error", caller
277
231
  []
278
232
  elsif r.response_code > 0
279
233
  logger.error "Execution Failure – Code: #{ r.response_code } – #{r.status_message} "
280
234
  error_message = JSON.parse( r.response_body, symbolize_names: true )
281
235
  logger.error "ErrorMessage: #{ error_message[:detail]} "
282
236
  if error_message[:detail] =~ /Duplicated key/
283
- raise Arcade::IndexError, error_message[:detail]
237
+ raise IndexError, error_message[:detail]
284
238
  else
285
239
  # available fields: :detail, :exception, error
286
240
  puts error_message[:detail]
@@ -290,16 +244,13 @@ module Arcade
290
244
  end
291
245
  def self.auth
292
246
  @a ||= { httpauth: :basic,
293
- username: Arcade::Config.admin[:user],
294
- password: Arcade::Config.admin[:pass] }
247
+ username: Config.admin[:user],
248
+ password: Config.admin[:pass] }
295
249
  end
296
250
 
297
- def self.json
298
- { headers: { "Content-Type" => "application/json"} }
299
- end
300
251
  # not tested
301
252
  def self.delete_data command
302
- result = Typhoeus.delete Arcade::Config.base_uri + command, auth
253
+ result = HTTPX.delete Config.base_uri + command, auth
303
254
  analyse_result(result, command)
304
255
  end
305
256
  end
@@ -0,0 +1,98 @@
1
+ module Arcade
2
+ module Api
3
+ module Primitives
4
+
5
+ # This module handles the interaction with the database through HTTPX
6
+ #
7
+ # ------------------------------ http ------------------------------------------------------------ #
8
+ # persistent http handle to the database
9
+
10
+ def http
11
+ break_on = -> (response) { response.status == 500 }
12
+ @http ||= HTTPX.plugin(:basic_auth).basic_auth(auth[:username], auth[:password])
13
+ .plugin(:persistent)
14
+ .plugin(:circuit_breaker)
15
+ # .plugin(:circuit_breaker, circuit_breaker_break_on: break_on)
16
+ end
17
+
18
+ # ------------------------------ get data -------------------------------------------------------- #
19
+ def get_data command
20
+ response = http.get( Config.base_uri + command )
21
+ response.raise_for_status
22
+
23
+ JSON.parse( response.body, symbolize_names: true )[:result]
24
+ # alternative to `raise for status `
25
+ # case response = http.basic_auth(auth[:username], auth[:password]).get( Config.base_uri + command )
26
+ # in { status: 200..203, body: }
27
+ # puts "success: #{JSON.parse(body, symbolize_names: true)[:result]}"
28
+ # in { status: 400..499, body: }
29
+ # puts "client error: #{body.json}"
30
+ # in { status: 500.., body: }
31
+ # puts "server error: #{body.to_s}"
32
+ # in { error: error }
33
+ # puts "error: #{error.message}"
34
+ # else
35
+ # raise "unexpected: #{response}"
36
+ # end
37
+ # puts "result : #{response}"
38
+ # puts "code: #{response.status}"
39
+ # analyse_result(response, command)
40
+ end
41
+
42
+ # ------------------------------ post data -------------------------------------------------------- #
43
+ def post_data command, payload
44
+ # http = HTTPX.plugin(:basic_auth)
45
+ # .basic_auth(auth[:username], auth[:password])
46
+ response = http.post( Config.base_uri + command, json: payload )
47
+ response.raise_for_status
48
+ JSON.parse( response.body, symbolize_names: true )[:result]
49
+ end
50
+
51
+ # ------------------------------ transaction ------------------------------------------------- #
52
+ #
53
+ def begin_transaction database
54
+ result = http.post Config.base_uri + "begin/#{database}"
55
+ @session_id = result.headers["arcadedb-session-id"]
56
+ # returns the session-id
57
+ end
58
+
59
+ # ------------------------------ post transaction ------------------------------------------------- #
60
+ def post_transaction command, params, session_id= @session_id
61
+ # http = HTTPX.plugin(:basic_auth)
62
+ # .basic_auth(auth[:username], auth[:password])
63
+ # .with( headers: { "arcadedb-session-id"=>session }, debug_level: 1)
64
+ http_a = http.with( headers: { "arcadedb-session-id" => session_id } , debug_level: 1)
65
+ response = http_a.post( Config.base_uri + command, json: params )
66
+ response.raise_for_status
67
+ JSON.parse( response.body, symbolize_names: true )[:result]
68
+
69
+ end
70
+
71
+ # ------------------------------ commit ------------------------------------------------- #
72
+ def commit database, session_id = @session_id
73
+ http_a = http.with( headers: { "arcadedb-session-id" => session_id } , debug_level: 1)
74
+ response = http_a.post( Config.base_uri + "commit/#{database}" )
75
+ response.raise_for_status
76
+ @session_id = nil
77
+ response.status # returns 204 --> success
78
+ # 403 --> incalid credentials
79
+ # 500 --> Transaction not begun
80
+
81
+ end
82
+
83
+ # ------------------------------ rollback ------------------------------------------------- #
84
+ def rollback database, session_id = @session_id, publish_error=true
85
+ # http = HTTPX.plugin(:basic_auth)
86
+ # .basic_auth(auth[:username], auth[:password])
87
+ # .with( headers: { "arcadedb-session-id"=>session_id }, debug_level: 1)
88
+ http_a = http.with( headers: { "arcadedb-session-id" => session_id } , debug_level: 1)
89
+ response = http_a.post( Config.base_uri + "rollback/#{database}" )
90
+ response.raise_for_status
91
+ @session_id = nil
92
+ logger.error "A Transaction has been rolled back" # if publish_error
93
+ response.status
94
+ end
95
+ end
96
+ end
97
+ end
98
+
data/lib/arcade/base.rb CHANGED
@@ -5,7 +5,7 @@ module Arcade
5
5
  # schema schema.strict # -- throws an error if specified keys are missing
6
6
  transform_keys{ |x| x[0] == '@' ? x[1..-1].to_sym : x.to_sym }
7
7
  # Types::Rid --> only accept #000:000, raises an Error, if rid is not present
8
- attribute :rid, Types::Rid
8
+ attribute :rid?, Types::Rid
9
9
  # maybe there are edges ## removed in favour of instance methods
10
10
  # attribute :in?, Types::Nominal::Any
11
11
  # attribute :out?, Types::Nominal::Any
@@ -41,12 +41,7 @@ module Arcade
41
41
  if the_class.respond_to?(:demodulize)
42
42
  if [ 'Document','Vertex', 'Edge'].include?(the_class.demodulize)
43
43
  if the_class == superclass # no inheritance
44
- ## we have to use demodulize as the_class actually is Arcade::Vertex, ...
45
- unless parent_present[ to_s.snake_case ]
46
44
  db.create_type the_class.demodulize, to_s.snake_case
47
- else
48
- db.logger.warn "Type #{ to_s.snake_case } is present, process skipped"
49
- end
50
45
  else
51
46
  if superclass.is_a? Class # maybe its a module.
52
47
  extended = superclass.to_s.snake_case
@@ -75,7 +70,7 @@ module Arcade
75
70
  db.execute { the_command }
76
71
  end unless custom_setup.nil?
77
72
 
78
- rescue Arcade::RollbackError => e
73
+ rescue RollbackError => e
79
74
  db.logger.warn e
80
75
  rescue RuntimeError => e
81
76
  db.logger.warn e
@@ -134,10 +129,10 @@ module Arcade
134
129
  # ( depreciated )
135
130
 
136
131
  def create **attributes
137
- Api.begin_transaction db.database
132
+ s = Api.begin_transaction db.database
138
133
  attributes.merge!( created: DateTime.now ) if timestamps
139
134
  record = insert **attributes
140
- Api.commit db.database
135
+ Api.commit db.database, s
141
136
  record
142
137
  rescue QueryError => e
143
138
  db.logger.error "Dataset NOT created"
@@ -222,8 +217,7 @@ module Arcade
222
217
  # Finds the first matching record providing the parameters of a `where` query
223
218
  # Strategie.find symbol: 'Still'
224
219
  # is equivalent to
225
- # Strategie.all.find{|y| y.symbol == 'Still'
226
- # }
220
+ # Strategie.all.find{|y| y.symbol == 'Still' }
227
221
  def find **args
228
222
  f= where(**args).first
229
223
  f= where( "#{ args.keys.first } like #{ args.values.first.to_or }" ).first if f.nil? || f.empty?
@@ -278,14 +272,14 @@ module Arcade
278
272
  end
279
273
  result= query( **( { kind: :upsert }.merge statement ) ).execute do | answer|
280
274
  z= answer[:"$current"] &.allocate_model(false) # do not autoload modelfiles
281
- raise Arcade::LoadError "Upsert failed" unless z.is_a? Arcade::Base
275
+ raise LoadError "Upsert failed" unless z.is_a? Base
282
276
  z # return record
283
277
  end
284
278
  end
285
279
 
286
280
 
287
281
  def query **args
288
- Arcade::Query.new( **{ from: self }.merge(args) )
282
+ Query.new( **{ from: self }.merge(args) )
289
283
  end
290
284
 
291
285
  # immutable support
@@ -332,7 +326,7 @@ module Arcade
332
326
  end
333
327
 
334
328
  def query **args
335
- Arcade::Query.new( **{ from: rid }.merge(args) )
329
+ Query.new( **{ from: rid }.merge(args) )
336
330
  end
337
331
 
338
332
  # to JSON controlls the serialisation of Arcade::Base Objects for the HTTP-JSON API
@@ -364,7 +358,7 @@ module Arcade
364
358
 
365
359
  "<#{ self.class.to_s.snake_case }" + rid? ? "[#{ rid }]: " : " " + invariant_attributes.map do |attr, value|
366
360
  v= case value
367
- when Arcade::Base
361
+ when Base
368
362
  "< #{ self.class.to_s.snake_case }: #{ value.rid } >"
369
363
  when Array
370
364
  value.map{|x| x.to_s}
@@ -375,7 +369,12 @@ module Arcade
375
369
  end.compact.sort.join(', ') + ">".gsub('"' , ' ')
376
370
  end
377
371
 
378
- alias to_s to_human
372
+
373
+ # configure irb-output to to_human for all Arcade::Base-Objects
374
+ #
375
+ def inspect
376
+ to_human
377
+ end
379
378
 
380
379
  def to_html # iruby
381
380
  _modul, _class = self.class.to_s.split "::"
@@ -383,7 +382,7 @@ module Arcade
383
382
  IRuby.display IRuby.html "<b style=\"color: #50953DFF\"><#{ the_class}</b>"
384
383
  + rid? ? "[#{ rid }]: " : " " + invariant_attributes.map do |attr, value|
385
384
  v= case value
386
- when Arcade::Base
385
+ when Base
387
386
  "< #{ self.class.to_s.snake_case }: #{ value.rid } >"
388
387
  when Array
389
388
  value.map{|x| x.to_s}
@@ -395,13 +394,13 @@ module Arcade
395
394
  end
396
395
 
397
396
  def update **args
398
- Arcade::Query.new( from: rid , kind: :update, set: args).execute
397
+ Query.new( from: rid , kind: :update, set: args).execute
399
398
  refresh
400
399
  end
401
400
 
402
401
  # inserts or updates a embedded document
403
402
  def insert_document name, obj
404
- value = if obj.is_a? Arcade::Document
403
+ value = if obj.is_a? Document
405
404
  obj.to_json
406
405
  else
407
406
  obj.to_or
@@ -417,7 +416,7 @@ module Arcade
417
416
  end
418
417
 
419
418
  def update_list list, value
420
- value = if value.is_a? Arcade::Document
419
+ value = if value.is_a? Document
421
420
  value.to_json
422
421
  else
423
422
  value.to_or
@@ -112,8 +112,13 @@ module Arcade
112
112
  types( true ) # update cached schema
113
113
  db
114
114
 
115
- rescue Arcade::QueryError
116
- Arcade::Database.logger.warn "Database type #{type} already present"
115
+ rescue HTTPX::HTTPError => e
116
+ # puts "ERROR: #{e.message.to_s}"
117
+ if e.status == 500 && e.message.to_s =~ /already exists/
118
+ Arcade::Database.logger.warn "Database type #{type} already present"
119
+ else
120
+ raise
121
+ end
117
122
  end
118
123
 
119
124
  alias create_class create_type
@@ -233,8 +238,18 @@ module Arcade
233
238
  # If an Error occurs, its rolled back
234
239
  #
235
240
  def execute &block
236
- Api.begin_transaction database
237
- response = Api.execute database, &block
241
+ s = Api.begin_transaction database
242
+ # begin
243
+ response = Api.execute database, nil, s, &block
244
+ # rescue HTTPX::HTTPError => e
245
+ # raise e.message
246
+ # puts e.methods
247
+ # puts e.status
248
+ # puts e.response
249
+ # puts e.message
250
+ # puts e.exception
251
+ # puts e.cause
252
+ # end
238
253
  # puts response.inspect # debugging
239
254
  r= if response.is_a? Hash
240
255
  _allocate_model res
@@ -251,11 +266,15 @@ module Arcade
251
266
  else
252
267
  response
253
268
  end
254
- Api.commit database
255
- r # return associated array of Arcade::Base-objects
256
- rescue Dry::Struct::Error, Arcade::QueryError => e
257
- Api.rollback database
258
- logger.error "Execution FAILED --> #{e.exception}"
269
+ if Api.commit( database, s) == 204
270
+ r # return associated array of Arcade::Base-objects
271
+ else
272
+ []
273
+ end
274
+ rescue Dry::Struct::Error, HTTPX::HTTPError, Arcade::QueryError => e
275
+ Api.rollback database, s
276
+ logger.error "Execution FAILED --> Status #{e.status}"
277
+ # logger.error "Execution FAILED --> #{e.exception.message}"
259
278
  [] # return empty result
260
279
  end
261
280
 
@@ -272,7 +291,17 @@ module Arcade
272
291
 
273
292
  content = attributes.empty? ? "" : "CONTENT #{attributes.to_json}"
274
293
  cr = ->( f, t ) do
275
- edges = Api.execute( database, "create edge #{edge_class} from #{f.rid} to #{t.rid} #{content}").allocate_model(false)
294
+ begin
295
+ edges = Api.execute( database, "create edge #{edge_class} from #{f.rid} to #{t.rid} #{content}").allocate_model(false)
296
+ rescue HTTPX::HTTPError => e
297
+ # if e.status == 503
298
+ # puts e.status
299
+ # puts e.message
300
+ # puts e.message.class
301
+ # end
302
+ raise unless e.message =~ /Found duplicate key/
303
+ puts "#"+e.message.split("#").last[0..-3]
304
+ end
276
305
  #else
277
306
  # logger.error "Could not create Edge #{edge_class} from #{f} to #{t}"
278
307
  ## logger.error edges.to_s
@@ -1,3 +1,3 @@
1
1
  module Arcade
2
- VERSION = "0.3.3"
2
+ VERSION = "0.4"
3
3
  end
data/lib/arcade.rb CHANGED
@@ -2,7 +2,7 @@ module Arcade
2
2
 
3
3
  end
4
4
 
5
- require "arcade/api/version"
5
+ require "arcade/version"
6
6
  require "dry/configurable"
7
7
  require "dry/struct"
8
8
  require "dry/core/class_builder"
@@ -12,14 +12,10 @@ require 'json'
12
12
  module Types
13
13
  include Dry.Types()
14
14
  end
15
- #require 'pg' # ruby postgres driver
16
- #require 'mini_sql'
17
- #require 'sequel'
18
- #require 'httparty'
19
15
  require 'yaml'
20
16
  require 'securerandom'
21
- require 'typhoeus' # curl library
22
- require_relative '../lib/arcade/errors'
17
+ require 'httpx'
18
+ require 'arcade/errors'
23
19
  require_relative '../lib/support/object'
24
20
  require_relative '../lib/support/string'
25
21
  require_relative '../lib/support/class'
@@ -28,6 +24,7 @@ require_relative '../lib/support/model'
28
24
  require_relative '../lib/arcade/logging'
29
25
  require_relative '../lib/config'
30
26
  require_relative '../lib/support/conversions'
27
+ require_relative '../lib/arcade/api/primitives'
31
28
  require_relative '../lib/arcade/api/operations'
32
29
  require_relative '../lib/arcade/base'
33
30
  require_relative '../lib/arcade/database'
data/lib/config.rb CHANGED
@@ -48,17 +48,19 @@ module Arcade
48
48
  setting :namespace, default: :namespace, reader: true , constructor: ->(v) { yml(v) }
49
49
  setting :secret, reader: true, default: 12, constructor: ->(v) { seed(v) }
50
50
  private
51
- # if a config dir exists, use it
51
+ # if a config dir exists, use it.
52
+ # Standard: ProjectRoot/config.yml
52
53
  def self.config_file
53
- if @cd.nil?
54
- ( cd = ProjectRoot + 'arcade.yml' ).exist? ||
55
- ( cd = ProjectRoot + 'config' + 'arcade.yml' ).exist? ||
56
- ( cd = ProjectRoot + "config.yml" )
57
- @cd = cd
58
- else
59
- @cd
54
+
55
+ configdir = -> do
56
+ pr = ProjectRoot.is_a?(Pathname)? ProjectRoot : Pathname.new( ProjectRoot )
57
+ ( cd = pr + 'arcade.yml' ).exist? || ( cd = pr + 'config' + 'arcade.yml' ).exist? || ( cd = pr + 'config.yml' )
58
+ cd
60
59
  end
60
+
61
+ @cd ||= configdir[]
61
62
  end
63
+
62
64
  def self.yml key=nil
63
65
  y= YAML::load_file( config_file )
64
66
  key.nil? ? y : y[key]
data/lib/model/vertex.rb CHANGED
@@ -59,14 +59,14 @@ module Arcade
59
59
 
60
60
  s = Query.new from: self
61
61
  s.nodes in_or_out, via: via, **args
62
- s.query.select_result
62
+ s.query &.select_result
63
63
  end
64
64
 
65
65
 
66
66
  # #
67
67
  ## --------------------------------- Instance Methods --------------------------------- ##
68
68
  #
69
- # We need expand as fallback if a vertex, which is stored as link is automatically loaded
69
+ # We need expand as fallback if a vertex, which is stored as link, is automatically loaded
70
70
  #
71
71
  def expand
72
72
  self
@@ -77,7 +77,7 @@ module Arcade
77
77
  s = Query.new from: rid
78
78
  s.nodes in_or_out, via: via, **args
79
79
  if execute
80
- s.query.select_result
80
+ s.query &.select_result
81
81
  else
82
82
  s # just return the query
83
83
  end
@@ -209,7 +209,7 @@ Format: < Classname: Edges, Attributes >
209
209
 
210
210
  #Default presentation of Arcade::Base::Model-Objects
211
211
 
212
- "<#{self.class.to_s.snake_case}[#{rid}]: " +
212
+ "<#{self.class.to_s.snake_case}[#{rid}]:" +
213
213
  in_and_out[] +
214
214
  invariant_attributes.map do |attr, value|
215
215
  v= case value
data/lib/query.rb CHANGED
@@ -104,7 +104,7 @@ module Arcade
104
104
  elsif @q[:database].present?
105
105
  the_argument = @q[:database]
106
106
  case @q[:database]
107
- when Arcade::Base # a single record
107
+ when Base # a single record
108
108
  the_argument.rid
109
109
  when self.class # result of a query
110
110
  ' ( '+ the_argument.compose + ' ) '
@@ -370,7 +370,7 @@ end # class << self
370
370
  end
371
371
  :protected
372
372
  def resolve_target
373
- if @q[:database].is_a? Arcade::Query
373
+ if @q[:database].is_a? Query
374
374
  @q[:database].resolve_target
375
375
  else
376
376
  @q[:database]
@@ -195,7 +195,7 @@ module Arcade
195
195
  when Symbol, String
196
196
  k.to_s
197
197
  else
198
- raise "not supported key: #[k} -- must a sting, symbol or number"
198
+ raise "not supported key: #{k} -- must a sting, symbol or number"
199
199
  end
200
200
  [orient_k, v.to_db]
201
201
  end.to_h
data/lib/support/model.rb CHANGED
@@ -19,14 +19,17 @@ module Arcade
19
19
  # used by array#allocate_model
20
20
  def _allocate_model response=nil, auto = Config.autoload
21
21
 
22
+
22
23
  if response.is_a? Hash
23
24
  # save rid to a safe place
24
25
  temp_rid = response.delete :"@rid"
25
-
26
- return response if temp_rid.rid?.nil?
27
- # extract type infos and convert to database-name
28
26
  type = response.delete :"@type"
29
27
  cat = response.delete :"@cat"
28
+
29
+ return response if type.nil?
30
+ temp_rid = "#0:0" if temp_rid.nil?
31
+ type = "d" if type.nil?
32
+ # extract type infos and convert to database-name
30
33
  n, type_name = type.camelcase_and_namespace
31
34
  n = self.namespace if n.nil?
32
35
  # autoconvert rid's in attributes to model-records (exclude edges!)
@@ -38,7 +41,7 @@ module Arcade
38
41
  when Array
39
42
  x.map do| y |
40
43
  if y.is_a?(Hash) && y.include?(:@type) # if embedded documents are present, load them
41
- y.merge( rid: '#0:0' ).allocate_model(false)
44
+ y.allocate_model(false)
42
45
  elsif y.rid? # if links are present, load the object
43
46
  y.load_rid(false) # do not autoload further records, prevents from recursive locking
44
47
  else
@@ -47,7 +50,7 @@ module Arcade
47
50
  end
48
51
  when Hash
49
52
  if x.include?(:@type)
50
- x.merge( rid: '#0:0' ).allocate_model(false)
53
+ x.allocate_model(false)
51
54
  else
52
55
  x.transform_values!{|z| z.rid? ? z.load_rid(false) : z }
53
56
  end
@@ -61,7 +64,7 @@ module Arcade
61
64
  #
62
65
  begin
63
66
  # create a new object of that class with the appropriate attributes
64
- new = klass.new **response.merge( rid: temp_rid || "#0:0" ) # #0:0 --> embedded model records
67
+ new = klass.new **response.merge( rid: temp_rid )
65
68
  rescue ::ArgumentError => e
66
69
  raise "Allocation of class #{klass.to_s} failed"
67
70
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arcadedb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hartmut Bischoff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-23 00:00:00.000000000 Z
11
+ date: 2023-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: typhoeus
56
+ name: httpx
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: dry-configurable
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Provides access to ArcadeDB from ruby
112
126
  email: topofocus@gmail.com
113
127
  executables: []
@@ -132,7 +146,7 @@ files:
132
146
  - examples/relation_n_n.rb
133
147
  - lib/arcade.rb
134
148
  - lib/arcade/api/operations.rb
135
- - lib/arcade/api/version.rb
149
+ - lib/arcade/api/primitives.rb
136
150
  - lib/arcade/base.rb
137
151
  - lib/arcade/database.rb
138
152
  - lib/arcade/errors.rb
@@ -1,5 +0,0 @@
1
- module Arcade
2
- module Api
3
- VERSION = 0.1
4
- end
5
- end