downpour 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,9 @@
1
+ = Downpour 0.0.1
2
+
3
+ Downpour is a gem to connect and query a Drizzle or MySql database using the libdrizzle library.
4
+
5
+ == Test setup
6
+ Run the following:
7
+ $ echo "create database test;" | drizzle
8
+ $ drizzle test < spec/bootstrap.sql
9
+ $ rake
data/downpour.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ require File.expand_path('../lib/downpour/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{downpour}
5
+ s.version = Downpour::VERSION
6
+ s.authors = ["Tejas Dinkar"]
7
+ s.date = Time.now.utc.strftime("%Y-%m-%d")
8
+ s.email = %q{tejas@gja.in}
9
+ s.extensions = ["ext/downpour/extconf.rb"]
10
+ s.extra_rdoc_files = [
11
+ "README.rdoc"
12
+ ]
13
+ s.files = `git ls-files ext lib downpour.gemspec`.split("\n")
14
+ s.homepage = %q{http://github.com/gja/downpour}
15
+ s.rdoc_options = ["--charset=UTF-8"]
16
+ s.require_paths = ["lib", "ext"]
17
+ s.rubygems_version = %q{1.4.2}
18
+ s.summary = %q{A simple, fast Mysql and Drizzle library for Ruby, binding to libdrizzle}
19
+ s.description = %q{A simple, fast Mysql and Drizzle library for Ruby, binding to libdrizzle. Still in early alpha}
20
+ s.test_files = `git ls-files spec examples`.split("\n")
21
+
22
+ # tests
23
+ s.add_development_dependency 'rake-compiler', "~> 0.7.1"
24
+ s.add_development_dependency 'rspec'
25
+ end
@@ -0,0 +1,23 @@
1
+ #include "drizzle.h"
2
+
3
+ #define SELF_TYPE drizzle_con_st
4
+
5
+ static VALUE query(VALUE self, VALUE query)
6
+ {
7
+ read_self_ptr();
8
+
9
+ Check_Type(query, T_STRING);
10
+
11
+ drizzle_return_t retptr;
12
+ drizzle_result_st *result = drizzle_query(self_ptr, NULL, RSTRING_PTR(query), RSTRING_LEN(query), &retptr);
13
+
14
+ CHECK_OK(retptr);
15
+
16
+ return Data_Wrap_Struct(DrizzleResult, NULL, NULL, result);
17
+ }
18
+
19
+ void init_drizzle_connection()
20
+ {
21
+ DrizzleConnection = drizzle_gem_create_class_with_private_constructor("Connection", rb_cObject);
22
+ rb_define_method(DrizzleConnection, "query", query, 1);
23
+ }
@@ -0,0 +1,19 @@
1
+ #include "drizzle.h"
2
+
3
+ VALUE DrizzleModule;
4
+ VALUE DrizzleStatus;
5
+ VALUE DrizzleConnection;
6
+ VALUE DrizzleResult;
7
+
8
+ void init_drizzle_module();
9
+ void init_drizzle_status();
10
+ void init_drizzle_connection();
11
+ void init_drizzle_result();
12
+
13
+ void Init_downpour()
14
+ {
15
+ init_drizzle_module();
16
+ init_drizzle_status();
17
+ init_drizzle_connection();
18
+ init_drizzle_result();
19
+ }
@@ -0,0 +1,24 @@
1
+ #ifndef DRIZZLE_H
2
+ #define DRIZZLE_H
3
+
4
+ #include "ruby.h"
5
+ #include <libdrizzle/drizzle.h>
6
+ #include <libdrizzle/drizzle_client.h>
7
+
8
+ extern VALUE DrizzleModule;
9
+ extern VALUE DrizzleStatus;
10
+ extern VALUE DrizzleConnection;
11
+ extern VALUE DrizzleResult;
12
+
13
+ VALUE drizzle_gem_create_class_with_private_constructor(const char *name, VALUE super);
14
+ void drizzle_gem_assert_value_is_ok(drizzle_return_t value);
15
+ VALUE drizzle_gem_to_string_array(char **array, long count);
16
+ const char *drizzle_gem_read_string_with_default(VALUE string, const char *default_value);
17
+
18
+ #define convert_to_struct(datatype, var_name, value) datatype *var_name; Data_Get_Struct(value, datatype, var_name)
19
+ #define read_self_ptr() convert_to_struct(SELF_TYPE, self_ptr, self)
20
+ #define CHECK_OK(value) drizzle_gem_assert_value_is_ok(value)
21
+ #define rb_call(self, string) rb_funcall(self, rb_intern(string), 0)
22
+ #define read_string(value, default_value) drizzle_gem_read_string_with_default(value, default_value)
23
+
24
+ #endif
@@ -0,0 +1,9 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'downpour'
4
+ dir_config(extension_name)
5
+
6
+ have_library("drizzle")
7
+ $CFLAGS += " -I/usr/local/include/libdrizzle-1.0 -I/usr/include/libdrizzle-1.0"
8
+
9
+ create_makefile(extension_name)
@@ -0,0 +1,39 @@
1
+ #include "drizzle.h"
2
+
3
+ static VALUE do_not_use_this_constructor(VALUE self)
4
+ {
5
+ rb_raise(rb_eNameError, "private method `new' called for %s:Class.", rb_class2name(CLASS_OF(self)));
6
+ }
7
+
8
+ VALUE drizzle_gem_to_string_array(char **array, long count)
9
+ {
10
+ VALUE ary = rb_ary_new2(count);
11
+
12
+ long i;
13
+ for(i = 0; i < count; i++)
14
+ rb_ary_push(ary, rb_str_new2(array[i]));
15
+
16
+ return ary;
17
+ }
18
+
19
+ VALUE drizzle_gem_create_class_with_private_constructor(const char *name, VALUE super)
20
+ {
21
+ VALUE ret = rb_define_class_under(DrizzleModule, name, super);
22
+ rb_define_method(ret, "initialize", do_not_use_this_constructor, 0);
23
+ return ret;
24
+ }
25
+
26
+ void drizzle_gem_assert_value_is_ok(drizzle_return_t ret)
27
+ {
28
+ if(ret != DRIZZLE_RETURN_OK)
29
+ rb_raise(rb_eIOError, "Action Failed with error code: %d. Please check the error string on status object for more information", ret);
30
+ }
31
+
32
+ const char *drizzle_gem_read_string_with_default(VALUE string, const char *default_value)
33
+ {
34
+ if(string == Qnil)
35
+ return default_value;
36
+
37
+ Check_Type(string, T_STRING);
38
+ return RSTRING_PTR(string);
39
+ }
@@ -0,0 +1,19 @@
1
+ #include "drizzle.h"
2
+
3
+ static VALUE version(VALUE self)
4
+ {
5
+ return rb_str_new2(drizzle_version());
6
+ }
7
+
8
+ static VALUE create(VALUE self)
9
+ {
10
+ drizzle_st *ptr = drizzle_create(NULL);
11
+ return Data_Wrap_Struct(DrizzleStatus, NULL, drizzle_free, ptr);
12
+ }
13
+
14
+ void init_drizzle_module()
15
+ {
16
+ DrizzleModule = rb_define_module("Drizzle");
17
+ rb_define_singleton_method(DrizzleModule, "version", version, 0);
18
+ rb_define_singleton_method(DrizzleModule, "create", create, 0);
19
+ }
@@ -0,0 +1,92 @@
1
+ #include "drizzle.h"
2
+
3
+ #define SELF_TYPE drizzle_result_st
4
+
5
+ static uint64_t do_column_count(drizzle_result_st *self_ptr)
6
+ {
7
+ return drizzle_result_column_count(self_ptr);
8
+ }
9
+
10
+ static VALUE is_buffered(VALUE self)
11
+ {
12
+ VALUE buffered = rb_iv_get(self, "@buffered");
13
+
14
+ if(buffered == Qnil || buffered == Qfalse)
15
+ return Qfalse;
16
+
17
+ return buffered;
18
+ }
19
+
20
+ static bool is_buffered_bool(VALUE self)
21
+ {
22
+ return RTEST(rb_call(self, "buffered?"));
23
+ }
24
+
25
+ static VALUE buffer_if_needed(VALUE self)
26
+ {
27
+ read_self_ptr();
28
+
29
+ // Only buffer once
30
+ if(is_buffered_bool(self))
31
+ return Qfalse;
32
+
33
+ CHECK_OK(drizzle_result_buffer(self_ptr));
34
+ rb_iv_set(self, "@buffered", Qtrue);
35
+ return Qtrue;
36
+ }
37
+
38
+ static VALUE row_count(VALUE self)
39
+ {
40
+ rb_call(self, "buffer!");
41
+ read_self_ptr();
42
+ return UINT2NUM(drizzle_result_row_count(self_ptr));
43
+ }
44
+
45
+ static VALUE wrap_row(drizzle_result_st *self_ptr, drizzle_row_t row)
46
+ {
47
+ // No more rows to read :-)
48
+ if(row == NULL)
49
+ return Qnil;
50
+
51
+ // TODO: wrap this in a Ruby Object. It should be freed
52
+ return drizzle_gem_to_string_array(row, do_column_count(self_ptr));
53
+ }
54
+
55
+ static VALUE next_row_buffered(drizzle_result_st *self_ptr)
56
+ {
57
+ return wrap_row(self_ptr, drizzle_row_next(self_ptr));
58
+ }
59
+
60
+ static VALUE next_row_unbuffered(drizzle_result_st *self_ptr)
61
+ {
62
+ drizzle_return_t ret;
63
+ drizzle_row_t result = drizzle_row_buffer(self_ptr, &ret);
64
+ CHECK_OK(ret);
65
+ return wrap_row(self_ptr, result);
66
+ }
67
+
68
+ static VALUE next_row(VALUE self)
69
+ {
70
+ read_self_ptr();
71
+
72
+ if(is_buffered_bool(self))
73
+ return next_row_buffered(self_ptr);
74
+
75
+ return next_row_unbuffered(self_ptr);
76
+ }
77
+
78
+ static VALUE column_count(VALUE self)
79
+ {
80
+ read_self_ptr();
81
+ return UINT2NUM(do_column_count(self_ptr));
82
+ }
83
+
84
+ void init_drizzle_result()
85
+ {
86
+ DrizzleResult = drizzle_gem_create_class_with_private_constructor("Result", rb_cObject);
87
+ rb_define_method(DrizzleResult, "row_count", row_count, 0);
88
+ rb_define_method(DrizzleResult, "column_count", column_count, 0);
89
+ rb_define_method(DrizzleResult, "buffer!", buffer_if_needed, 0);
90
+ rb_define_method(DrizzleResult, "buffered?", is_buffered, 0);
91
+ rb_define_method(DrizzleResult, "next_row", next_row, 0);
92
+ }
@@ -0,0 +1,67 @@
1
+ #include "drizzle.h"
2
+
3
+ #define SELF_TYPE drizzle_st
4
+
5
+ static VALUE clone_status(VALUE self)
6
+ {
7
+ read_self_ptr();
8
+ drizzle_st *cloned = drizzle_clone(NULL, self_ptr);
9
+ return Data_Wrap_Struct(DrizzleStatus, NULL, drizzle_free, cloned);
10
+ }
11
+
12
+ static in_port_t get_port(VALUE port)
13
+ {
14
+ if(port == Qnil)
15
+ return DRIZZLE_DEFAULT_TCP_PORT;
16
+ Check_Type(port, T_FIXNUM);
17
+ return NUM2UINT(port);
18
+ }
19
+
20
+
21
+ static VALUE add_tcp_connection(int argc, VALUE *argv, VALUE self)
22
+ {
23
+ read_self_ptr();
24
+
25
+ VALUE host, port, user, passwd, db, options;
26
+
27
+ //TODO: We ignore options
28
+ rb_scan_args(argc, argv, "06", &host, &user, &passwd, &db, &port, &options);
29
+
30
+ drizzle_con_st *connection = drizzle_con_add_tcp(self_ptr, NULL,
31
+ read_string(host, "localhost"),
32
+ get_port(port),
33
+ read_string(user, ""),
34
+ read_string(passwd, ""),
35
+ read_string(db, "test"),
36
+ DRIZZLE_CON_NONE);
37
+
38
+ VALUE val = Data_Wrap_Struct(DrizzleConnection, NULL, NULL, connection);
39
+ rb_iv_set(val, "@status", self);
40
+ return val;
41
+ }
42
+
43
+ static VALUE error(VALUE self)
44
+ {
45
+ read_self_ptr();
46
+
47
+ return rb_str_new2(drizzle_error(self_ptr));
48
+ }
49
+
50
+ static VALUE set_verbose(VALUE self, VALUE newVerbocity)
51
+ {
52
+ read_self_ptr();
53
+
54
+ int verbocity = NUM2INT(newVerbocity);
55
+ drizzle_set_verbose(self_ptr, verbocity);
56
+
57
+ return newVerbocity;
58
+ }
59
+
60
+ void init_drizzle_status()
61
+ {
62
+ DrizzleStatus = drizzle_gem_create_class_with_private_constructor("Status", rb_cObject);
63
+ rb_define_method(DrizzleStatus, "clone", clone_status, 0);
64
+ rb_define_method(DrizzleStatus, "add_tcp_connection", add_tcp_connection, -1);
65
+ rb_define_method(DrizzleStatus, "error", error, 0);
66
+ rb_define_method(DrizzleStatus, "verbose=", set_verbose, 1);
67
+ }
@@ -0,0 +1,3 @@
1
+ module Downpour
2
+ VERSION = "0.0.1"
3
+ end
data/lib/downpour.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'downpour/downpour'
2
+ require 'downpour/version'
@@ -0,0 +1,7 @@
1
+ drop table if exists Test1;
2
+ create table Test1 (
3
+ name varchar(20)
4
+ );
5
+ insert into Test1 values ('foo');
6
+ insert into Test1 values ('bar');
7
+ insert into Test1 values ('baz');
@@ -0,0 +1,5 @@
1
+ describe Drizzle do
2
+ it "should have the version number set" do
3
+ Drizzle.version.should == "7"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ describe Drizzle do
2
+ before(:each) do
3
+ @status = Drizzle.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
@@ -0,0 +1,61 @@
1
+ describe Drizzle do
2
+
3
+ before(:each) do
4
+ @status = Drizzle.create
5
+ @conn = create_connection(@status)
6
+ end
7
+
8
+ context "select query" do
9
+ before(:each) do
10
+ @results = @conn.query "select * from Test1"
11
+ end
12
+
13
+ it "should count records" do
14
+ @results.row_count.should == 3
15
+ @results.should be_buffered
16
+ end
17
+
18
+ it "should buffer records" do
19
+ @results.should_not be_buffered
20
+ @results.buffer!
21
+ @results.should be_buffered
22
+ end
23
+
24
+ it "should only buffer records once" do
25
+ @results.buffer!.should be_true
26
+ @results.buffer!.should be_false
27
+ end
28
+
29
+ it "should count columns" do
30
+ @results.column_count.should == 1
31
+ end
32
+
33
+ it "should not buffer when reading a single row" do
34
+ @results.next_row
35
+ @results.should_not be_buffered
36
+ end
37
+
38
+ shared_examples_for "a read query" do
39
+ it "should read all rows" do
40
+ @results.next_row.should == ["foo"]
41
+ @results.next_row.should == ["bar"]
42
+ @results.next_row.should == ["baz"]
43
+ @results.next_row.should be_nil
44
+ end
45
+ end
46
+
47
+ context "without buffering" do
48
+ it_should_behave_like "a read query"
49
+ end
50
+
51
+ context "with buffering" do
52
+ before(:each) { @results.buffer! }
53
+
54
+ it_should_behave_like "a read query"
55
+ end
56
+ end
57
+
58
+ after(:each) do
59
+ #puts @status.error
60
+ end
61
+ end
@@ -0,0 +1,5 @@
1
+ require './lib/downpour/downpour'
2
+
3
+ def create_connection(status)
4
+ status.add_tcp_connection "localhost", ENV["USER"], "", "test"
5
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: downpour
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Tejas Dinkar
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-25 00:00:00 +05:30
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rake-compiler
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 0.7.1
25
+ type: :development
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :development
37
+ version_requirements: *id002
38
+ description: A simple, fast Mysql and Drizzle library for Ruby, binding to libdrizzle. Still in early alpha
39
+ email: tejas@gja.in
40
+ executables: []
41
+
42
+ extensions:
43
+ - ext/downpour/extconf.rb
44
+ extra_rdoc_files:
45
+ - README.rdoc
46
+ files:
47
+ - downpour.gemspec
48
+ - ext/downpour/connection.c
49
+ - ext/downpour/drizzle.c
50
+ - ext/downpour/drizzle.h
51
+ - ext/downpour/extconf.rb
52
+ - ext/downpour/helpers.c
53
+ - ext/downpour/module.c
54
+ - ext/downpour/result.c
55
+ - ext/downpour/status.c
56
+ - lib/downpour.rb
57
+ - lib/downpour/version.rb
58
+ - README.rdoc
59
+ - spec/bootstrap.sql
60
+ - spec/module_spec.rb
61
+ - spec/query_spec.rb
62
+ - spec/smoke_spec.rb
63
+ - spec/spec_helper.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/gja/downpour
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options:
70
+ - --charset=UTF-8
71
+ require_paths:
72
+ - lib
73
+ - ext
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ requirements: []
87
+
88
+ rubyforge_project:
89
+ rubygems_version: 1.6.2
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: A simple, fast Mysql and Drizzle library for Ruby, binding to libdrizzle
93
+ test_files:
94
+ - spec/bootstrap.sql
95
+ - spec/module_spec.rb
96
+ - spec/query_spec.rb
97
+ - spec/smoke_spec.rb
98
+ - spec/spec_helper.rb