orient_db_client 0.0.3 → 0.0.4

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