Permalink
Browse files

adding statements and whatnot

  • Loading branch information...
1 parent 2ab9c72 commit f7580a769b3f660e1060f2bdad7b84802e59c345 @tenderlove committed Jan 20, 2010
View
@@ -2,7 +2,6 @@
VALUE mSqlite3;
VALUE cDeeBee;
-VALUE cDeeBeeStatement;
static VALUE libversion(VALUE klass)
{
@@ -13,7 +12,7 @@ static VALUE open_connection(VALUE klass, VALUE file)
{
sqlite3 * database;
if(SQLITE_OK != sqlite3_open(StringValuePtr(file), &database)) {
- rb_raise(rb_eRuntimeError, "fixme!");
+ rb_raise(rb_eRuntimeError, "%s", sqlite3_errmsg(database));
}
return Data_Wrap_Struct(klass, 0, 0, database);
@@ -36,16 +35,44 @@ static VALUE prepare(VALUE self, VALUE sql)
if(SQLITE_OK != status)
rb_raise(rb_eRuntimeError, "%s", sqlite3_errmsg(ctx));
- return Data_Wrap_Struct(cDeeBeeStatement, 0, 0, stmt);
+ VALUE statement = Data_Wrap_Struct(cDeeBeeStatement, 0, 0, stmt);
+ rb_iv_set(statement, "@connection", self);
+
+ return statement;
+}
+
+int enc_cb(void * _self, int columns, char **data, char **names)
+{
+ VALUE self = (VALUE)_self;
+ int index = rb_enc_find_index("UTF-8");
+ VALUE enc = rb_str_new2(data[0]);
+ rb_enc_associate_index(enc, index);
+
+ rb_iv_set(self, "@encoding", enc);
+
+ return 0;
+}
+
+static VALUE encoding_str(VALUE self)
+{
+ sqlite3 * ctx;
+
+ Data_Get_Struct(self, sqlite3, ctx);
+
+ sqlite3_exec(ctx, "PRAGMA encoding", enc_cb, (void *)self, NULL);
+
+ return rb_iv_get(self, "@encoding");
}
void Init_deebee()
{
mSqlite3 = rb_define_module("SQLite3");
cDeeBee = rb_define_class_under(mSqlite3, "DeeBee", rb_cObject);
- cDeeBeeStatement = rb_define_class_under(cDeeBee, "Statement", rb_cObject);
+
+ init_deebee_statement();
rb_define_singleton_method(cDeeBee, "libversion", libversion, 0);
rb_define_singleton_method(cDeeBee, "open", open_connection, 1);
rb_define_method(cDeeBee, "prepare", prepare, 1);
+ rb_define_private_method(cDeeBee, "encoding_str", encoding_str, 0);
}
View
@@ -4,4 +4,9 @@
#include <ruby.h>
#include <sqlite3.h>
+extern VALUE mSqlite3;
+extern VALUE cDeeBee;
+
+#include <deebee_statement.h>
+
#endif
@@ -0,0 +1,56 @@
+#include <deebee.h>
+
+VALUE cDeeBeeStatement;
+
+static VALUE each(VALUE self)
+{
+ sqlite3_stmt *stmt;
+
+ Data_Get_Struct(self, sqlite3_stmt, stmt);
+ int value = sqlite3_step(stmt);
+ while(value != SQLITE_DONE) {
+ switch(value) {
+ case SQLITE_ROW:
+ {
+ int length = sqlite3_column_count(stmt);
+ VALUE list = rb_ary_new2(length);
+
+ int i;
+ for(i = 0; i < length; i++) {
+ switch(sqlite3_column_type(stmt, i)) {
+ case SQLITE_INTEGER:
+ rb_ary_push(list, INT2NUM(sqlite3_column_int(stmt, i)));
+ break;
+ case SQLITE_FLOAT:
+ rb_ary_push(list, rb_float_new(sqlite3_column_double(stmt, i)));
+ break;
+ case SQLITE_TEXT:
+ rb_ary_push(list, rb_str_new2(sqlite3_column_text(stmt, i)));
+ break;
+ case SQLITE_BLOB:
+ rb_ary_push(list, rb_str_new2(sqlite3_column_blob(stmt, i)));
+ break;
+ case SQLITE_NULL:
+ rb_ary_push(list, Qnil);
+ break;
+ default:
+ rb_raise(rb_eRuntimeError, "oh no!");
+ }
+ }
+ rb_yield(list);
+ }
+ break;
+ default:
+ rb_raise(rb_eRuntimeError, "oh no!");
+ }
+ value = sqlite3_step(stmt);
+ }
+ return self;
+}
+
+void init_deebee_statement()
+{
+ cDeeBeeStatement = rb_define_class_under(cDeeBee, "Statement", rb_cObject);
+
+ rb_define_method(cDeeBeeStatement, "each", each, 0);
+}
@@ -0,0 +1,10 @@
+#ifndef DEEBEE_STATEMENT
+#define DEEBEE_STATEMENT
+
+#include <deebee.h>
+
+extern VALUE cDeeBeeStatement;
+
+void init_deebee_statement();
+
+#endif
View
@@ -1,7 +1,12 @@
require 'deebee/deebee'
+require 'deebee/statement'
module SQLite3
class DeeBee
VERSION = '1.0.0'
+
+ def encoding
+ Encoding.find(encoding_str)
+ end
end
end
View
@@ -0,0 +1,7 @@
+module SQLite3
+ class DeeBee
+ class Statement
+ include Enumerable
+ end
+ end
+end
View
@@ -16,4 +16,10 @@ def test_prepare
stmt = db.prepare('PRAGMA encoding')
assert_instance_of(SQLite3::DeeBee::Statement, stmt);
end
+
+ def test_encoding
+ enc = Encoding.find('UTF-8')
+ db = SQLite3::DeeBee.open(File.join(Dir.tmpdir, 'foo.db'))
+ assert_equal enc, db.encoding
+ end
end
View
@@ -0,0 +1,13 @@
+require "test/unit"
+require "deebee"
+require 'tmpdir'
+
+class TestStatement < Test::Unit::TestCase
+ def test_step
+ db = SQLite3::DeeBee.open(File.join(Dir.tmpdir, 'foo.db'))
+ stmt = db.prepare('PRAGMA encoding')
+ called = false
+ stmt.each { |row| called = true }
+ assert called
+ end
+end

0 comments on commit f7580a7

Please sign in to comment.