vertica 0.7.4 → 0.8.1

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.
Files changed (63) hide show
  1. data/README.md +85 -0
  2. data/Rakefile +56 -38
  3. data/VERSION +1 -0
  4. data/lib/vertica.rb +59 -11
  5. data/lib/vertica/bit_helper.rb +7 -24
  6. data/lib/vertica/column.rb +34 -53
  7. data/lib/vertica/connection.rb +123 -139
  8. data/lib/vertica/core_ext/numeric.rb +13 -0
  9. data/lib/vertica/core_ext/string.rb +22 -0
  10. data/lib/vertica/messages/{authentication.rb → backend_messages/authentication.rb} +6 -9
  11. data/lib/vertica/messages/{backend_key_data.rb → backend_messages/backend_key_data.rb} +2 -2
  12. data/lib/vertica/messages/{bind_complete.rb → backend_messages/bind_complete.rb} +0 -1
  13. data/lib/vertica/messages/{close_complete.rb → backend_messages/close_complete.rb} +0 -1
  14. data/lib/vertica/messages/{command_complete.rb → backend_messages/command_complete.rb} +3 -3
  15. data/lib/vertica/messages/{data_row.rb → backend_messages/data_row.rb} +3 -6
  16. data/lib/vertica/messages/{empty_query_response.rb → backend_messages/empty_query_response.rb} +0 -1
  17. data/lib/vertica/messages/backend_messages/error_response.rb +35 -0
  18. data/lib/vertica/messages/{no_data.rb → backend_messages/no_data.rb} +0 -1
  19. data/lib/vertica/messages/backend_messages/notice_response.rb +16 -0
  20. data/lib/vertica/messages/{notification_response.rb → backend_messages/notification_response.rb} +0 -0
  21. data/lib/vertica/messages/{parameter_description.rb → backend_messages/parameter_description.rb} +0 -0
  22. data/lib/vertica/messages/{parameter_status.rb → backend_messages/parameter_status.rb} +0 -0
  23. data/lib/vertica/messages/{parse_complete.rb → backend_messages/parse_complete.rb} +0 -1
  24. data/lib/vertica/messages/{portal_suspended.rb → backend_messages/portal_suspended.rb} +0 -1
  25. data/lib/vertica/messages/{ready_for_query.rb → backend_messages/ready_for_query.rb} +2 -2
  26. data/lib/vertica/messages/{row_description.rb → backend_messages/row_description.rb} +3 -3
  27. data/lib/vertica/messages/{unknown.rb → backend_messages/unknown.rb} +2 -2
  28. data/lib/vertica/messages/frontend_messages/bind.rb +28 -0
  29. data/lib/vertica/messages/frontend_messages/cancel_request.rb +21 -0
  30. data/lib/vertica/messages/frontend_messages/close.rb +24 -0
  31. data/lib/vertica/messages/frontend_messages/describe.rb +24 -0
  32. data/lib/vertica/messages/frontend_messages/execute.rb +20 -0
  33. data/lib/vertica/messages/frontend_messages/flush.rb +7 -0
  34. data/lib/vertica/messages/frontend_messages/parse.rb +23 -0
  35. data/lib/vertica/messages/frontend_messages/password.rb +35 -0
  36. data/lib/vertica/messages/frontend_messages/query.rb +17 -0
  37. data/lib/vertica/messages/frontend_messages/ssl_request.rb +12 -0
  38. data/lib/vertica/messages/frontend_messages/startup.rb +25 -0
  39. data/lib/vertica/messages/frontend_messages/sync.rb +7 -0
  40. data/lib/vertica/messages/frontend_messages/terminate.rb +7 -0
  41. data/lib/vertica/messages/message.rb +26 -57
  42. data/lib/vertica/result.rb +28 -20
  43. data/lib/vertica/vertica_socket.rb +14 -3
  44. data/test/test_helper.rb +7 -16
  45. metadata +55 -50
  46. data/README.textile +0 -69
  47. data/lib/vertica/messages/bind.rb +0 -36
  48. data/lib/vertica/messages/cancel_request.rb +0 -25
  49. data/lib/vertica/messages/close.rb +0 -30
  50. data/lib/vertica/messages/describe.rb +0 -30
  51. data/lib/vertica/messages/error_response.rb +0 -59
  52. data/lib/vertica/messages/execute.rb +0 -24
  53. data/lib/vertica/messages/flush.rb +0 -15
  54. data/lib/vertica/messages/notice_response.rb +0 -21
  55. data/lib/vertica/messages/parse.rb +0 -31
  56. data/lib/vertica/messages/password.rb +0 -33
  57. data/lib/vertica/messages/query.rb +0 -20
  58. data/lib/vertica/messages/ssl_request.rb +0 -14
  59. data/lib/vertica/messages/startup.rb +0 -38
  60. data/lib/vertica/messages/sync.rb +0 -15
  61. data/lib/vertica/messages/terminate.rb +0 -14
  62. data/test/create_schema.sql +0 -4
  63. data/vertica.gemspec +0 -64
@@ -0,0 +1,13 @@
1
+ class Numeric
2
+ def to_network_int16
3
+ [self].pack('n')
4
+ end
5
+
6
+ def to_network_int32
7
+ [self].pack('N')
8
+ end
9
+
10
+ def to_byte
11
+ [self].pack('C')
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ class String
2
+ def to_cstring
3
+ raise ArgumentError, "Invalid cstring" if self.include?("\000")
4
+ "#{self}\000"
5
+ end
6
+
7
+ def from_cstring
8
+ self[0..-2]
9
+ end
10
+
11
+ def to_byte
12
+ unpack('C').first
13
+ end
14
+
15
+ def to_network_int16
16
+ unpack('n').first
17
+ end
18
+
19
+ def to_network_int32
20
+ unpack('l').first
21
+ end
22
+ end
@@ -12,20 +12,17 @@ module Vertica
12
12
  GSS = 7
13
13
  GSS_CONTINUE = 8
14
14
  SSPI = 9
15
-
15
+
16
16
  attr_reader :code
17
17
  attr_reader :salt
18
18
  attr_reader :auth_data
19
-
19
+
20
20
  def initialize(stream, size)
21
21
  super
22
- @code = stream.read_network_int32
23
- if @code == CRYPT_PASSWORD
24
- @salt = stream.readn(2)
25
- elsif @code == MD5_PASSWORD
26
- @salt = stream.readn(4)
27
- elsif @code == GSS_CONTINUE
28
- @auth_data = stream.readn(size - 9)
22
+ case @code = stream.read_network_int32
23
+ when CRYPT_PASSWORD then @salt = stream.readn(2)
24
+ when MD5_PASSWORD then @salt = stream.readn(4)
25
+ when GSS_CONTINUE then @auth_data = stream.readn(size - 9)
29
26
  end
30
27
  end
31
28
  end
@@ -2,10 +2,10 @@ module Vertica
2
2
  module Messages
3
3
  class BackendKeyData < BackendMessage
4
4
  message_id ?K
5
-
5
+
6
6
  attr_reader :pid
7
7
  attr_reader :key
8
-
8
+
9
9
  def initialize(stream, size)
10
10
  super
11
11
  @pid = stream.read_network_int32
@@ -2,7 +2,6 @@ module Vertica
2
2
  module Messages
3
3
  class BindComplete < BackendMessage
4
4
  message_id ?2
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -2,7 +2,6 @@ module Vertica
2
2
  module Messages
3
3
  class CloseComplete < BackendMessage
4
4
  message_id ?3
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -2,15 +2,15 @@ module Vertica
2
2
  module Messages
3
3
  class CommandComplete < BackendMessage
4
4
  message_id ?C
5
-
5
+
6
6
  attr_reader :tag
7
7
  attr_reader :rows
8
-
8
+
9
9
  def initialize(stream, size)
10
10
  @tag = stream.read_cstring
11
11
  @rows = @tag.split[-1].to_i
12
12
  end
13
-
13
+
14
14
  end
15
15
  end
16
16
  end
@@ -2,20 +2,17 @@ module Vertica
2
2
  module Messages
3
3
  class DataRow < BackendMessage
4
4
  message_id ?D
5
-
5
+
6
6
  attr_reader :field_count
7
7
  attr_reader :fields
8
-
8
+
9
9
  def initialize(stream, size)
10
10
  @fields = []
11
11
 
12
12
  @field_count = stream.read_network_int16
13
13
  @field_count.times do |field_index|
14
14
  size = stream.read_network_int32
15
- @fields << {
16
- :size => size,
17
- :value => size == -1 ? nil : stream.readn(size)
18
- }
15
+ @fields << (size == -1 ? nil : stream.readn(size))
19
16
  end
20
17
  end
21
18
  end
@@ -2,7 +2,6 @@ module Vertica
2
2
  module Messages
3
3
  class EmptyQueryResponse < BackendMessage
4
4
  message_id ?I
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -0,0 +1,35 @@
1
+ module Vertica
2
+ module Messages
3
+ class ErrorResponse < BackendMessage
4
+ message_id ?E
5
+
6
+ ERRORS = {
7
+ ?q => [0, "Internal Query"],
8
+ ?S => [1, "Severity"],
9
+ ?M => [2, "Message"],
10
+ ?C => [3, "Sqlstate"],
11
+ ?D => [4, "Detail"],
12
+ ?H => [5, "Hint"],
13
+ ?P => [6, "Position"],
14
+ ?W => [7, "Where"],
15
+ ?p => [8, "Internal Position"],
16
+ ?R => [10, "Routine"],
17
+ ?F => [11, "File"],
18
+ ?L => [12, "Line"],
19
+ }
20
+
21
+ def initialize(stream, size)
22
+ super
23
+ @errors, type = {}, nil
24
+ @errors[type] = stream.read_cstring while (type = stream.read_byte) != 0
25
+ end
26
+
27
+ def error
28
+ @errors.map { |type, msg| [(ERRORS[type] || [ERRORS.size, type.to_s]), msg].flatten }.
29
+ sort_by { |e| e.first }.
30
+ map { |e| "#{e[1]}: #{e[2]}" }.
31
+ join(', ')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -2,7 +2,6 @@ module Vertica
2
2
  module Messages
3
3
  class NoData < BackendMessage
4
4
  message_id ?n
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -0,0 +1,16 @@
1
+ module Vertica
2
+ module Messages
3
+ class NoticeResponse < BackendMessage
4
+ message_id ?N
5
+
6
+ attr_reader :notices
7
+
8
+ def initialize(stream, size)
9
+ super
10
+ @notices, type = [], nil
11
+ @notices << [type, stream.read_cstring] while (type = stream.read_byte) != 0
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -2,7 +2,6 @@ module Vertica
2
2
  module Messages
3
3
  class ParseComplete < BackendMessage
4
4
  message_id ?1
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -2,7 +2,6 @@ module Vertica
2
2
  module Messages
3
3
  class PortalSuspended < BackendMessage
4
4
  message_id ?s
5
-
6
5
  end
7
6
  end
8
7
  end
@@ -2,9 +2,9 @@ module Vertica
2
2
  module Messages
3
3
  class ReadyForQuery < BackendMessage
4
4
  message_id ?Z
5
-
5
+
6
6
  attr_reader :transaction_status
7
-
7
+
8
8
  def initialize(stream, size)
9
9
  super
10
10
  @transaction_status = stream.read_byte
@@ -2,15 +2,15 @@ module Vertica
2
2
  module Messages
3
3
  class RowDescription < BackendMessage
4
4
  message_id ?T
5
-
5
+
6
6
  attr_reader :field_count
7
7
  attr_reader :fields
8
-
8
+
9
9
  def initialize(stream, size)
10
10
  super
11
11
 
12
12
  @fields = []
13
-
13
+
14
14
  @field_count = stream.read_network_int16
15
15
  @field_count.times do |field_index|
16
16
  @fields << {
@@ -2,8 +2,8 @@ module Vertica
2
2
  module Messages
3
3
  class Unknown < BackendMessage
4
4
  attr_reader :message_id
5
-
6
- def initialize(message_id)
5
+
6
+ def initialize(stream, size)
7
7
  @message_id = message_id
8
8
  end
9
9
  end
@@ -0,0 +1,28 @@
1
+ module Vertica
2
+ module Messages
3
+ class Bind < FrontendMessage
4
+ message_id ?B
5
+
6
+ def initialize(portal_name, prepared_statement_name, parameter_values)
7
+ @portal_name = portal_name
8
+ @prepared_statement_name = prepared_statement_name
9
+ @parameter_values = parameter_values.map(&:to_s)
10
+ end
11
+
12
+ def to_bytes
13
+ bytes = [
14
+ @portal_name.to_cstring, # portal name ("")
15
+ @prepared_statement_name.to_cstring, # prep
16
+ 0.to_network_int16, # format codes (0 - default text format)
17
+ @parameter_values.length.to_network_int16, # number of parameters
18
+ ]
19
+ @parameter_values.each do |parameter_value|
20
+ bytes << parameter_value.length.to_network_int32 # parameter value (which is represented as a string) length
21
+ bytes << parameter_value # parameter value written out in text representation
22
+ end
23
+ message_string bytes
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ module Vertica
2
+ module Messages
3
+ class CancelRequest < FrontendMessage
4
+ message_id nil
5
+
6
+ def initialize(backend_pid, backend_key)
7
+ @backend_pid = backend_pid
8
+ @backend_key = backend_key
9
+ end
10
+
11
+ def to_bytes
12
+ message_string([
13
+ 80877102.to_network_int32,
14
+ @backend_pid.to_network_int32,
15
+ @backend_key.to_network_int32
16
+ ])
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ module Vertica
2
+ module Messages
3
+ class Close < FrontendMessage
4
+ message_id ?C
5
+
6
+ def initialize(close_type, close_name)
7
+ @close_name = close_name
8
+ @close_type = case close_type
9
+ when :portal then ?P
10
+ when :prepared_statement then ?S
11
+ else raise ArgumentError.new("#{close_type} is not a valid close_type. Must be either :portal or :prepared_statement.")
12
+ end
13
+ end
14
+
15
+ def to_bytes
16
+ message_string([
17
+ @close_type.to_byte,
18
+ @close_name.to_cstring
19
+ ])
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Vertica
2
+ module Messages
3
+ class Describe < FrontendMessage
4
+ message_id ?D
5
+
6
+ def initialize(describe_type, describe_name)
7
+ @describe_name = describe_name
8
+ @describe_type = case describe_type
9
+ when :portal then ?P
10
+ when :prepared_statement then ?S
11
+ else raise ArgumentError.new("#{describe_type} is not a valid describe_type. Must be either :portal or :prepared_statement.")
12
+ end
13
+ end
14
+
15
+ def to_bytes
16
+ message_string([
17
+ @describe_type.to_byte,
18
+ @describe_name.to_cstring
19
+ ])
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module Vertica
2
+ module Messages
3
+ class Execute < FrontendMessage
4
+ message_id ?E
5
+
6
+ def initialize(portal_name, max_rows)
7
+ @portal_name = portal_name
8
+ @max_rows = max_rows
9
+ end
10
+
11
+ def to_bytes
12
+ message_string([
13
+ @portal_name.to_cstring,
14
+ @max_rows.to_network_int32
15
+ ])
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module Vertica
2
+ module Messages
3
+ class Flush < FrontendMessage
4
+ message_id ?H
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ module Vertica
2
+ module Messages
3
+ class Parse < FrontendMessage
4
+ message_id ?P
5
+
6
+ def initialize(name, query, param_types)
7
+ @name = name
8
+ @query = query
9
+ @param_types = param_types
10
+ end
11
+
12
+ def to_bytes
13
+ message_string([
14
+ @name.to_cstring,
15
+ @query.to_cstring,
16
+ @param_types.length.to_network_int16,
17
+ @param_types.map { |type| type.to_network_int32 }
18
+ ].flatten)
19
+ end
20
+
21
+ end
22
+ end
23
+ end