orientdb-binary 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +64 -0
- data/lib/orientdb_binary.rb +25 -0
- data/lib/orientdb_binary/base.rb +40 -0
- data/lib/orientdb_binary/config.rb +5 -0
- data/lib/orientdb_binary/connection.rb +17 -0
- data/lib/orientdb_binary/database.rb +24 -0
- data/lib/orientdb_binary/database_operations/base_operations.rb +70 -0
- data/lib/orientdb_binary/database_operations/data_cluster.rb +116 -0
- data/lib/orientdb_binary/database_operations/data_segment.rb +31 -0
- data/lib/orientdb_binary/database_operations/query.rb +58 -0
- data/lib/orientdb_binary/database_operations/record.rb +105 -0
- data/lib/orientdb_binary/database_operations/transaction.rb +8 -0
- data/lib/orientdb_binary/operation_types.rb +51 -0
- data/lib/orientdb_binary/parser/deserializer.rb +161 -0
- data/lib/orientdb_binary/parser/serializer.rb +83 -0
- data/lib/orientdb_binary/protocols/base.rb +42 -0
- data/lib/orientdb_binary/protocols/bindata_primitives.rb +46 -0
- data/lib/orientdb_binary/protocols/command.rb +166 -0
- data/lib/orientdb_binary/protocols/config_get.rb +22 -0
- data/lib/orientdb_binary/protocols/config_list.rb +24 -0
- data/lib/orientdb_binary/protocols/config_set.rb +22 -0
- data/lib/orientdb_binary/protocols/connect.rb +26 -0
- data/lib/orientdb_binary/protocols/datacluster_add.rb +26 -0
- data/lib/orientdb_binary/protocols/datacluster_count.rb +26 -0
- data/lib/orientdb_binary/protocols/datacluster_datarange.rb +23 -0
- data/lib/orientdb_binary/protocols/datacluster_drop.rb +22 -0
- data/lib/orientdb_binary/protocols/datacluster_lh_cluster_is_used.rb +20 -0
- data/lib/orientdb_binary/protocols/datasegment_add.rb +24 -0
- data/lib/orientdb_binary/protocols/datasegment_drop.rb +23 -0
- data/lib/orientdb_binary/protocols/db_close.rb +16 -0
- data/lib/orientdb_binary/protocols/db_countrecords.rb +20 -0
- data/lib/orientdb_binary/protocols/db_create.rb +23 -0
- data/lib/orientdb_binary/protocols/db_drop.rb +22 -0
- data/lib/orientdb_binary/protocols/db_exist.rb +23 -0
- data/lib/orientdb_binary/protocols/db_freeze.rb +21 -0
- data/lib/orientdb_binary/protocols/db_list.rb +26 -0
- data/lib/orientdb_binary/protocols/db_open.rb +43 -0
- data/lib/orientdb_binary/protocols/db_release.rb +21 -0
- data/lib/orientdb_binary/protocols/db_reload.rb +26 -0
- data/lib/orientdb_binary/protocols/db_size.rb +20 -0
- data/lib/orientdb_binary/protocols/errors.rb +28 -0
- data/lib/orientdb_binary/protocols/record_create.rb +35 -0
- data/lib/orientdb_binary/protocols/record_delete.rb +25 -0
- data/lib/orientdb_binary/protocols/record_load.rb +65 -0
- data/lib/orientdb_binary/protocols/record_update.rb +27 -0
- data/lib/orientdb_binary/protocols/shutdown.rb +21 -0
- data/lib/orientdb_binary/server.rb +71 -0
- data/orientdb-binary.gemspec +26 -0
- data/test/database/test_database.rb +193 -0
- data/test/database/test_deserializer.rb +140 -0
- data/test/database/test_serializer.rb +55 -0
- data/test/server/test_server.rb +73 -0
- data/test/test_helper.rb +9 -0
- metadata +162 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'orientdb_binary/protocols/datasegment_add'
|
2
|
+
require 'orientdb_binary/protocols/datasegment_drop'
|
3
|
+
|
4
|
+
module OrientdbBinary
|
5
|
+
module DatabaseOperations
|
6
|
+
module DataSegment
|
7
|
+
|
8
|
+
# name: string
|
9
|
+
# location: string
|
10
|
+
# Usage:
|
11
|
+
# db.add_datasegment(name: "posts")
|
12
|
+
# db.add_datasegment(name: "posts", location: "posts_segments")
|
13
|
+
#
|
14
|
+
def add_datasegment(args)
|
15
|
+
default = {
|
16
|
+
location: args[:name] + "_segments"
|
17
|
+
}
|
18
|
+
options = default.merge(args)
|
19
|
+
OrientdbBinary::Protocols::DatasegmentAdd.new(params(options)).process(socket)
|
20
|
+
end
|
21
|
+
|
22
|
+
# name: string
|
23
|
+
# Usage:
|
24
|
+
# db.drop_datasegment(name: 'posts')
|
25
|
+
#
|
26
|
+
def drop_datasegment(args)
|
27
|
+
OrientdbBinary::Protocols::DatasegmentDrop.new(params(args)).process(socket)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'orientdb_binary/protocols/command'
|
2
|
+
|
3
|
+
module OrientdbBinary
|
4
|
+
module DatabaseOperations
|
5
|
+
module Query
|
6
|
+
def query(text, params, fetch_plan="*:0")
|
7
|
+
class_name = 'com.orientechnologies.orient.core.sql.query.OSQLSynchQuery'
|
8
|
+
serialized_params = OrientdbBinary::Parser::Serializer.new.serialize_document({params: params})
|
9
|
+
q = OrientdbBinary::Protocols::SqlCommandPayload.new text: text, serialized_params: serialized_params,
|
10
|
+
fetch_plan: fetch_plan,
|
11
|
+
class_name: class_name
|
12
|
+
_command(q.to_binary_s, class_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
# def script(text)
|
16
|
+
# class_name = 'com.orientechnologies.orient.core.sql.OCommandSQL'
|
17
|
+
# end
|
18
|
+
|
19
|
+
def command(text, params={})
|
20
|
+
class_name = 'com.orientechnologies.orient.core.sql.OCommandSQL'
|
21
|
+
fetch_plan = nil
|
22
|
+
serialized_params = OrientdbBinary::Parser::Serializer.new.serialize_document({params: params})
|
23
|
+
q = OrientdbBinary::Protocols::SqlCommandPayload.new text: text, serialized_params: serialized_params,
|
24
|
+
fetch_plan: fetch_plan,
|
25
|
+
class_name: class_name
|
26
|
+
_command(q.to_binary_s, class_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
# def command(text)
|
30
|
+
# mode = 's'.ord
|
31
|
+
# class_name = 'com.orientechnologies.orient.core.sql.query.OSQLSynchQuery'
|
32
|
+
# fetchplan = "*0"
|
33
|
+
|
34
|
+
# query = OrientdbBinary::Protocols::SqlCommandPayload.new text: text, non_text_limit: -1, fetchplan: fetchplan
|
35
|
+
# p query
|
36
|
+
|
37
|
+
# # command = OrientdbBinary::Protocols::Command.new session: session, mode: mode, clazz_name: class_name, command_payload_length: query.to_binary_s.length, command_payload: query.to_binary_s
|
38
|
+
# command = OrientdbBinary::Protocols::Command.new session: session, mode: mode, text: text, command_payload: query.to_binary_s
|
39
|
+
# command.write(socket)
|
40
|
+
|
41
|
+
# status = BinData::Int8.read(socket).to_i
|
42
|
+
# process_errors(status)
|
43
|
+
|
44
|
+
# p OrientdbBinary::Protocols::CommandAnswer.read(socket)
|
45
|
+
# end
|
46
|
+
|
47
|
+
private
|
48
|
+
def _command(binary_query, class_name)
|
49
|
+
mode = 's'.ord
|
50
|
+
OrientdbBinary::Protocols::Command.new(
|
51
|
+
session: session, mode: mode,
|
52
|
+
command_payload_length: binary_query.length,
|
53
|
+
command_payload: binary_query
|
54
|
+
).process(socket)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'orientdb_binary/protocols/record_load'
|
2
|
+
require 'orientdb_binary/protocols/record_create'
|
3
|
+
require 'orientdb_binary/protocols/record_update'
|
4
|
+
require 'orientdb_binary/protocols/record_delete'
|
5
|
+
require 'orientdb_binary/protocols/db_countrecords'
|
6
|
+
|
7
|
+
module OrientdbBinary
|
8
|
+
module DatabaseOperations
|
9
|
+
module Record
|
10
|
+
|
11
|
+
# rid: #id:position / id:position
|
12
|
+
# or
|
13
|
+
# cluster_id: int
|
14
|
+
# cluster:position: int
|
15
|
+
# optional
|
16
|
+
# fetch_plan: string (by default used "*:0")
|
17
|
+
# ignore_cache: int (0-1, by default 1)
|
18
|
+
# load_tombstones: int (0-1, by default 0)
|
19
|
+
# Usage:
|
20
|
+
# db.load_record("#5:2")
|
21
|
+
# db.load_record("#5:2", fetch_plan: "*:-1")
|
22
|
+
# db.load_record(5, 2, fetch_plan: "*:-1", ignore_cache: 0, load_tombstones: 1)
|
23
|
+
#
|
24
|
+
def load_record(args)
|
25
|
+
if args[:rid]
|
26
|
+
match = args[:rid].match(/#*(?<id>\d+):(?<position>\d+)/)
|
27
|
+
args[:cluster_id] = match[:id].to_i
|
28
|
+
args[:cluster_position] = match[:position].to_i
|
29
|
+
end
|
30
|
+
defaults = {
|
31
|
+
fetch_plan: "*:0",
|
32
|
+
ignore_cache: 1,
|
33
|
+
load_tombstones: 0
|
34
|
+
}
|
35
|
+
options = defaults.merge(args)
|
36
|
+
answer = OrientdbBinary::Protocols::RecordLoad.new(params(options)).process(socket)
|
37
|
+
answer.process(options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Create record from object
|
41
|
+
# Usage:
|
42
|
+
# record = {
|
43
|
+
# :@class => "Posts",
|
44
|
+
# :@type => "d",
|
45
|
+
# :@cluster => "posts"
|
46
|
+
# name: "some name"
|
47
|
+
# param: "some param"
|
48
|
+
# }
|
49
|
+
# Usage:
|
50
|
+
# db.create_record_from_object(record)
|
51
|
+
#
|
52
|
+
def create_record_from_object(record)
|
53
|
+
record_type = record[:@type] ? record[:@type].ord : "d".ord
|
54
|
+
cluster_id = (cluster = find_datacluster_by(cluster_name: 'default')) ? cluster[:cluster_id] : nil
|
55
|
+
|
56
|
+
if record[:@cluster]
|
57
|
+
if record[:@cluster].is_a? Integer
|
58
|
+
cluster_id = record[:@cluster]
|
59
|
+
else
|
60
|
+
cluster_id = (cluster = find_datacluster_by(cluster_name: record[:@cluster])) ? cluster[:cluster_id] : cluster_id
|
61
|
+
end
|
62
|
+
elsif record[:@class]
|
63
|
+
cluster_id = (cluster = find_datacluster_by(cluster_name: record[:@class])) ? cluster[:cluster_id] : cluster_id
|
64
|
+
end
|
65
|
+
|
66
|
+
record_content = OrientdbBinary::Parser::Serializer.new.serialize_document(record)
|
67
|
+
create_record(record_type: record_type, cluster_id: cluster_id, record_content: record_content)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Create record
|
71
|
+
# cluster_id: int or cluster_name: string
|
72
|
+
# record_content: string -> it's serialized document; use create_record_from_object which serialize hash into string accepted by Orientdb
|
73
|
+
# Usage:
|
74
|
+
# db.create_record(cluster_id: 5, record_content: "Post@title=\"Post title\"")
|
75
|
+
#
|
76
|
+
def create_record(args)
|
77
|
+
if args[:cluster_name] and not args[:cluster_id]
|
78
|
+
args[:cluster_id] = (cluster = find_datacluster_by(cluster_name: args[:cluster_name])) ? cluster_id : nil
|
79
|
+
end
|
80
|
+
|
81
|
+
defaults = {
|
82
|
+
datasegment_id: -1,
|
83
|
+
record_type: "d".ord,
|
84
|
+
mode: 0
|
85
|
+
}
|
86
|
+
|
87
|
+
options = defaults.merge(args)
|
88
|
+
answer = OrientdbBinary::Protocols::RecordCreate.new(params(args)).process(socket)
|
89
|
+
answer.process(options)
|
90
|
+
end
|
91
|
+
|
92
|
+
def update_record(args)
|
93
|
+
OrientdbBinary::Protocols::RecordUpdate.new(params(args)).process(socket)
|
94
|
+
end
|
95
|
+
|
96
|
+
def delete_record(args)
|
97
|
+
OrientdbBinary::Protocols::RecordDelete.new(params(args)).process(socket)
|
98
|
+
end
|
99
|
+
|
100
|
+
def count_records
|
101
|
+
OrientdbBinary::Protocols::DbCountRecords.new(params).process(socket)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module OrientdbBinary
|
2
|
+
module OperationTypes
|
3
|
+
NEW_SESSION = -1
|
4
|
+
REQUEST_SHUTDOWN = 1
|
5
|
+
REQUEST_CONNECT = 2
|
6
|
+
REQUEST_DB_OPEN = 3
|
7
|
+
REQUEST_DB_CREATE = 4
|
8
|
+
REQUEST_DB_CLOSE = 5
|
9
|
+
REQUEST_DB_EXIST = 6
|
10
|
+
REQUEST_DB_DROP = 7
|
11
|
+
REQUEST_DB_SIZE = 8
|
12
|
+
REQUEST_DB_COUNTRECORDS = 9
|
13
|
+
REQUEST_DATACLUSTER_ADD = 10
|
14
|
+
REQUEST_DATACLUSTER_DROP = 11
|
15
|
+
REQUEST_DATACLUSTER_COUNT = 12
|
16
|
+
REQUEST_DATACLUSTER_DATARANGE = 13
|
17
|
+
REQUEST_DATACLUSTER_COPY = 14
|
18
|
+
REQUEST_DATACLUSTER_LH_CLUSTER_IS_USED = 16
|
19
|
+
REQUEST_DATASEGMENT_ADD = 20
|
20
|
+
REQUEST_DATASEGMENT_DROP = 21
|
21
|
+
REQUEST_RECORD_METADATA = 29
|
22
|
+
REQUEST_RECORD_LOAD = 30
|
23
|
+
REQUEST_RECORD_CREATE = 31
|
24
|
+
REQUEST_RECORD_UPDATE = 32
|
25
|
+
REQUEST_RECORD_DELETE = 33
|
26
|
+
REQUEST_RECORD_COPY = 34
|
27
|
+
REQUEST_POSITIONS_HIGHER = 36
|
28
|
+
REQUEST_POSITIONS_LOWER = 37
|
29
|
+
REQUEST_RECORD_CLEAN_OUT = 38
|
30
|
+
REQUEST_POSITIONS_FLOOR = 39
|
31
|
+
REQUEST_COUNT = 40 # (DEPRECATED: USE REQUEST_DATACLUSTER_COUNT)
|
32
|
+
REQUEST_COMMAND = 41
|
33
|
+
REQUEST_POSITIONS_CEILING = 42
|
34
|
+
REQUEST_TX_COMMIT = 60
|
35
|
+
REQUEST_CONFIG_GET = 70
|
36
|
+
REQUEST_CONFIG_SET = 71
|
37
|
+
REQUEST_CONFIG_LIST = 72
|
38
|
+
REQUEST_DB_RELOAD = 73
|
39
|
+
REQUEST_DB_LIST = 74
|
40
|
+
REQUEST_PUSH_RECORD = 79
|
41
|
+
REQUEST_PUSH_DISTRIB_CONFIG = 80
|
42
|
+
REQUEST_DB_COPY = 90
|
43
|
+
REQUEST_REPLICATION = 91
|
44
|
+
REQUEST_CLUSTER = 92
|
45
|
+
REQUEST_DB_TRANSFER = 93
|
46
|
+
REQUEST_DB_FREEZE = 94
|
47
|
+
REQUEST_DB_RELEASE = 95
|
48
|
+
REQUEST_DATACLUSTER_FREEZE = 96
|
49
|
+
REQUEST_DATACLUSTER_RELEASE = 97
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module OrientdbBinary
|
2
|
+
module Parser
|
3
|
+
class Deserializer
|
4
|
+
attr_accessor :record
|
5
|
+
|
6
|
+
def initialize()
|
7
|
+
@record = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def split(serialized, position)
|
11
|
+
first = serialized[0...position]
|
12
|
+
second = serialized[position+1..-1]
|
13
|
+
return first, second
|
14
|
+
end
|
15
|
+
|
16
|
+
def deserialize(document, params={})
|
17
|
+
@record = deserialize_document(document)
|
18
|
+
params.each do |k,v|
|
19
|
+
@record[k] = v
|
20
|
+
end
|
21
|
+
@record
|
22
|
+
end
|
23
|
+
|
24
|
+
def deserialize_document(serialized, document={}, is_map=false)
|
25
|
+
serialized = serialized.strip
|
26
|
+
class_index = serialized.index('@')
|
27
|
+
colon_index = serialized.index(':')
|
28
|
+
if class_index && (!colon_index || colon_index > class_index)
|
29
|
+
document[:@class], serialized = split(serialized, class_index)
|
30
|
+
end
|
31
|
+
document[:@type] = "d" unless is_map
|
32
|
+
|
33
|
+
while (serialized and field_index = serialized.index(':')) do
|
34
|
+
field, serialized = split(serialized, field_index)
|
35
|
+
|
36
|
+
if field[0] == "\"" and field[-1] == "\""
|
37
|
+
field = field[1..-2]
|
38
|
+
end
|
39
|
+
|
40
|
+
comma_index = look_for_comma_index(serialized)
|
41
|
+
value, serialized = split(serialized, comma_index)
|
42
|
+
value = deserialize_field_value(value)
|
43
|
+
document[field.to_sym] = value
|
44
|
+
end
|
45
|
+
document
|
46
|
+
end
|
47
|
+
|
48
|
+
def deserialize_field_value(value)
|
49
|
+
return nil if value.empty?
|
50
|
+
|
51
|
+
if ["true", "false"].include? value
|
52
|
+
return value == "true"
|
53
|
+
end
|
54
|
+
|
55
|
+
first_char = value[0]
|
56
|
+
last_char = value[-1]
|
57
|
+
|
58
|
+
if "\"" == first_char
|
59
|
+
val = value[1..-2]
|
60
|
+
val = val.gsub(/\\"/, "\"")
|
61
|
+
val = val.sub(/\\\\/, "\\")
|
62
|
+
return val
|
63
|
+
end
|
64
|
+
|
65
|
+
# split for date and datetime
|
66
|
+
if ["t", "a"].include? last_char
|
67
|
+
date = DateTime.strptime(value[0..-1],'%s')
|
68
|
+
date = date.to_date if last_char == "a"
|
69
|
+
return date
|
70
|
+
end
|
71
|
+
|
72
|
+
if "(" == first_char
|
73
|
+
return deserialize_document(value[1..-2])
|
74
|
+
end
|
75
|
+
|
76
|
+
if "{" == first_char
|
77
|
+
return deserialize_document(value[1..-2], {}, true)
|
78
|
+
end
|
79
|
+
|
80
|
+
if ["[", "<"].include? first_char
|
81
|
+
ret = [] if first_char == "["
|
82
|
+
ret = Set.new if first_char == "<"
|
83
|
+
|
84
|
+
values = split_values_from(value[1..-2])
|
85
|
+
values.each { |val| ret << deserialize_field_value(val) }
|
86
|
+
return ret
|
87
|
+
end
|
88
|
+
|
89
|
+
if "b" == last_char
|
90
|
+
return value[0..-2].to_i
|
91
|
+
end
|
92
|
+
|
93
|
+
# split for long/short?
|
94
|
+
if ["l", "s"].include? last_char
|
95
|
+
return value[0..-2].to_i
|
96
|
+
end
|
97
|
+
|
98
|
+
if "c" == last_char
|
99
|
+
return BigDecimal.new(value[0..-2].to_i)
|
100
|
+
end
|
101
|
+
|
102
|
+
if ["f", "d"].include? last_char
|
103
|
+
return value[0..-2].to_f
|
104
|
+
end
|
105
|
+
|
106
|
+
return value.to_i if value.to_i.to_s == value
|
107
|
+
|
108
|
+
return value
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def split_values_from(value)
|
114
|
+
result = []
|
115
|
+
while value do
|
116
|
+
comma_at = look_for_comma_index(value)
|
117
|
+
res, value = split(value, comma_at)
|
118
|
+
result << res
|
119
|
+
end
|
120
|
+
result
|
121
|
+
end
|
122
|
+
|
123
|
+
def look_for_comma_index(serialized)
|
124
|
+
delimiters = []
|
125
|
+
(0...serialized.length).each do |idx|
|
126
|
+
current = serialized[idx]
|
127
|
+
if current == "," and delimiters.length == 0
|
128
|
+
return idx
|
129
|
+
elsif start_delimiter?(current) and delimiters[-1] != "\""
|
130
|
+
delimiters << current
|
131
|
+
elsif end_delimiter?(current) and delimiters[-1] != "\"" and current == opposite_delimiter_of(delimiters[-1])
|
132
|
+
delimiters.pop
|
133
|
+
elsif current == "\"" and delimiters[-1] == "\"" and idx > 0 and serialized[idx-1] != "\\"
|
134
|
+
delimiters.pop
|
135
|
+
elsif current == "\"" and delimiters[-1] != "\""
|
136
|
+
delimiters << current
|
137
|
+
end
|
138
|
+
end
|
139
|
+
return serialized.length
|
140
|
+
end
|
141
|
+
|
142
|
+
def start_delimiter?(c)
|
143
|
+
["(", "[", "{", "<"].include? c
|
144
|
+
end
|
145
|
+
|
146
|
+
def end_delimiter?(c)
|
147
|
+
[")", "]", "}", ">"].include? c
|
148
|
+
end
|
149
|
+
|
150
|
+
def opposite_delimiter_of(c)
|
151
|
+
case c
|
152
|
+
when "[" then return "]"
|
153
|
+
when "{" then return "}"
|
154
|
+
when "(" then return ")"
|
155
|
+
when "<" then return ">"
|
156
|
+
else return "\""
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module OrientdbBinary
|
2
|
+
module Parser
|
3
|
+
class Serializer
|
4
|
+
def initialize()
|
5
|
+
end
|
6
|
+
|
7
|
+
def serialize_field_value(value)
|
8
|
+
|
9
|
+
if value.is_a? String
|
10
|
+
val = /^#\-{0,1}[\d]+:\-{0,1}[\d]+$/.match(value)
|
11
|
+
return value if val
|
12
|
+
value = value.sub(/\\/, "\\\\")
|
13
|
+
value = value.gsub(/"/, "\\\"")
|
14
|
+
return "\"#{value}\""
|
15
|
+
end
|
16
|
+
|
17
|
+
if value.is_a? Integer
|
18
|
+
return value.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
if value.is_a? Float
|
22
|
+
return value.to_s + "f"
|
23
|
+
end
|
24
|
+
|
25
|
+
if value.is_a? Bignum
|
26
|
+
return value.to_s + "l"
|
27
|
+
end
|
28
|
+
|
29
|
+
if value.is_a? BigDecimal
|
30
|
+
return value.to_s + "d"
|
31
|
+
end
|
32
|
+
|
33
|
+
if value.is_a? Array or value.is_a? Set
|
34
|
+
type = value.class.to_s.downcase == "set" ? "<$>" : "[$]"
|
35
|
+
result = []
|
36
|
+
|
37
|
+
value.each do |el|
|
38
|
+
result << serialize_field_value(el)
|
39
|
+
end
|
40
|
+
return type.gsub("$", result.join(','))
|
41
|
+
end
|
42
|
+
|
43
|
+
if value.is_a?(TrueClass) or value.is_a?(FalseClass)
|
44
|
+
return value.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
if value.is_a? Hash
|
48
|
+
type = value[:@type] == "d" ? "($)" : "{$}"
|
49
|
+
return type.gsub("$", serialize_document(value, value[:@type] != "d"))
|
50
|
+
end
|
51
|
+
|
52
|
+
if value.is_a? Date
|
53
|
+
value.to_datetime.to_time.to_i + "a"
|
54
|
+
end
|
55
|
+
|
56
|
+
if value.is_a? DateTime
|
57
|
+
value.to_time.to_i + "t"
|
58
|
+
end
|
59
|
+
|
60
|
+
if value.is_a? Time
|
61
|
+
value.to_i + "t"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def serialize_document(document, is_map=false)
|
66
|
+
klass = ""
|
67
|
+
result = []
|
68
|
+
document.each do |key, value|
|
69
|
+
unless [:@version, :@rid, :@type, :@cluster].include? key
|
70
|
+
if key == :@class
|
71
|
+
klass = value
|
72
|
+
else
|
73
|
+
field_wrap = is_map ? "\"" : ""
|
74
|
+
result << "#{key.to_s}:#{serialize_field_value(value)}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
return klass.empty? ? result.join(',') : klass + "@" + result.join(',')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|