downpour 0.0.2 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,24 @@
1
1
  #include "downpour.h"
2
2
 
3
3
  #define SELF_TYPE drizzle_con_st
4
+ #define attr(foo, conversion) static VALUE attr_##foo(VALUE self)\
5
+ {\
6
+ read_self_ptr();\
7
+ return conversion(drizzle_con_##foo(self_ptr));\
8
+ }
9
+ #define settr(foo) static VALUE settr_##foo(VALUE self, VALUE newValue)\
10
+ {\
11
+ read_self_ptr();\
12
+ Check_Type(newValue, T_STRING);\
13
+ drizzle_con_set_##foo(self_ptr, RSTRING_PTR(newValue));\
14
+ return newValue;\
15
+ }
16
+ #define attr_string(foo) attr(foo, rb_str_new2)
17
+ #define prop(foo) attr_string(foo) settr(foo)
18
+
19
+ #define define_attr(foo) rb_define_method(DrizzleConnection, #foo, attr_##foo, 0)
20
+ #define define_settr(foo) rb_define_method(DrizzleConnection, #foo "=", settr_##foo, 1)
21
+ #define define_prop(foo) define_attr(foo); define_settr(foo)
4
22
 
5
23
  static VALUE query(VALUE self, VALUE query)
6
24
  {
@@ -16,15 +34,52 @@ static VALUE query(VALUE self, VALUE query)
16
34
  return downpour_result_constructor(result, self);
17
35
  }
18
36
 
37
+ static VALUE connection_close(VALUE self)
38
+ {
39
+ read_self_ptr();
40
+ drizzle_con_close(self_ptr);
41
+ return Qnil;
42
+ }
43
+
44
+ attr_string(error);
45
+ attr(errno, INT2NUM);
46
+ attr(error_code, UINT2NUM);
47
+ attr_string(sqlstate);
48
+ attr_string(host);
49
+ attr(port, UINT2NUM);
50
+ prop(uds);
51
+ attr_string(user);
52
+ attr_string(password);
53
+ prop(db);
54
+ attr(protocol_version, UINT2NUM);
55
+ attr_string(server_version);
56
+ attr(server_version_number, UINT2NUM);
57
+ attr(thread_id, UINT2NUM);
58
+ attr(max_packet_size, UINT2NUM);
59
+
19
60
  VALUE downpour_connection_constructor(drizzle_con_st *self_ptr, VALUE status)
20
61
  {
21
- VALUE ret = Data_Wrap_Struct(DrizzleConnection, NULL, drizzle_con_free, self_ptr);
22
- rb_iv_set(ret, "@status", status);
23
- return ret;
62
+ return to_ruby_object(self_ptr, DrizzleConnection, status, drizzle_con_free, drizzle_con_set_context);
24
63
  }
25
64
 
26
65
  void init_drizzle_connection()
27
66
  {
28
67
  DrizzleConnection = drizzle_gem_create_class_with_private_constructor("Connection", rb_cObject);
29
68
  rb_define_method(DrizzleConnection, "query", query, 1);
69
+ define_attr(error);
70
+ define_attr(errno);
71
+ define_attr(error_code);
72
+ define_attr(sqlstate);
73
+ define_attr(host);
74
+ define_attr(port);
75
+ define_prop(uds);
76
+ define_attr(user);
77
+ define_attr(password);
78
+ define_prop(db);
79
+ define_attr(protocol_version);
80
+ define_attr(server_version);
81
+ define_attr(server_version_number);
82
+ define_attr(thread_id);
83
+ define_attr(max_packet_size);
84
+ rb_define_method(DrizzleConnection, "close!", connection_close, 0);
30
85
  }
@@ -4,11 +4,13 @@ VALUE DownpourModule;
4
4
  VALUE DrizzleStatus;
5
5
  VALUE DrizzleConnection;
6
6
  VALUE DrizzleResult;
7
+ VALUE DrizzleQuery;
7
8
 
8
9
  void init_downpour_module();
9
10
  void init_drizzle_status();
10
11
  void init_drizzle_connection();
11
12
  void init_drizzle_result();
13
+ void init_drizzle_query();
12
14
 
13
15
  void Init_downpour()
14
16
  {
@@ -16,4 +18,5 @@ void Init_downpour()
16
18
  init_drizzle_status();
17
19
  init_drizzle_connection();
18
20
  init_drizzle_result();
21
+ init_drizzle_query();
19
22
  }
@@ -9,23 +9,32 @@ extern VALUE DownpourModule;
9
9
  extern VALUE DrizzleStatus;
10
10
  extern VALUE DrizzleConnection;
11
11
  extern VALUE DrizzleResult;
12
+ extern VALUE DrizzleQuery;
13
+
14
+ // All mark and release methods
15
+ typedef void (*FREE_METHOD)(void* ptr);
16
+ typedef void (*SET_CONTEXT)(void* ptr, void *context);
17
+ void *downpour_from_ruby_object(VALUE value);
18
+ VALUE downpour_to_ruby_object(void *ptr, VALUE klass, VALUE parent, FREE_METHOD free_method, SET_CONTEXT set_context);
19
+ VALUE downpour_get_ruby_object(void *ptr);
12
20
 
13
21
  // All Constructors
14
22
  VALUE downpour_constructor(drizzle_st *self_ptr);
15
23
  VALUE downpour_connection_constructor(drizzle_con_st *self_ptr, VALUE status);
16
24
  VALUE downpour_result_constructor(drizzle_result_st *self_ptr, VALUE connection);
25
+ VALUE downpour_query_constructor(drizzle_query_st *self_ptr, VALUE connection);
17
26
 
18
27
  VALUE drizzle_gem_create_class_with_private_constructor(const char *name, VALUE super);
19
28
  void drizzle_gem_assert_value_is_ok(drizzle_return_t value);
20
29
  VALUE drizzle_gem_to_string_array(char **array, long count);
21
30
  const char *drizzle_gem_read_string_with_default(VALUE string, const char *default_value);
22
31
 
23
- #define convert_to_struct(datatype, var_name, value) datatype *var_name; Data_Get_Struct(value, datatype, var_name)
32
+ #define convert_to_struct(datatype, var_name, value) datatype *var_name; var_name = downpour_from_ruby_object(value)
24
33
  #define read_self_ptr() convert_to_struct(SELF_TYPE, self_ptr, self)
25
34
  #define CHECK_OK(value) drizzle_gem_assert_value_is_ok(value)
26
35
  #define rb_call(self, string) rb_funcall(self, rb_intern(string), 0)
27
36
  #define read_string(value, default_value) drizzle_gem_read_string_with_default(value, default_value)
28
37
  #define drizzle_alloc(type) ((type *) malloc(sizeof(type)))
29
- #define unset_option(value, bit) if(value->options & bit) value->options ^= bit
38
+ #define to_ruby_object(ptr, klass, parent, free_method, set_context) downpour_to_ruby_object(ptr, klass, parent, (FREE_METHOD) (free_method), (SET_CONTEXT) (set_context))
30
39
 
31
40
  #endif
@@ -0,0 +1,93 @@
1
+ #include "downpour.h"
2
+
3
+ typedef struct DownpourWrapper {
4
+ int reference_count;
5
+ void *ptr;
6
+ struct DownpourWrapper *parent;
7
+ FREE_METHOD free_method;
8
+ VALUE rb_object;
9
+ } DownpourWrapper;
10
+
11
+ static void downpour_mark(DownpourWrapper *wrapper)
12
+ {
13
+ if(wrapper == NULL)
14
+ return;
15
+
16
+ wrapper->reference_count++;
17
+ }
18
+
19
+ static void downpour_release(DownpourWrapper *wrapper)
20
+ {
21
+ if(wrapper == NULL)
22
+ return;
23
+
24
+ wrapper->reference_count--;
25
+
26
+ if(wrapper->reference_count == 0) {
27
+ wrapper->free_method(wrapper->ptr);
28
+ downpour_release(wrapper->parent);
29
+ free(wrapper);
30
+ }
31
+ }
32
+
33
+ static DownpourWrapper *downpour_wrap_pointer(void *ptr, DownpourWrapper *parent, FREE_METHOD free_method)
34
+ {
35
+ DownpourWrapper *wrapper = drizzle_alloc(DownpourWrapper);
36
+ wrapper->ptr = ptr;
37
+ wrapper->parent = parent;
38
+ wrapper->free_method = free_method;
39
+ wrapper->reference_count = 0;
40
+
41
+ downpour_mark(parent);
42
+ downpour_mark(wrapper);
43
+ return wrapper;
44
+ }
45
+
46
+ static void mark_for_ruby_gc(DownpourWrapper *wrapper)
47
+ {
48
+ if(wrapper == NULL)
49
+ return;
50
+
51
+ rb_gc_mark(wrapper->rb_object);
52
+
53
+ mark_for_ruby_gc(wrapper->parent);
54
+ }
55
+
56
+ static DownpourWrapper *get_wrapper_from_object(VALUE value)
57
+ {
58
+ if(value == Qnil)
59
+ return NULL;
60
+
61
+ DownpourWrapper *wrapper = NULL;
62
+ Data_Get_Struct(value, DownpourWrapper, wrapper);
63
+ return wrapper;
64
+ }
65
+
66
+ VALUE downpour_get_ruby_object(void *ptr)
67
+ {
68
+ if(ptr == NULL)
69
+ return Qnil;
70
+
71
+ DownpourWrapper *wrapper = (DownpourWrapper *)ptr;
72
+ return wrapper->rb_object;
73
+ }
74
+
75
+ void *downpour_from_ruby_object(VALUE value)
76
+ {
77
+ DownpourWrapper *wrapper;
78
+ wrapper = get_wrapper_from_object(value);
79
+ return wrapper == NULL? NULL : wrapper->ptr;
80
+ }
81
+
82
+ VALUE downpour_to_ruby_object(void *ptr, VALUE klass, VALUE parent, FREE_METHOD free_method, SET_CONTEXT set_context)
83
+ {
84
+ if(ptr == NULL)
85
+ return Qnil;
86
+
87
+ DownpourWrapper *wrapper = downpour_wrap_pointer(ptr, get_wrapper_from_object(parent), free_method);
88
+
89
+ if(set_context != NULL)
90
+ set_context(ptr, wrapper);
91
+
92
+ return wrapper->rb_object = Data_Wrap_Struct(klass, mark_for_ruby_gc, downpour_release, wrapper);
93
+ }
@@ -8,7 +8,7 @@ static VALUE version(VALUE self)
8
8
  static VALUE create(VALUE self)
9
9
  {
10
10
  drizzle_st *ptr = drizzle_create(NULL);
11
- unset_option(ptr, DRIZZLE_FREE_OBJECTS);
11
+ drizzle_remove_options(ptr, DRIZZLE_FREE_OBJECTS);
12
12
  return downpour_constructor(ptr);
13
13
  }
14
14
 
@@ -0,0 +1,27 @@
1
+ #include "downpour.h"
2
+
3
+ #define SELF_TYPE drizzle_query_st
4
+
5
+ static VALUE get_result(VALUE self)
6
+ {
7
+ read_self_ptr();
8
+
9
+ VALUE cached_result = rb_iv_get(self, "@result");
10
+ if(cached_result != Qnil)
11
+ return cached_result;
12
+
13
+ drizzle_result_st *result = drizzle_query_result(self_ptr);
14
+ VALUE ret = rb_iv_set(self, "@result", downpour_result_constructor(result, rb_iv_get(self, "@connection")));
15
+ return ret;
16
+ }
17
+
18
+ VALUE downpour_query_constructor(drizzle_query_st *self_ptr, VALUE connection)
19
+ {
20
+ return to_ruby_object(self_ptr, DrizzleQuery, connection, drizzle_query_free, drizzle_query_set_context);
21
+ }
22
+
23
+ void init_drizzle_query()
24
+ {
25
+ DrizzleQuery = drizzle_gem_create_class_with_private_constructor("Query", rb_cObject);
26
+ rb_define_method(DrizzleQuery, "result", get_result, 0);
27
+ }
@@ -7,19 +7,15 @@ static uint64_t do_column_count(drizzle_result_st *self_ptr)
7
7
  return drizzle_result_column_count(self_ptr);
8
8
  }
9
9
 
10
- static VALUE is_buffered(VALUE self)
10
+ static bool is_buffered_bool(VALUE self)
11
11
  {
12
- VALUE buffered = rb_iv_get(self, "@buffered");
13
-
14
- if(buffered == Qnil || buffered == Qfalse)
15
- return Qfalse;
16
-
17
- return buffered;
12
+ read_self_ptr();
13
+ return self_ptr->options & (DRIZZLE_RESULT_BUFFER_ROW);
18
14
  }
19
15
 
20
- static bool is_buffered_bool(VALUE self)
16
+ static VALUE is_buffered(VALUE self)
21
17
  {
22
- return RTEST(rb_call(self, "buffered?"));
18
+ return is_buffered_bool(self) ? Qtrue : Qfalse;
23
19
  }
24
20
 
25
21
  static VALUE buffer_if_needed(VALUE self)
@@ -31,7 +27,6 @@ static VALUE buffer_if_needed(VALUE self)
31
27
  return Qfalse;
32
28
 
33
29
  CHECK_OK(drizzle_result_buffer(self_ptr));
34
- rb_iv_set(self, "@buffered", Qtrue);
35
30
  return Qtrue;
36
31
  }
37
32
 
@@ -105,11 +100,15 @@ static VALUE insert_id(VALUE self)
105
100
  return UINT2NUM(drizzle_result_insert_id(self_ptr));
106
101
  }
107
102
 
103
+ static VALUE error_code(VALUE self)
104
+ {
105
+ read_self_ptr();
106
+ return UINT2NUM(drizzle_result_error_code(self_ptr));
107
+ }
108
+
108
109
  VALUE downpour_result_constructor(drizzle_result_st *self_ptr, VALUE connection)
109
110
  {
110
- VALUE ret = Data_Wrap_Struct(DrizzleResult, NULL, drizzle_result_free, self_ptr);
111
- rb_iv_set(ret, "@connection", connection);
112
- return ret;
111
+ return to_ruby_object(self_ptr, DrizzleResult, connection, drizzle_result_free, NULL);
113
112
  }
114
113
 
115
114
  void init_drizzle_result()
@@ -121,4 +120,5 @@ void init_drizzle_result()
121
120
  rb_define_method(DrizzleResult, "buffered?", is_buffered, 0);
122
121
  rb_define_method(DrizzleResult, "next_row", next_row, 0);
123
122
  rb_define_method(DrizzleResult, "insert_id", insert_id, 0);
123
+ rb_define_method(DrizzleResult, "error_code", error_code, 0);
124
124
  }
@@ -60,9 +60,41 @@ static VALUE verbose_name(VALUE self)
60
60
  return rb_str_new2(drizzle_verbose_name(drizzle_verbose(self_ptr)));
61
61
  }
62
62
 
63
+ static VALUE add_query(VALUE self, VALUE connection, VALUE query)
64
+ {
65
+ read_self_ptr();
66
+ convert_to_struct(drizzle_con_st, connection_ptr, connection);
67
+ Check_Type(query, T_STRING);
68
+
69
+ drizzle_query_st *query_ptr = drizzle_query_add(self_ptr, NULL, connection_ptr, NULL,
70
+ RSTRING_PTR(query), RSTRING_LEN(query), 0, NULL);
71
+
72
+ return downpour_query_constructor(query_ptr, connection);
73
+ }
74
+
75
+ static VALUE run_all(VALUE self)
76
+ {
77
+ read_self_ptr();
78
+ CHECK_OK(drizzle_query_run_all(self_ptr));
79
+ return Qnil;
80
+ }
81
+
82
+ static VALUE run_one(VALUE self)
83
+ {
84
+ read_self_ptr();
85
+ drizzle_return_t ret;
86
+ drizzle_query_st *query = drizzle_query_run(self_ptr, &ret);
87
+ CHECK_OK(ret);
88
+
89
+ if(query == NULL)
90
+ return Qnil;
91
+
92
+ return downpour_get_ruby_object(drizzle_query_context(query));
93
+ }
94
+
63
95
  VALUE downpour_constructor(drizzle_st *self_ptr)
64
96
  {
65
- return Data_Wrap_Struct(DrizzleStatus, NULL, drizzle_free, self_ptr);
97
+ return to_ruby_object(self_ptr, DrizzleStatus, Qnil, drizzle_free, drizzle_set_context);
66
98
  }
67
99
 
68
100
  void init_drizzle_status()
@@ -73,4 +105,7 @@ void init_drizzle_status()
73
105
  rb_define_method(DrizzleStatus, "verbose=", set_verbose, 1);
74
106
  rb_define_method(DrizzleStatus, "verbose", get_verbose, 0);
75
107
  rb_define_method(DrizzleStatus, "verbose_name", verbose_name, 0);
108
+ rb_define_method(DrizzleStatus, "add_query", add_query, 2);
109
+ rb_define_method(DrizzleStatus, "run_all!", run_all, 0);
110
+ rb_define_method(DrizzleStatus, "run!", run_one, 0);
76
111
  }
@@ -1,3 +1,3 @@
1
1
  module Downpour
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,31 @@
1
+ describe "a concurrent query" do
2
+
3
+ before(:each) do
4
+ @status = Downpour.create
5
+ @conn = create_connection(@status)
6
+ @conn2 = create_connection(@status)
7
+ @query1 = @status.add_query(@conn, "select * from Test1 where name like '%oo'");
8
+ @query2 = @status.add_query(@conn2, "select name from Test1 where name like '%ar'");
9
+ end
10
+
11
+ it "should buffer all queries" do
12
+ @status.run_all!
13
+ @query1.result.should be_buffered
14
+ @query2.result.should be_buffered
15
+ end
16
+
17
+ it "should run all queries" do
18
+ @status.run_all!
19
+ @query1.result.next_row.should == ["foo"]
20
+ @query2.result.next_row.should == ["bar"]
21
+ end
22
+
23
+ it "should run a query" do
24
+ rows = []
25
+ rows << @status.run!.result.next_row
26
+ rows << @status.run!.result.next_row
27
+ rows.should include(["foo"])
28
+ rows.should include(["bar"])
29
+ @status.run!.should be_nil
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ describe "Downpour connections" do
2
+
3
+ before(:each) do
4
+ @status = Downpour.create
5
+ @user = ENV["USER"]
6
+ @password = ""
7
+ @database = "test"
8
+ end
9
+
10
+ shared_examples_for "a working downpour connection" do
11
+ it "should count records" do
12
+ results = @connection.query "select * from Test1"
13
+ results.row_count.should == 3
14
+ end
15
+
16
+ it "should read a row" do
17
+ results = @connection.query "select * from Test1"
18
+ results.next_row.should == ["foo"]
19
+ end
20
+
21
+ it "should be used concurrently" do
22
+ query = @status.add_query(@connection, "select * from Test1")
23
+ @status.run_all!
24
+ query.result.next_row.should == ["foo"]
25
+ end
26
+ end
27
+
28
+ context "over drizzle tcp protocol" do
29
+ before(:each) do
30
+ @connection = @status.add_tcp_connection('localhost', @user, @password, @database)
31
+ end
32
+
33
+ it_should_behave_like "a working downpour connection"
34
+ end
35
+ end
@@ -0,0 +1,41 @@
1
+ describe Downpour do
2
+ before(:each) do
3
+ @status = Downpour.create
4
+ @connection = create_connection(@status)
5
+ end
6
+
7
+ context "error handling" do
8
+
9
+ it "should catch errors" do
10
+ begin
11
+ query = @connection.query "this is invalid sql"
12
+ raise "should have failed here"
13
+ rescue IOError
14
+ @status.error.should == "You have an error in your SQL syntax; check the manual that corresponds to your Drizzle server version for the right syntax to use near 'this is invalid sql' at line 1"
15
+ end
16
+ end
17
+
18
+ it "should only accept a string as query" do
19
+ lambda {@connection.query 42}.should raise_error(TypeError)
20
+ end
21
+ end
22
+
23
+ context "simple attributes" do
24
+ it "should change the database" do
25
+ @connection.db.should == "test"
26
+ @connection.db = "blah"
27
+ @connection.db.should == "blah"
28
+ end
29
+
30
+ it "should read simple attributes" do
31
+ @connection.port.should == 4427
32
+ @connection.user.should == ENV["USER"]
33
+ @connection.password.should == ""
34
+ end
35
+ end
36
+
37
+ it "should close the connection" do
38
+ @connection.close!
39
+ # TODO: Find a way to assert on this
40
+ end
41
+ end
@@ -1,4 +1,4 @@
1
- describe "insert query" do
1
+ describe "an insert query" do
2
2
 
3
3
  def count_of_test2
4
4
  @conn.query("select * from Test2").row_count
@@ -1,4 +1,4 @@
1
- describe "select query" do
1
+ describe "a select query" do
2
2
 
3
3
  before(:each) do
4
4
  @status = Downpour.create
@@ -22,15 +22,6 @@ describe "select query" do
22
22
  @results.buffer!.should be_false
23
23
  end
24
24
 
25
- it "should count columns" do
26
- @results.column_count.should == 1
27
- end
28
-
29
- it "should not buffer when reading a single row" do
30
- @results.next_row
31
- @results.should_not be_buffered
32
- end
33
-
34
25
  shared_examples_for "a read query" do
35
26
  it "should read all rows" do
36
27
  @results.next_row.should == ["foo"]
@@ -38,10 +29,16 @@ describe "select query" do
38
29
  @results.next_row.should == ["baz"]
39
30
  @results.next_row.should be_nil
40
31
  end
32
+
33
+ it "should count columns" do
34
+ @results.column_count.should == 1
35
+ end
41
36
  end
42
37
 
43
38
  context "without buffering" do
44
39
  it_should_behave_like "a read query"
40
+
41
+ after(:each) {@results.should_not be_buffered}
45
42
  end
46
43
 
47
44
  context "with buffering" do
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: downpour
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tejas Dinkar
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-30 00:00:00 +05:30
13
+ date: 2011-06-02 00:00:00 +05:30
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -50,15 +50,19 @@ files:
50
50
  - ext/downpour/downpour.h
51
51
  - ext/downpour/extconf.rb
52
52
  - ext/downpour/helpers.c
53
+ - ext/downpour/memory_allocation.c
53
54
  - ext/downpour/module.c
55
+ - ext/downpour/query.c
54
56
  - ext/downpour/result.c
55
57
  - ext/downpour/status.c
56
58
  - lib/downpour.rb
57
59
  - lib/downpour/version.rb
58
60
  - spec/bootstrap.sql
61
+ - spec/downpour/concurrent_spec.rb
62
+ - spec/downpour/connect_type_spec.rb
63
+ - spec/downpour/connection_spec.rb
59
64
  - spec/downpour/insert_spec.rb
60
65
  - spec/downpour/module_spec.rb
61
- - spec/downpour/query_spec.rb
62
66
  - spec/downpour/select_spec.rb
63
67
  - spec/spec_helper.rb
64
68
  - README.rdoc
@@ -93,8 +97,10 @@ specification_version: 3
93
97
  summary: A simple, fast Mysql and Drizzle library for Ruby, binding to libdrizzle
94
98
  test_files:
95
99
  - spec/bootstrap.sql
100
+ - spec/downpour/concurrent_spec.rb
101
+ - spec/downpour/connect_type_spec.rb
102
+ - spec/downpour/connection_spec.rb
96
103
  - spec/downpour/insert_spec.rb
97
104
  - spec/downpour/module_spec.rb
98
- - spec/downpour/query_spec.rb
99
105
  - spec/downpour/select_spec.rb
100
106
  - spec/spec_helper.rb
@@ -1,27 +0,0 @@
1
- describe Downpour do
2
- before(:each) do
3
- @status = Downpour.create
4
- @connection = create_connection(@status)
5
- end
6
-
7
- context "error handling" do
8
-
9
- it "should be able to catch errors" do
10
- begin
11
- query = @connection.query "this is invalid sql"
12
- raise "should have failed here"
13
- rescue IOError
14
- @status.error.should == "You have an error in your SQL syntax; check the manual that corresponds to your Drizzle server version for the right syntax to use near 'this is invalid sql' at line 1"
15
- end
16
- end
17
-
18
- it "should only accept a string as query" do
19
- begin
20
- @connection.query 42
21
- raise "should have failed here"
22
- rescue TypeError
23
- end
24
- end
25
-
26
- end
27
- end