orient_db_client 0.0.3 → 0.0.4

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.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .DS_Store
data/README.md CHANGED
@@ -49,7 +49,7 @@ When you're done with the connection (and all of the sessions you have opened wi
49
49
 
50
50
  A server session is only needed when an application wants to create, delete, or confirm the existence of a database.
51
51
 
52
- To obtain a server session, call #open_server on the connection. This requires user credentials from the `<users>` section of the OrientDB server's `orientdb-server-config.xml` file.
52
+ To obtain a server session, call #open_server on the connection. This requires user credentials from the `<users>` section of the OrientDB server's `orientdb-server-config.xml` file.
53
53
 
54
54
  server = connection.open_server({
55
55
  :user => 'root',
@@ -11,9 +11,9 @@ module OrientDbClient
11
11
 
12
12
  s = TCPSocket.open(host, options[:port])
13
13
 
14
- protocol = s.read(2).unpack('s>').first
14
+ protocol = BinData::Int16be.read(s)
15
15
 
16
- Connection.new(s, protocol)
16
+ Connection.new(s, options[:protocol] || protocol)
17
17
  end
18
18
  module_function :connect
19
19
  end
@@ -1,5 +1,8 @@
1
+ require "bindata"
2
+
1
3
  module OrientDbClient
2
4
  class NetworkMessage
5
+
3
6
  def initialize(&block)
4
7
  @components = []
5
8
 
@@ -4,9 +4,15 @@ require File.join(File.dirname(__FILE__), 'protocols', 'protocol9')
4
4
  module OrientDbClient
5
5
  class ProtocolFactory
6
6
 
7
+ # Orient server 1.0 supports Protocols 7 and 9.
8
+ # Since Protocols 10 and 11 are not implemented by this client,
9
+ # protocol 9 is substituted to allow connections to succeed.
10
+
7
11
  PROTOCOLS = {
8
12
  '7' => Protocols::Protocol7,
9
- '9' => Protocols::Protocol9
13
+ '9' => Protocols::Protocol9,
14
+ '10' => Protocols::Protocol9,
15
+ '11' => Protocols::Protocol9
10
16
  }
11
17
 
12
18
  def self.get_protocol(version)
@@ -4,6 +4,8 @@ require 'orient_db_client/deserializers/deserializer7'
4
4
  require 'orient_db_client/serializers/serializer7'
5
5
  require 'orient_db_client/exceptions'
6
6
 
7
+ require 'bindata'
8
+
7
9
  module OrientDbClient
8
10
  module Protocols
9
11
  class Protocol7
@@ -71,6 +73,227 @@ module OrientDbClient
71
73
 
72
74
  NEW_SESSION = -1
73
75
 
76
+ class ProtocolString < BinData::Primitive
77
+ endian :big
78
+
79
+ int32 :len, :value => lambda { data.length }
80
+ string :data, :read_length => :len
81
+
82
+ def get; self.data; end
83
+ def set(v) self.data = v; end
84
+ end
85
+
86
+ class QueryMessage < BinData::Record
87
+ endian :big
88
+
89
+ protocol_string :query_class_name
90
+ protocol_string :text
91
+ int32 :non_text_limit, :initial_value => -1
92
+ int32 :serialized_params, :value => 0
93
+ end
94
+
95
+ module Commands
96
+ class Command < BinData::Record
97
+ endian :big
98
+
99
+ int8 :operation, :value => Operations::COMMAND
100
+ int32 :session
101
+ int8 :mode, :initial_value => 's'.ord
102
+
103
+ protocol_string :command_serialized
104
+ end
105
+
106
+ class Connect < BinData::Record
107
+ endian :big
108
+
109
+ int8 :operation, :value => Operations::CONNECT
110
+ int32 :session, :value => NEW_SESSION
111
+ protocol_string :driver, :value => DRIVER_NAME
112
+ protocol_string :driver_version, :value => DRIVER_VERSION
113
+ int16 :version
114
+ protocol_string :client_id
115
+ protocol_string :user
116
+ protocol_string :password
117
+ end
118
+
119
+ class Count < BinData::Record
120
+ endian :big
121
+
122
+ int8 :operation, :value => Operations::COUNT
123
+ int32 :session
124
+ protocol_string :cluster_name
125
+ end
126
+
127
+ class DataclusterAddLogical < BinData::Record
128
+ endian :big
129
+
130
+ int8 :operation, :value => Operations::DATACLUSTER_ADD
131
+ int32 :session
132
+ protocol_string :type, :value => 'LOGICAL'
133
+
134
+ int32 :physical_cluster_container_id
135
+ end
136
+
137
+ class DataclusterAddMemory < BinData::Record
138
+ endian :big
139
+
140
+ int8 :operation, :value => Operations::DATACLUSTER_ADD
141
+ int32 :session
142
+ protocol_string :type, :value => 'MEMORY'
143
+
144
+ protocol_string :name
145
+ end
146
+
147
+ class DataclusterAddPhysical < BinData::Record
148
+ endian :big
149
+
150
+ int8 :operation, :value => Operations::DATACLUSTER_ADD
151
+ int32 :session
152
+ protocol_string :type, :value => 'PHYSICAL'
153
+
154
+ protocol_string :name
155
+ protocol_string :file_name
156
+ int32 :initial_size, :initial_value => -1
157
+ end
158
+
159
+ class DataclusterDatarange < BinData::Record
160
+ endian :big
161
+
162
+ int8 :operation, :value => Operations::DATACLUSTER_DATARANGE
163
+ int32 :session
164
+ int16 :cluster_id
165
+ end
166
+
167
+ class DataclusterRemove < BinData::Record
168
+ endian :big
169
+
170
+ int8 :operation, :value => Operations::DATACLUSTER_REMOVE
171
+ int32 :session
172
+ Int16 :cluster_id
173
+ end
174
+
175
+ class DbClose < BinData::Record
176
+ endian :big
177
+
178
+ int8 :operation, :value => Operations::DB_CLOSE
179
+ int32 :session
180
+ end
181
+
182
+ class DbCountRecords < BinData::Record
183
+ endian :big
184
+
185
+ int8 :operation, :value => Operations::DB_COUNTRECORDS
186
+ int32 :session
187
+ end
188
+
189
+ class DbCreate < BinData::Record
190
+ endian :big
191
+
192
+ int8 :operation, :value => Operations::DB_CREATE
193
+ int32 :session
194
+
195
+ protocol_string :database
196
+ protocol_string :storage_type
197
+ end
198
+
199
+ class DbDelete < BinData::Record
200
+ endian :big
201
+
202
+ int8 :operation, :value => Operations::DB_DELETE
203
+ int32 :session
204
+
205
+ protocol_string :database
206
+ end
207
+
208
+ class DbExist < BinData::Record
209
+ endian :big
210
+
211
+ int8 :operation, :value => Operations::DB_EXIST
212
+ int32 :session
213
+
214
+ protocol_string :database
215
+ end
216
+
217
+ class DbOpen < BinData::Record
218
+ endian :big
219
+
220
+ int8 :operation, :value => Operations::DB_OPEN
221
+ int32 :session, :value => NEW_SESSION
222
+
223
+ protocol_string :driver, :value => DRIVER_NAME
224
+ protocol_string :driver_version, :value => DRIVER_VERSION
225
+ int16 :version
226
+ protocol_string :client_id
227
+ protocol_string :database
228
+ protocol_string :user
229
+ protocol_string :password
230
+ end
231
+
232
+ class DbReload < BinData::Record
233
+ endian :big
234
+
235
+ int8 :operation, :value => Operations::DB_RELOAD
236
+ int32 :session
237
+ end
238
+
239
+ class DbSize < BinData::Record
240
+ endian :big
241
+
242
+ int8 :operation, :value => Operations::DB_SIZE
243
+ int32 :session
244
+ end
245
+
246
+ class RecordCreate < BinData::Record
247
+ endian :big
248
+
249
+ int8 :operation, :value => Operations::RECORD_CREATE
250
+ int32 :session
251
+
252
+ int16 :cluster_id
253
+ protocol_string :record_content
254
+ int8 :record_type, :value => RecordTypes::DOCUMENT
255
+ int8 :mode, :value => SyncModes::SYNC
256
+ end
257
+
258
+ class RecordDelete < BinData::Record
259
+ endian :big
260
+
261
+ int8 :operation, :value => Operations::RECORD_DELETE
262
+ int32 :session
263
+
264
+ int16 :cluster_id
265
+ int64 :cluster_position
266
+ int32 :record_version
267
+ int8 :mode, :value => SyncModes::SYNC
268
+ end
269
+
270
+ class RecordLoad < BinData::Record
271
+ endian :big
272
+
273
+ int8 :operation, :value => Operations::RECORD_LOAD
274
+ int32 :session
275
+
276
+ int16 :cluster_id
277
+ int64 :cluster_position
278
+ protocol_string :fetch_plan
279
+ end
280
+
281
+ class RecordUpdate < BinData::Record
282
+ endian :big
283
+
284
+ int8 :operation, :value => Operations::RECORD_UPDATE
285
+ int32 :session
286
+
287
+ int16 :cluster_id
288
+ int64 :cluster_position
289
+
290
+ protocol_string :record_content
291
+ int32 :record_version
292
+ int8 :record_type, :value => RecordTypes::DOCUMENT
293
+ int8 :mode, :value => SyncModes::SYNC
294
+ end
295
+ end
296
+
74
297
  def self.command(socket, session, command, options = {})
75
298
  options = {
76
299
  :async => false, # Async mode is not supported yet
@@ -86,19 +309,15 @@ module OrientDbClient
86
309
  end
87
310
  end
88
311
 
89
- serialized_command = NetworkMessage.new { |m|
90
- m.add :string, options[:query_class_name]
91
- m.add :string, command
92
- m.add :integer, options[:non_text_limit] || options[:limit]
93
- m.add :integer, 0
94
- }.pack
312
+ query = QueryMessage.new :query_class_name => options[:query_class_name],
313
+ :text => command,
314
+ :non_text_limit => options[:non_text_limit] || options[:limit]
315
+
316
+ command = Commands::Command.new :session => session,
317
+ :mode => options[:async] ? 'a'.ord : 's'.ord,
318
+ :command_serialized => query.to_binary_s
95
319
 
96
- socket.write NetworkMessage.new { |m|
97
- m.add :byte, Operations::COMMAND
98
- m.add :integer, session
99
- m.add :byte, options[:async] ? 'a' : 's'
100
- m.add :string, serialized_command
101
- }.pack
320
+ command.write(socket)
102
321
 
103
322
  read_response(socket)
104
323
 
@@ -107,16 +326,10 @@ module OrientDbClient
107
326
  end
108
327
 
109
328
  def self.connect(socket, options = {})
110
- socket.write NetworkMessage.new { |m|
111
- m.add :byte, Operations::CONNECT
112
- m.add :integer, NEW_SESSION
113
- m.add :string, DRIVER_NAME
114
- m.add :string, DRIVER_VERSION
115
- m.add :short, self.version
116
- m.add :integer, 0
117
- m.add :string, options[:user]
118
- m.add :string, options[:password]
119
- }.pack
329
+ command = Commands::Connect.new :version => self.version,
330
+ :user => options[:user],
331
+ :password => options[:password]
332
+ command.write(socket)
120
333
 
121
334
  read_response(socket)
122
335
 
@@ -125,11 +338,10 @@ module OrientDbClient
125
338
  end
126
339
 
127
340
  def self.count(socket, session, cluster_name)
128
- socket.write NetworkMessage.new { |m|
129
- m.add :byte, Operations::COUNT
130
- m.add :integer, session
131
- m.add :string, cluster_name
132
- }.pack
341
+ command = Commands::Count.new :session => session,
342
+ :cluster_name => cluster_name
343
+
344
+ command.write(socket)
133
345
 
134
346
  read_response(socket)
135
347
 
@@ -138,25 +350,23 @@ module OrientDbClient
138
350
  end
139
351
 
140
352
  def self.datacluster_add(socket, session, type, options)
141
- socket.write NetworkMessage.new { |m|
142
- type = type.downcase.to_sym if type.is_a?(String)
143
- type_string = type.to_s.upcase
144
-
145
- m.add :byte, Operations::DATACLUSTER_ADD
146
- m.add :integer, session
147
- m.add :string, type_string
148
-
149
- case type
150
- when :physical
151
- m.add :string, options[:name]
152
- m.add :string, options[:file_name]
153
- m.add :integer, options[:initial_size] || -1
154
- when :logical
155
- m.add :integer, options[:physical_cluster_container_id]
156
- when :memory
157
- m.add :string, options[:name]
158
- end
159
- }.pack
353
+ type = type.downcase.to_sym if type.is_a?(String)
354
+
355
+ case type
356
+ when :physical
357
+ command = Commands::DataclusterAddPhysical.new :session => session,
358
+ :name => options[:name],
359
+ :file_name => options[:file_name],
360
+ :initial_size => options[:initial_size] || -1
361
+ when :logical
362
+ command = Commands::DataclusterAddLogical.new :session => session,
363
+ :physical_cluster_container_id => options[:physical_cluster_container_id]
364
+ when :memory
365
+ command = Commands::DataclusterAddMemory.new :session => session,
366
+ :name => options[:name]
367
+ end
368
+
369
+ command.write(socket)
160
370
 
161
371
  read_response(socket)
162
372
 
@@ -165,11 +375,10 @@ module OrientDbClient
165
375
  end
166
376
 
167
377
  def self.datacluster_datarange(socket, session, cluster_id)
168
- socket.write NetworkMessage.new { |m|
169
- m.add :byte, Operations::DATACLUSTER_DATARANGE
170
- m.add :integer, session
171
- m.add :short, cluster_id
172
- }.pack
378
+ command = Commands::DataclusterDatarange.new :session => session,
379
+ :cluster_id => cluster_id
380
+
381
+ command.write(socket)
173
382
 
174
383
  read_response(socket)
175
384
 
@@ -178,11 +387,9 @@ module OrientDbClient
178
387
  end
179
388
 
180
389
  def self.datacluster_remove(socket, session, cluster_id)
181
- socket.write NetworkMessage.new { |m|
182
- m.add :byte, Operations::DATACLUSTER_REMOVE
183
- m.add :integer, session
184
- m.add :short, cluster_id
185
- }.pack
390
+ command = Commands::DataclusterRemove.new :session => session,
391
+ :cluster_id => cluster_id
392
+ command.write(socket)
186
393
 
187
394
  read_response(socket)
188
395
 
@@ -191,19 +398,15 @@ module OrientDbClient
191
398
  end
192
399
 
193
400
  def self.db_close(socket, session = NEW_SESSION)
194
- socket.write NetworkMessage.new { |m|
195
- m.add :byte, Operations::DB_CLOSE
196
- m.add :integer, session
197
- }.pack
401
+ command = Commands::DbClose.new :session => session
402
+ command.write(socket)
198
403
 
199
404
  return socket.closed?
200
405
  end
201
406
 
202
407
  def self.db_countrecords(socket, session)
203
- socket.write NetworkMessage.new { |m|
204
- m.add :byte, Operations::DB_COUNTRECORDS
205
- m.add :integer, session
206
- }.pack
408
+ command = Commands::DbCountRecords.new :session => session
409
+ command.write(socket)
207
410
 
208
411
  read_response(socket)
209
412
 
@@ -220,7 +423,7 @@ module OrientDbClient
220
423
 
221
424
  options[:storage_type] = options[:storage_type].to_s
222
425
 
223
- socket.write make_db_create_message(session, database, options).pack
426
+ make_db_create_command(session, database, options).write(socket)
224
427
 
225
428
  read_response(socket)
226
429
 
@@ -228,11 +431,9 @@ module OrientDbClient
228
431
  end
229
432
 
230
433
  def self.db_delete(socket, session, database)
231
- socket.write NetworkMessage.new { |m|
232
- m.add :byte, Operations::DB_DELETE
233
- m.add :integer, session
234
- m.add :string, database
235
- }.pack
434
+ command = Commands::DbDelete.new :session => session,
435
+ :database => database
436
+ command.write(socket)
236
437
 
237
438
  read_response(socket)
238
439
 
@@ -240,11 +441,9 @@ module OrientDbClient
240
441
  end
241
442
 
242
443
  def self.db_exist(socket, session, database)
243
- socket.write NetworkMessage.new { |m|
244
- m.add :byte, Operations::DB_EXIST
245
- m.add :integer, session
246
- m.add :string, database
247
- }.pack
444
+ command = Commands::DbExist.new :session => session,
445
+ :database => database
446
+ command.write(socket)
248
447
 
249
448
  read_response(socket)
250
449
 
@@ -253,17 +452,11 @@ module OrientDbClient
253
452
  end
254
453
 
255
454
  def self.db_open(socket, database, options = {})
256
- socket.write NetworkMessage.new { |m|
257
- m.add :byte, Operations::DB_OPEN
258
- m.add :integer, NEW_SESSION
259
- m.add :string, DRIVER_NAME
260
- m.add :string, DRIVER_VERSION
261
- m.add :short, self.version
262
- m.add :integer, 0
263
- m.add :string, database
264
- m.add :string, options[:user]
265
- m.add :string, options[:password]
266
- }.pack
455
+ command = Commands::DbOpen.new :version => self.version,
456
+ :database => database,
457
+ :user => options[:user],
458
+ :password => options[:password]
459
+ command.write(socket)
267
460
 
268
461
  read_response(socket)
269
462
 
@@ -272,10 +465,8 @@ module OrientDbClient
272
465
  end
273
466
 
274
467
  def self.db_reload(socket, session)
275
- socket.write NetworkMessage.new { |m|
276
- m.add :byte, Operations::DB_RELOAD
277
- m.add :integer, session
278
- }.pack
468
+ command = Commands::DbReload.new :session => session
469
+ command.write(socket)
279
470
 
280
471
  read_response(socket)
281
472
 
@@ -284,10 +475,8 @@ module OrientDbClient
284
475
  end
285
476
 
286
477
  def self.db_size(socket, session)
287
- socket.write NetworkMessage.new { |m|
288
- m.add :byte, Operations::DB_SIZE
289
- m.add :integer, session
290
- }.pack
478
+ command = Commands::DbSize.new :session => session
479
+ command.write(socket)
291
480
 
292
481
  read_response(socket)
293
482
 
@@ -296,14 +485,10 @@ module OrientDbClient
296
485
  end
297
486
 
298
487
  def self.record_create(socket, session, cluster_id, record)
299
- socket.write NetworkMessage.new { |m|
300
- m.add :byte, Operations::RECORD_CREATE
301
- m.add :integer, session
302
- m.add :short, cluster_id
303
- m.add :string, serializer.serialize(record)
304
- m.add :byte, RecordTypes::DOCUMENT
305
- m.add :byte, SyncModes::SYNC
306
- }.pack
488
+ command = Commands::RecordCreate.new :session => session,
489
+ :cluster_id => cluster_id,
490
+ :record_content => serializer.serialize(record)
491
+ command.write(socket)
307
492
 
308
493
  read_response(socket)
309
494
 
@@ -312,14 +497,11 @@ module OrientDbClient
312
497
  end
313
498
 
314
499
  def self.record_delete(socket, session, cluster_id, cluster_position, version)
315
- socket.write NetworkMessage.new { |m|
316
- m.add :byte, Operations::RECORD_DELETE
317
- m.add :integer, session
318
- m.add :short, cluster_id
319
- m.add :long, cluster_position
320
- m.add :integer, version
321
- m.add :byte, SyncModes::SYNC
322
- }.pack
500
+ command = Commands::RecordDelete.new :session => session,
501
+ :cluster_id => cluster_id,
502
+ :cluster_position => cluster_position,
503
+ :record_version => version
504
+ command.write(socket)
323
505
 
324
506
  read_response(socket)
325
507
 
@@ -328,13 +510,10 @@ module OrientDbClient
328
510
  end
329
511
 
330
512
  def self.record_load(socket, session, rid)
331
- socket.write NetworkMessage.new { |m|
332
- m.add :byte, Operations::RECORD_LOAD
333
- m.add :integer, session
334
- m.add :short, rid.cluster_id
335
- m.add :long, rid.cluster_position
336
- m.add :string, ""
337
- }.pack
513
+ command = Commands::RecordLoad.new :session => session,
514
+ :cluster_id => rid.cluster_id,
515
+ :cluster_position => rid.cluster_position
516
+ command.write(socket)
338
517
 
339
518
  read_response(socket)
340
519
 
@@ -351,16 +530,12 @@ module OrientDbClient
351
530
  end
352
531
  end
353
532
 
354
- socket.write NetworkMessage.new { |m|
355
- m.add :byte, Operations::RECORD_UPDATE
356
- m.add :integer, session
357
- m.add :short, cluster_id
358
- m.add :long, cluster_position
359
- m.add :string, serializer.serialize(record)
360
- m.add :integer, version
361
- m.add :byte, RecordTypes::DOCUMENT
362
- m.add :byte, SyncModes::SYNC
363
- }.pack
533
+ command = Commands::RecordUpdate.new :session => session,
534
+ :cluster_id => cluster_id,
535
+ :cluster_position => cluster_position,
536
+ :record_content => serializer.serialize(record),
537
+ :record_version => version
538
+ command.write(socket)
364
539
 
365
540
  read_response(socket)
366
541
 
@@ -382,21 +557,18 @@ module OrientDbClient
382
557
 
383
558
  private
384
559
 
385
- def self.make_db_create_message(*args)
560
+ def self.make_db_create_command(*args)
386
561
  session = args.shift
387
562
  database = args.shift
388
563
  options = args.shift
389
564
 
390
- NetworkMessage.new { |m|
391
- m.add :byte, Operations::DB_CREATE
392
- m.add :integer, session
393
- m.add :string, database
394
- m.add :string, options[:storage_type].to_s
395
- }
565
+ Commands::DbCreate.new :session => session,
566
+ :database => database,
567
+ :storage_type => options[:storage_type]
396
568
  end
397
569
 
398
570
  def self.read_byte(socket)
399
- socket.read(1).unpack('C').first
571
+ BinData::Int8.read(socket).to_i
400
572
  end
401
573
 
402
574
  def self.read_count(socket)
@@ -492,11 +664,11 @@ module OrientDbClient
492
664
  end
493
665
 
494
666
  def self.read_integer(socket)
495
- socket.read(4).unpack('l>').first
667
+ BinData::Int32be.read(socket).to_i
496
668
  end
497
669
 
498
670
  def self.read_long(socket)
499
- socket.read(8).unpack('q>').first
671
+ BinData::Int64be.read(socket).to_i
500
672
  end
501
673
 
502
674
  def self.read_record(socket)
@@ -579,13 +751,17 @@ module OrientDbClient
579
751
  end
580
752
 
581
753
  def self.read_short(socket)
582
- socket.read(2).unpack('s>').first
754
+ BinData::Int16be.read(socket).to_i
583
755
  end
584
756
 
585
757
  def self.read_string(socket)
586
- length = read_integer(socket)
587
-
588
- length > 0 ? socket.read(length) : nil
758
+ bin_length = read_integer(socket)
759
+ return nil if bin_length < 0
760
+
761
+ raise bin_length.inspect if bin_length < 0
762
+
763
+ bin_str = socket.read(bin_length)
764
+ bin_str.length > 0 ? bin_str : nil
589
765
  end
590
766
  end
591
767
  end