monetdb 0.2.3 → 0.2.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.
- checksums.yaml +8 -8
- data/CHANGELOG.rdoc +4 -0
- data/VERSION +1 -1
- data/lib/monetdb/connection.rb +11 -3
- data/lib/monetdb/connection/query.rb +18 -74
- data/lib/monetdb/connection/query/table.rb +86 -0
- data/lib/monetdb/version.rb +1 -1
- data/test/test_helper/simple_connection.rb +7 -0
- data/test/unit/connection/test_query.rb +1 -1
- data/test/unit/test_connection.rb +65 -10
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Mjg1NWNmZjNmOWY2M2M5OWIwZDcxY2Y0ODA3ODBmNDc0MzgyYWFiMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OWIxYTQzZTYyYTQzZmYzZWZkNjE5NWFmNDllNDcyZjgwNDk1MzZlMw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTk1ODNlMDViZDVlZWE5MDRlNmEzOTc3Y2MyNjE0MWFjYWUyNjJhM2ZlYzJm
|
10
|
+
ODZiNjNlMTViZjg5MzFkMTgxMDJjMWU5YmJhNGVhM2Y3OWE3MjJhMzMyZWI3
|
11
|
+
YmYzNThkMzgxOTUxZTE4OTAzZWNhM2RlNDA2MmYzZDIzMjAwODU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YWZlZjUyYjhiODEyZjdiMjBmMzkxNzk4NmMxZmRkMDVmNDU0Mzg0N2Q1ODRj
|
14
|
+
NDdiZDVmYzA1ZGI0MjkxMjhhOTc4YzFiMDU4MTM3ZjQzNzkwZDMwNjQxMDlk
|
15
|
+
MTU1NmVlMmViMDQwOGFkZmRkNDBkZWU1NzcxODViOWUyNmJjZDc=
|
data/CHANGELOG.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.4
|
data/lib/monetdb/connection.rb
CHANGED
@@ -63,13 +63,21 @@ module MonetDB
|
|
63
63
|
true
|
64
64
|
end
|
65
65
|
|
66
|
+
def disconnect
|
67
|
+
socket.disconnect if connected?
|
68
|
+
@socket = nil
|
69
|
+
end
|
70
|
+
|
66
71
|
def connected?
|
67
72
|
!socket.nil?
|
68
73
|
end
|
69
74
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
75
|
+
def reconnect?
|
76
|
+
!!config[:reconnect]
|
77
|
+
end
|
78
|
+
|
79
|
+
def check_connectivity!
|
80
|
+
connect if reconnect? && !connected?
|
73
81
|
end
|
74
82
|
|
75
83
|
private
|
@@ -1,8 +1,15 @@
|
|
1
|
+
require "monetdb/connection/query/table"
|
2
|
+
|
1
3
|
module MonetDB
|
2
4
|
class Connection
|
3
5
|
module Query
|
4
6
|
|
7
|
+
def self.included(base)
|
8
|
+
base.send :include, Table
|
9
|
+
end
|
10
|
+
|
5
11
|
def query(statement)
|
12
|
+
check_connectivity!
|
6
13
|
raise ConnectionError, "Not connected to server" unless connected?
|
7
14
|
|
8
15
|
start = Time.now
|
@@ -11,19 +18,7 @@ module MonetDB
|
|
11
18
|
response = read.split("\n")
|
12
19
|
|
13
20
|
log :info, "\n [1m[35mSQL (#{((Time.now - start) * 1000).round(1)}ms)[0m #{statement}[0m"
|
14
|
-
|
15
|
-
query_header, table_header = extract_headers!(response)
|
16
|
-
|
17
|
-
if query_header[:type] == Q_TABLE
|
18
|
-
unless query_header[:rows] == response.size
|
19
|
-
raise QueryError, "Amount of fetched rows does not match header value (#{response.size} instead of #{query_header[:rows]})"
|
20
|
-
end
|
21
|
-
response = parse_rows(query_header, table_header, response.join("\n"))
|
22
|
-
else
|
23
|
-
response = true
|
24
|
-
end
|
25
|
-
|
26
|
-
response
|
21
|
+
parse_response response
|
27
22
|
end
|
28
23
|
|
29
24
|
alias :select_rows :query
|
@@ -39,6 +34,15 @@ module MonetDB
|
|
39
34
|
|
40
35
|
private
|
41
36
|
|
37
|
+
def parse_response(response)
|
38
|
+
query_header, table_header = extract_headers!(response)
|
39
|
+
if query_header[:type] == Q_TABLE
|
40
|
+
parse_table_response query_header, table_header, response
|
41
|
+
else
|
42
|
+
true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
42
46
|
def extract_headers!(response)
|
43
47
|
[parse_query_header!(response), parse_scheme_header!(response)]
|
44
48
|
end
|
@@ -49,6 +53,7 @@ module MonetDB
|
|
49
53
|
raise QueryError, header if header[0].chr == MSG_ERROR
|
50
54
|
|
51
55
|
unless header[0].chr == MSG_QUERY
|
56
|
+
ENV["MONETDB_QUERY_RESPONSE"] = ([header] + response).join("\n").inspect
|
52
57
|
raise QueryError, "Expected an query header (#{MSG_QUERY}) but got (#{header[0].chr})"
|
53
58
|
end
|
54
59
|
|
@@ -87,67 +92,6 @@ module MonetDB
|
|
87
92
|
{:table_name => table_name, :column_names => column_names, :column_types => column_types, :column_lengths => column_lengths}.freeze
|
88
93
|
end
|
89
94
|
|
90
|
-
def parse_rows(query_header, table_header, response)
|
91
|
-
start = Time.now
|
92
|
-
column_types = table_header[:column_types]
|
93
|
-
|
94
|
-
response.slice(0..-3).split("\t]\n").collect do |row|
|
95
|
-
parsed, values = [], row.slice(1..-1).split(",\t")
|
96
|
-
values.each_with_index do |value, index|
|
97
|
-
parsed << parse_value(column_types[index], value.strip)
|
98
|
-
end
|
99
|
-
parsed
|
100
|
-
end.tap do
|
101
|
-
log :info, " [1m[36mRUBY (#{((Time.now - start) * 1000).round(1)}ms)[0m [ Rows: #{query_header[:rows]}, Bytesize: #{response.bytesize} bytes ][0m"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def parse_value(type, value)
|
106
|
-
unless value == "NULL"
|
107
|
-
case type
|
108
|
-
when :varchar, :text
|
109
|
-
parse_string_value value
|
110
|
-
when :int, :smallint, :bigint
|
111
|
-
parse_integer_value value
|
112
|
-
when :double, :float, :real
|
113
|
-
parse_float_value value
|
114
|
-
when :date
|
115
|
-
parse_date_value value
|
116
|
-
when :timestamp
|
117
|
-
parse_date_time_value value
|
118
|
-
when :tinyint
|
119
|
-
parse_boolean_value value
|
120
|
-
else
|
121
|
-
raise NotImplementedError, "Cannot parse value of type #{type.inspect}"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def parse_string_value(value)
|
127
|
-
value.slice(1..-2).force_encoding("UTF-8")
|
128
|
-
end
|
129
|
-
|
130
|
-
def parse_integer_value(value)
|
131
|
-
value.to_i
|
132
|
-
end
|
133
|
-
|
134
|
-
def parse_float_value(value)
|
135
|
-
value.to_f
|
136
|
-
end
|
137
|
-
|
138
|
-
def parse_date_value(value)
|
139
|
-
Date.new *value.split("-").collect(&:to_i)
|
140
|
-
end
|
141
|
-
|
142
|
-
def parse_date_time_value(value)
|
143
|
-
date, time = value.split(" ")
|
144
|
-
Time.new *(date.split("-") + time.split(":")).collect(&:to_i)
|
145
|
-
end
|
146
|
-
|
147
|
-
def parse_boolean_value(value)
|
148
|
-
value == "1"
|
149
|
-
end
|
150
|
-
|
151
95
|
end
|
152
96
|
end
|
153
97
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module MonetDB
|
2
|
+
class Connection
|
3
|
+
module Query
|
4
|
+
module Table
|
5
|
+
|
6
|
+
def parse_table_response(query_header, table_header, response)
|
7
|
+
unless query_header[:rows] == response.size
|
8
|
+
disconnect if reconnect?
|
9
|
+
raise QueryError, "Amount of fetched rows does not match header value (#{response.size} instead of #{query_header[:rows]})"
|
10
|
+
end
|
11
|
+
parse_table_rows query_header, table_header, response.join("\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_table_rows(query_header, table_header, response)
|
15
|
+
start = Time.now
|
16
|
+
rows = response.slice(0..-3).split("\t]\n")
|
17
|
+
parse_rows(table_header, rows).tap do
|
18
|
+
log :info, " [1m[36mRUBY (#{((Time.now - start) * 1000).round(1)}ms)[0m [ Rows: #{query_header[:rows]}, Bytesize: #{response.bytesize} bytes ][0m"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_rows(table_header, rows)
|
23
|
+
column_types = table_header[:column_types]
|
24
|
+
rows.collect do |row|
|
25
|
+
parse_row column_types, row
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse_row(column_types, row)
|
30
|
+
[].tap do |parsed|
|
31
|
+
row.slice(1..-1).split(",\t").each_with_index do |value, index|
|
32
|
+
parsed << parse_value(column_types[index], value.strip)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_value(type, value)
|
38
|
+
unless value == "NULL"
|
39
|
+
case type
|
40
|
+
when :varchar, :text
|
41
|
+
parse_string_value value
|
42
|
+
when :int, :smallint, :bigint
|
43
|
+
parse_integer_value value
|
44
|
+
when :double, :float, :real
|
45
|
+
parse_float_value value
|
46
|
+
when :date
|
47
|
+
parse_date_value value
|
48
|
+
when :timestamp
|
49
|
+
parse_date_time_value value
|
50
|
+
when :tinyint
|
51
|
+
parse_boolean_value value
|
52
|
+
else
|
53
|
+
raise NotImplementedError, "Cannot parse value of type #{type.inspect}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_string_value(value)
|
59
|
+
value.slice(1..-2).force_encoding("UTF-8")
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_integer_value(value)
|
63
|
+
value.to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_float_value(value)
|
67
|
+
value.to_f
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_date_value(value)
|
71
|
+
Date.new *value.split("-").collect(&:to_i)
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse_date_time_value(value)
|
75
|
+
date, time = value.split(" ")
|
76
|
+
Time.new *(date.split("-") + time.split(":")).collect(&:to_i)
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_boolean_value(value)
|
80
|
+
value == "1"
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/monetdb/version.rb
CHANGED
@@ -280,7 +280,7 @@ module Unit
|
|
280
280
|
assert_equal [
|
281
281
|
["Paul Engel", Date.parse("1982-08-01"), 1709.34],
|
282
282
|
["Ken Adams", Date.parse("1980-10-31"), 2003.47]
|
283
|
-
], @connection.send(:
|
283
|
+
], @connection.send(:parse_table_rows, query_header, table_header, response)
|
284
284
|
end
|
285
285
|
end
|
286
286
|
|
@@ -45,16 +45,6 @@ module Unit
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
describe "#connected?" do
|
49
|
-
it "returns whether it has an active socket" do
|
50
|
-
assert_equal false, @connection.connected?
|
51
|
-
@connection.instance_variable_set :@socket, mock
|
52
|
-
assert_equal true, @connection.connected?
|
53
|
-
@connection.instance_variable_set :@socket, nil
|
54
|
-
assert_equal false, @connection.connected?
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
48
|
describe "#disconnect" do
|
59
49
|
describe "when disconnected" do
|
60
50
|
it "does nothing" do
|
@@ -79,6 +69,71 @@ module Unit
|
|
79
69
|
end
|
80
70
|
end
|
81
71
|
|
72
|
+
describe "#connected?" do
|
73
|
+
it "returns whether it has an active socket" do
|
74
|
+
assert_equal false, @connection.connected?
|
75
|
+
@connection.instance_variable_set :@socket, mock
|
76
|
+
assert_equal true, @connection.connected?
|
77
|
+
@connection.instance_variable_set :@socket, nil
|
78
|
+
assert_equal false, @connection.connected?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#reconnect?" do
|
83
|
+
describe "at default" do
|
84
|
+
it "returns false" do
|
85
|
+
assert_equal false, @connection.reconnect?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "when configured to true" do
|
90
|
+
it "returns true" do
|
91
|
+
@connection.instance_variable_get(:@config)[:reconnect] = true
|
92
|
+
assert_equal true, @connection.reconnect?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#check_connectivity!" do
|
98
|
+
describe "when configured reconnect: true" do
|
99
|
+
before do
|
100
|
+
@connection.expects(:reconnect?).returns(true)
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "when disconnected" do
|
104
|
+
it "connects" do
|
105
|
+
@connection.expects(:connected?).returns(false)
|
106
|
+
@connection.expects(:connect)
|
107
|
+
@connection.check_connectivity!
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "when connected" do
|
112
|
+
it "does nothing" do
|
113
|
+
@connection.expects(:connected?).returns(true)
|
114
|
+
@connection.expects(:connect).never
|
115
|
+
@connection.check_connectivity!
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "when not configured reconnect: true" do
|
121
|
+
describe "when disconnected" do
|
122
|
+
it "does nothing" do
|
123
|
+
@connection.expects(:connect).never
|
124
|
+
@connection.check_connectivity!
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "when connected" do
|
129
|
+
it "does nothing" do
|
130
|
+
@connection.expects(:connect).never
|
131
|
+
@connection.check_connectivity!
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
82
137
|
describe "#socket" do
|
83
138
|
it "returns its instance variable :@socket" do
|
84
139
|
@connection.instance_variable_set :@socket, (socket = mock)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monetdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Engel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/monetdb/connection/logger.rb
|
116
116
|
- lib/monetdb/connection/messages.rb
|
117
117
|
- lib/monetdb/connection/query.rb
|
118
|
+
- lib/monetdb/connection/query/table.rb
|
118
119
|
- lib/monetdb/connection/setup.rb
|
119
120
|
- lib/monetdb/error.rb
|
120
121
|
- lib/monetdb/version.rb
|