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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWIxMjU2MTVlNWE5OGI2NmM5OTM5MjljZWVkNTQ2NzViOTUxMDAyOA==
4
+ Mjg1NWNmZjNmOWY2M2M5OWIwZDcxY2Y0ODA3ODBmNDc0MzgyYWFiMA==
5
5
  data.tar.gz: !binary |-
6
- ZmU2YTQ4ZDhkOTk0NGVlMDY0ZTg4ODU4NjA5MThhM2U1YTc1ZjNmZQ==
6
+ OWIxYTQzZTYyYTQzZmYzZWZkNjE5NWFmNDllNDcyZjgwNDk1MzZlMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NjJmYzAxZGQ1MmY0ZDk4OWU3MzViNzYyYTNhMTVmYjhiZWEyZWM2YjZlMmYw
10
- YWVhOTA5NWM1YWNlZmM3NTc5ZDJhNjQ1MDU4NWJlZTQyYTIwZWEyNzcxNjM4
11
- N2VlZTc2ZGY4OGM4N2Y2MjBiYjZiYmFhYzU3Y2JiMzIxNTU2ZmU=
9
+ YTk1ODNlMDViZDVlZWE5MDRlNmEzOTc3Y2MyNjE0MWFjYWUyNjJhM2ZlYzJm
10
+ ODZiNjNlMTViZjg5MzFkMTgxMDJjMWU5YmJhNGVhM2Y3OWE3MjJhMzMyZWI3
11
+ YmYzNThkMzgxOTUxZTE4OTAzZWNhM2RlNDA2MmYzZDIzMjAwODU=
12
12
  data.tar.gz: !binary |-
13
- NDM2MWJlNjg0NTkzNTY5ZjhmNTdhM2E0M2I4MjIzZDYyZjMwMjdjN2VhMmY3
14
- OGU1MzQ0YWE2NzczNjhjODAyOTI3MTgyZTExYTc5Yzg1OGEwOGNlN2JkY2Y1
15
- NGI2YTg3MjUxYjkxYWFmMWVmNmIyYjY3ZmVmNzE0YzhlMDI1MGU=
13
+ YWZlZjUyYjhiODEyZjdiMjBmMzkxNzk4NmMxZmRkMDVmNDU0Mzg0N2Q1ODRj
14
+ NDdiZDVmYzA1ZGI0MjkxMjhhOTc4YzFiMDU4MTM3ZjQzNzkwZDMwNjQxMDlk
15
+ MTU1NmVlMmViMDQwOGFkZmRkNDBkZWU1NzcxODViOWUyNmJjZDc=
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,9 @@
1
1
  = MonetDB CHANGELOG
2
2
 
3
+ == Version 0.2.4 (October 29, 2014)
4
+
5
+ * Being able to reconnect after getting invalid query header error
6
+
3
7
  == Version 0.2.3 (October 22, 2014)
4
8
 
5
9
  * Dropped activesupport dependency
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 0.2.4
@@ -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 disconnect
71
- socket.disconnect if connected?
72
- @socket = nil
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 SQL (#{((Time.now - start) * 1000).round(1)}ms) #{statement}"
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, " RUBY (#{((Time.now - start) * 1000).round(1)}ms) [ Rows: #{query_header[:rows]}, Bytesize: #{response.bytesize} bytes ]"
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, " RUBY (#{((Time.now - start) * 1000).round(1)}ms) [ Rows: #{query_header[:rows]}, Bytesize: #{response.bytesize} bytes ]"
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
@@ -1,7 +1,7 @@
1
1
  module MonetDB
2
2
  MAJOR = 0
3
3
  MINOR = 2
4
- TINY = 3
4
+ TINY = 4
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join(".")
7
7
  end
@@ -14,6 +14,13 @@ class SimpleConnection
14
14
  !@socket.nil?
15
15
  end
16
16
 
17
+ def reconnect?
18
+ false
19
+ end
20
+
21
+ def check_connectivity!
22
+ end
23
+
17
24
  private
18
25
 
19
26
  def socket
@@ -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(:parse_rows, query_header, table_header, response)
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.3
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-22 00:00:00.000000000 Z
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