do_sqlite3 0.9.12-x86-mswin32-60 → 0.10.0-x86-mswin32-60
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.
- data/{History.txt → HISTORY.markdown} +10 -2
- data/Manifest.txt +2 -2
- data/{README.txt → README.markdown} +2 -1
- data/Rakefile +2 -2
- data/ext/do_sqlite3_ext/do_sqlite3_ext.c +94 -19
- data/ext/do_sqlite3_ext/error.h +106 -0
- data/ext/do_sqlite3_ext/extconf.rb +3 -19
- data/lib/do_sqlite3.rb +19 -18
- data/lib/do_sqlite3/transaction.rb +6 -14
- data/lib/do_sqlite3/version.rb +1 -1
- data/lib/do_sqlite3_ext.so +0 -0
- data/spec/result_spec.rb +10 -0
- data/spec/spec_helper.rb +39 -10
- data/spec/typecast/bigdecimal_spec.rb +3 -0
- data/spec/typecast/boolean_spec.rb +3 -0
- data/spec/typecast/date_spec.rb +3 -0
- data/spec/typecast/datetime_spec.rb +3 -0
- data/spec/typecast/float_spec.rb +4 -0
- data/spec/typecast/nil_spec.rb +11 -1
- data/tasks/gem.rake +1 -54
- data/tasks/release.rake +7 -7
- data/tasks/retrieve.rake +2 -2
- data/tasks/spec.rake +1 -0
- metadata +11 -10
@@ -1,10 +1,18 @@
|
|
1
|
-
|
1
|
+
## 0.10.0 2009-10-15
|
2
|
+
* Improvements
|
3
|
+
* JRuby Support (using *do_jdbc*)
|
4
|
+
|
5
|
+
## 0.9.12 2009-05-17
|
6
|
+
* Improvements
|
7
|
+
* rake-compiler for Windows support
|
8
|
+
|
9
|
+
## 0.9.11 2009-01-19
|
2
10
|
* Improvements
|
3
11
|
* Ruby 1.9 support
|
4
12
|
* Fixes
|
5
13
|
* Fix Windows gem
|
6
14
|
|
7
|
-
|
15
|
+
## 0.9.9 2008-11-27
|
8
16
|
* Improvements
|
9
17
|
* Added cross compile rake tasks for Windows gems [Jonathan Stott, Luis Lavena]
|
10
18
|
* Added initial support for Ruby 1.9 [John Harrison]
|
data/Manifest.txt
CHANGED
data/Rakefile
CHANGED
@@ -8,9 +8,9 @@ require 'lib/do_sqlite3/version'
|
|
8
8
|
ROOT = Pathname(__FILE__).dirname.expand_path
|
9
9
|
JRUBY = RUBY_PLATFORM =~ /java/
|
10
10
|
WINDOWS = Gem.win_platform?
|
11
|
-
SUDO =
|
11
|
+
SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
|
12
12
|
BINARY_VERSION = '3_6_13'
|
13
13
|
|
14
|
-
Dir['tasks/*.rake'].each { |f| import f }
|
14
|
+
Dir['tasks/*.rake'].sort.each { |f| import f }
|
15
15
|
|
16
16
|
CLEAN.include(%w[ {tmp,pkg}/ **/*.{o,so,bundle,jar,log,a,gem,dSYM,obj,pdb,exp,DS_Store,rbc,db} ext/do_sqlite3_ext/Makefile ext-java/target ])
|
@@ -4,6 +4,38 @@
|
|
4
4
|
#include <time.h>
|
5
5
|
#include <locale.h>
|
6
6
|
#include <sqlite3.h>
|
7
|
+
#include "error.h"
|
8
|
+
|
9
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
10
|
+
#include <ruby/encoding.h>
|
11
|
+
|
12
|
+
#define DO_STR_NEW2(str, encoding) \
|
13
|
+
({ \
|
14
|
+
VALUE _string = rb_str_new2((const char *)str); \
|
15
|
+
if(encoding != -1) { \
|
16
|
+
rb_enc_associate_index(_string, encoding); \
|
17
|
+
} \
|
18
|
+
_string; \
|
19
|
+
})
|
20
|
+
|
21
|
+
#define DO_STR_NEW(str, len, encoding) \
|
22
|
+
({ \
|
23
|
+
VALUE _string = rb_str_new((const char *)str, (long)len); \
|
24
|
+
if(encoding != -1) { \
|
25
|
+
rb_enc_associate_index(_string, encoding); \
|
26
|
+
} \
|
27
|
+
_string; \
|
28
|
+
})
|
29
|
+
|
30
|
+
#else
|
31
|
+
|
32
|
+
#define DO_STR_NEW2(str, encoding) \
|
33
|
+
rb_str_new2((const char *)str)
|
34
|
+
|
35
|
+
#define DO_STR_NEW(str, len, encoding) \
|
36
|
+
rb_str_new((const char *)str, (long)len)
|
37
|
+
#endif
|
38
|
+
|
7
39
|
|
8
40
|
#define ID_CONST_GET rb_intern("const_get")
|
9
41
|
#define ID_PATH rb_intern("path")
|
@@ -12,8 +44,6 @@
|
|
12
44
|
#define ID_QUERY rb_intern("query")
|
13
45
|
|
14
46
|
#define RUBY_CLASS(name) rb_const_get(rb_cObject, rb_intern(name))
|
15
|
-
#define RUBY_STRING(char_ptr) rb_str_new2(char_ptr)
|
16
|
-
#define TAINTED_STRING(name, length) rb_tainted_str_new(name, length)
|
17
47
|
#define CONST_GET(scope, constant) (rb_funcall(scope, ID_CONST_GET, 1, rb_str_new2(constant)))
|
18
48
|
#define SQLITE3_CLASS(klass, parent) (rb_define_class_under(mSqlite3, klass, parent))
|
19
49
|
|
@@ -69,7 +99,8 @@ static VALUE cResult;
|
|
69
99
|
static VALUE cReader;
|
70
100
|
|
71
101
|
static VALUE eArgumentError;
|
72
|
-
static VALUE
|
102
|
+
static VALUE eConnectionError;
|
103
|
+
static VALUE eDataError;
|
73
104
|
|
74
105
|
static VALUE OPEN_FLAG_READONLY;
|
75
106
|
static VALUE OPEN_FLAG_READWRITE;
|
@@ -126,6 +157,32 @@ static void data_objects_debug(VALUE string, struct timeval* start) {
|
|
126
157
|
}
|
127
158
|
}
|
128
159
|
|
160
|
+
static void raise_error(VALUE self, sqlite3 *result, VALUE query) {
|
161
|
+
VALUE exception;
|
162
|
+
const char *message = sqlite3_errmsg(result);
|
163
|
+
const char *exception_type = "SQLError";
|
164
|
+
int sqlite3_errno = sqlite3_errcode(result);
|
165
|
+
|
166
|
+
struct errcodes *errs;
|
167
|
+
|
168
|
+
for (errs = errors; errs->error_name; errs++) {
|
169
|
+
if(errs->error_no == sqlite3_errno) {
|
170
|
+
exception_type = errs->exception;
|
171
|
+
break;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
|
176
|
+
VALUE uri = rb_funcall(rb_iv_get(self, "@connection"), rb_intern("to_s"), 0);
|
177
|
+
|
178
|
+
exception = rb_funcall(CONST_GET(mDO, exception_type), ID_NEW, 5,
|
179
|
+
rb_str_new2(message),
|
180
|
+
INT2NUM(sqlite3_errno),
|
181
|
+
rb_str_new2(""),
|
182
|
+
query,
|
183
|
+
uri);
|
184
|
+
rb_exc_raise(exception);
|
185
|
+
}
|
129
186
|
|
130
187
|
static VALUE parse_date(char *date) {
|
131
188
|
int year, month, day;
|
@@ -200,7 +257,7 @@ static VALUE parse_date_time(char *date) {
|
|
200
257
|
hour_offset = 0;
|
201
258
|
minute_offset = 0;
|
202
259
|
sec = 0;
|
203
|
-
}
|
260
|
+
}
|
204
261
|
// We read the Date and Time, default to the current locale's offset
|
205
262
|
|
206
263
|
// Get localtime
|
@@ -222,7 +279,7 @@ static VALUE parse_date_time(char *date) {
|
|
222
279
|
|
223
280
|
} else {
|
224
281
|
// Something went terribly wrong
|
225
|
-
rb_raise(
|
282
|
+
rb_raise(eDataError, "Couldn't parse date: %s", date);
|
226
283
|
}
|
227
284
|
|
228
285
|
jd = jd_from_date(year, month, day);
|
@@ -278,7 +335,7 @@ static VALUE parse_time(char *date) {
|
|
278
335
|
return rb_funcall(rb_cTime, rb_intern("local"), 7, INT2NUM(year), INT2NUM(month), INT2NUM(day), INT2NUM(hour), INT2NUM(min), INT2NUM(sec), INT2NUM(usec));
|
279
336
|
}
|
280
337
|
|
281
|
-
static VALUE typecast(sqlite3_stmt *stmt, int i, VALUE type) {
|
338
|
+
static VALUE typecast(sqlite3_stmt *stmt, int i, VALUE type, int encoding) {
|
282
339
|
VALUE ruby_value = Qnil;
|
283
340
|
int original_type = sqlite3_column_type(stmt, i);
|
284
341
|
int length = sqlite3_column_bytes(stmt, i);
|
@@ -310,11 +367,11 @@ static VALUE typecast(sqlite3_stmt *stmt, int i, VALUE type) {
|
|
310
367
|
if (type == rb_cInteger) {
|
311
368
|
return LL2NUM(sqlite3_column_int64(stmt, i));
|
312
369
|
} else if (type == rb_cString) {
|
313
|
-
return
|
370
|
+
return DO_STR_NEW((char*)sqlite3_column_text(stmt, i), length, encoding);
|
314
371
|
} else if (type == rb_cFloat) {
|
315
372
|
return rb_float_new(sqlite3_column_double(stmt, i));
|
316
373
|
} else if (type == rb_cBigDecimal) {
|
317
|
-
return rb_funcall(rb_cBigDecimal, ID_NEW, 1,
|
374
|
+
return rb_funcall(rb_cBigDecimal, ID_NEW, 1, rb_str_new((char*)sqlite3_column_text(stmt, i), length));
|
318
375
|
} else if (type == rb_cDate) {
|
319
376
|
return parse_date((char*)sqlite3_column_text(stmt, i));
|
320
377
|
} else if (type == rb_cDateTime) {
|
@@ -324,15 +381,15 @@ static VALUE typecast(sqlite3_stmt *stmt, int i, VALUE type) {
|
|
324
381
|
} else if (type == rb_cTrueClass) {
|
325
382
|
return strcmp((char*)sqlite3_column_text(stmt, i), "t") == 0 ? Qtrue : Qfalse;
|
326
383
|
} else if (type == rb_cByteArray) {
|
327
|
-
return rb_funcall(rb_cByteArray, ID_NEW, 1,
|
384
|
+
return rb_funcall(rb_cByteArray, ID_NEW, 1, rb_str_new((char*)sqlite3_column_blob(stmt, i), length));
|
328
385
|
} else if (type == rb_cClass) {
|
329
|
-
return rb_funcall(rb_cObject, rb_intern("full_const_get"), 1,
|
386
|
+
return rb_funcall(rb_cObject, rb_intern("full_const_get"), 1, rb_str_new((char*)sqlite3_column_text(stmt, i), length));
|
330
387
|
} else if (type == rb_cObject) {
|
331
388
|
return rb_marshal_load(rb_str_new((char*)sqlite3_column_text(stmt, i), length));
|
332
389
|
} else if (type == rb_cNilClass) {
|
333
390
|
return Qnil;
|
334
391
|
} else {
|
335
|
-
return
|
392
|
+
return DO_STR_NEW((char*)sqlite3_column_text(stmt, i), length, encoding);
|
336
393
|
}
|
337
394
|
}
|
338
395
|
|
@@ -390,11 +447,16 @@ static VALUE cConnection_initialize(VALUE self, VALUE uri) {
|
|
390
447
|
#endif
|
391
448
|
|
392
449
|
if ( ret != SQLITE_OK ) {
|
393
|
-
|
450
|
+
raise_error(self, db, Qnil);
|
394
451
|
}
|
395
452
|
|
396
453
|
rb_iv_set(self, "@uri", uri);
|
397
454
|
rb_iv_set(self, "@connection", Data_Wrap_Struct(rb_cObject, 0, 0, db));
|
455
|
+
// Sqlite3 only supports UTF-8, so this is the standard encoding
|
456
|
+
rb_iv_set(self, "@encoding", rb_str_new2("UTF-8"));
|
457
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
458
|
+
rb_iv_set(self, "@encoding_id", INT2FIX(rb_enc_find_index("UTF-8")));
|
459
|
+
#endif
|
398
460
|
|
399
461
|
return Qtrue;
|
400
462
|
}
|
@@ -453,7 +515,7 @@ static VALUE cCommand_set_types(int argc, VALUE *argv, VALUE self) {
|
|
453
515
|
}
|
454
516
|
|
455
517
|
static VALUE cConnection_quote_boolean(VALUE self, VALUE value) {
|
456
|
-
return
|
518
|
+
return rb_str_new2(value == Qtrue ? "'t'" : "'f'");
|
457
519
|
}
|
458
520
|
|
459
521
|
static VALUE cConnection_quote_string(VALUE self, VALUE string) {
|
@@ -464,7 +526,10 @@ static VALUE cConnection_quote_string(VALUE self, VALUE string) {
|
|
464
526
|
// Wrap the escaped string in single-quotes, this is DO's convention
|
465
527
|
escaped_with_quotes = sqlite3_mprintf("%Q", source);
|
466
528
|
|
467
|
-
result =
|
529
|
+
result = rb_str_new2(escaped_with_quotes);
|
530
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
531
|
+
rb_enc_associate_index(result, FIX2INT(rb_iv_get(self, "@encoding_id")));
|
532
|
+
#endif
|
468
533
|
sqlite3_free(escaped_with_quotes);
|
469
534
|
return result;
|
470
535
|
}
|
@@ -499,7 +564,7 @@ static VALUE cCommand_execute_non_query(int argc, VALUE *argv, VALUE self) {
|
|
499
564
|
status = sqlite3_exec(db, StringValuePtr(query), 0, 0, &error_message);
|
500
565
|
|
501
566
|
if ( status != SQLITE_OK ) {
|
502
|
-
|
567
|
+
raise_error(self, db, query);
|
503
568
|
}
|
504
569
|
data_objects_debug(query, &start);
|
505
570
|
|
@@ -531,7 +596,7 @@ static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) {
|
|
531
596
|
data_objects_debug(query, &start);
|
532
597
|
|
533
598
|
if ( status != SQLITE_OK ) {
|
534
|
-
|
599
|
+
raise_error(self, db, query);
|
535
600
|
}
|
536
601
|
|
537
602
|
field_count = sqlite3_column_count(sqlite3_reader);
|
@@ -603,9 +668,18 @@ static VALUE cReader_next(VALUE self) {
|
|
603
668
|
return Qfalse;
|
604
669
|
}
|
605
670
|
|
671
|
+
int enc = -1;
|
672
|
+
#ifdef HAVE_RUBY_ENCODING_H
|
673
|
+
VALUE encoding_id = rb_iv_get(rb_iv_get(self, "@connection"), "@encoding_id");
|
674
|
+
if (encoding_id != Qnil) {
|
675
|
+
enc = FIX2INT(encoding_id);
|
676
|
+
}
|
677
|
+
#endif
|
678
|
+
|
679
|
+
|
606
680
|
for ( i = 0; i < field_count; i++ ) {
|
607
681
|
field_type = rb_ary_entry(field_types, i);
|
608
|
-
value = typecast(reader, i, field_type);
|
682
|
+
value = typecast(reader, i, field_type, enc);
|
609
683
|
rb_ary_push(arr, value);
|
610
684
|
}
|
611
685
|
|
@@ -617,7 +691,7 @@ static VALUE cReader_next(VALUE self) {
|
|
617
691
|
static VALUE cReader_values(VALUE self) {
|
618
692
|
VALUE state = rb_iv_get(self, "@state");
|
619
693
|
if ( state == Qnil || NUM2INT(state) != SQLITE_ROW ) {
|
620
|
-
rb_raise(
|
694
|
+
rb_raise(eDataError, "Reader is not initialized");
|
621
695
|
return Qnil;
|
622
696
|
}
|
623
697
|
else {
|
@@ -670,7 +744,8 @@ void Init_do_sqlite3_ext() {
|
|
670
744
|
mSqlite3 = rb_define_module_under(mDO, "Sqlite3");
|
671
745
|
|
672
746
|
eArgumentError = CONST_GET(rb_mKernel, "ArgumentError");
|
673
|
-
|
747
|
+
eConnectionError = CONST_GET(mDO, "ConnectionError");
|
748
|
+
eDataError = CONST_GET(mDO, "DataError");
|
674
749
|
|
675
750
|
cConnection = SQLITE3_CLASS("Connection", cDO_Connection);
|
676
751
|
rb_define_method(cConnection, "initialize", cConnection_initialize, 1);
|
@@ -0,0 +1,106 @@
|
|
1
|
+
static struct errcodes {
|
2
|
+
int error_no;
|
3
|
+
const char *error_name;
|
4
|
+
const char *exception;
|
5
|
+
} errors [] = {
|
6
|
+
#ifdef SQLITE_ERROR
|
7
|
+
{ SQLITE_ERROR,
|
8
|
+
"SQLITE_ERROR", "SyntaxError"},
|
9
|
+
#endif
|
10
|
+
#ifdef SQLITE_INTERNAL
|
11
|
+
{ SQLITE_INTERNAL,
|
12
|
+
"SQLITE_INTERNAL", "SQLError"},
|
13
|
+
#endif
|
14
|
+
#ifdef SQLITE_PERM
|
15
|
+
{ SQLITE_PERM,
|
16
|
+
"SQLITE_PERM", "ConnectionError"},
|
17
|
+
#endif
|
18
|
+
#ifdef SQLITE_ABORT
|
19
|
+
{ SQLITE_ABORT,
|
20
|
+
"SQLITE_ABORT", "ConnectionError"},
|
21
|
+
#endif
|
22
|
+
#ifdef SQLITE_BUSY
|
23
|
+
{ SQLITE_BUSY,
|
24
|
+
"SQLITE_BUSY", "ConnectionError"},
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#ifdef SQLITE_LOCKED
|
28
|
+
{ SQLITE_LOCKED,
|
29
|
+
"SQLITE_LOCKED", "ConnectionError"},
|
30
|
+
#endif
|
31
|
+
#ifdef SQLITE_NOMEM
|
32
|
+
{ SQLITE_NOMEM,
|
33
|
+
"SQLITE_NOMEM", "ConnectionError"},
|
34
|
+
#endif
|
35
|
+
#ifdef SQLITE_READONLY
|
36
|
+
{ SQLITE_READONLY,
|
37
|
+
"SQLITE_READONLY", "ConnectionError"},
|
38
|
+
#endif
|
39
|
+
#ifdef SQLITE_INTERRUPT
|
40
|
+
{ SQLITE_INTERRUPT,
|
41
|
+
"SQLITE_INTERRUPT", "ConnectionError"},
|
42
|
+
#endif
|
43
|
+
#ifdef SQLITE_IOERR
|
44
|
+
{ SQLITE_IOERR,
|
45
|
+
"SQLITE_IOERR", "ConnectionError"},
|
46
|
+
#endif
|
47
|
+
#ifdef SQLITE_CORRUPT
|
48
|
+
{ SQLITE_CORRUPT,
|
49
|
+
"SQLITE_CORRUPT", "ConnectionError"},
|
50
|
+
#endif
|
51
|
+
#ifdef SQLITE_FULL
|
52
|
+
{ SQLITE_FULL,
|
53
|
+
"SQLITE_FULL", "ConnectionError"},
|
54
|
+
#endif
|
55
|
+
#ifdef SQLITE_CANTOPEN
|
56
|
+
{ SQLITE_CANTOPEN,
|
57
|
+
"SQLITE_CANTOPEN", "ConnectionError"},
|
58
|
+
#endif
|
59
|
+
#ifdef SQLITE_EMPTY
|
60
|
+
{ SQLITE_EMPTY,
|
61
|
+
"SQLITE_EMPTY", "ConnectionError"},
|
62
|
+
#endif
|
63
|
+
#ifdef SQLITE_SCHEMA
|
64
|
+
{ SQLITE_SCHEMA,
|
65
|
+
"SQLITE_SCHEMA", "DataError"},
|
66
|
+
#endif
|
67
|
+
#ifdef SQLITE_TOOBIG
|
68
|
+
{ SQLITE_TOOBIG,
|
69
|
+
"SQLITE_TOOBIG", "DataError"},
|
70
|
+
#endif
|
71
|
+
#ifdef SQLITE_MISMATCH
|
72
|
+
{ SQLITE_MISMATCH,
|
73
|
+
"SQLITE_MISMATCH", "DataError"},
|
74
|
+
#endif
|
75
|
+
#ifdef SQLITE_CONSTRAINT
|
76
|
+
{ SQLITE_CONSTRAINT,
|
77
|
+
"SQLITE_CONSTRAINT", "IntegrityError"},
|
78
|
+
#endif
|
79
|
+
#ifdef SQLITE_MISUSE
|
80
|
+
{ SQLITE_MISUSE,
|
81
|
+
"SQLITE_MISUSE", "SQLError"},
|
82
|
+
#endif
|
83
|
+
|
84
|
+
#ifdef SQLITE_NOLFS
|
85
|
+
{ SQLITE_NOLFS,
|
86
|
+
"SQLITE_NOLFS", "ConnectionError"},
|
87
|
+
#endif
|
88
|
+
#ifdef SQLITE_FORMAT
|
89
|
+
{ SQLITE_FORMAT,
|
90
|
+
"SQLITE_FORMAT", "SyntaxError"},
|
91
|
+
#endif
|
92
|
+
#ifdef SQLITE_RANGE
|
93
|
+
{ SQLITE_RANGE,
|
94
|
+
"SQLITE_RANGE", "DataError"},
|
95
|
+
#endif
|
96
|
+
#ifdef SQLITE_NOTADB
|
97
|
+
{ SQLITE_NOTADB,
|
98
|
+
"SQLITE_NOTADB", "ConnectionError"},
|
99
|
+
#endif
|
100
|
+
|
101
|
+
#ifdef SQLITE_ROW
|
102
|
+
{ SQLITE_ROW,
|
103
|
+
"SQLITE_ROW", "SyntaxError"},
|
104
|
+
#endif
|
105
|
+
{0, NULL, NULL}
|
106
|
+
};
|
@@ -1,21 +1,4 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
# require 'mkmf'
|
4
|
-
#
|
5
|
-
# SWIG_WRAP = "sqlite3_api_wrap.c"
|
6
|
-
#
|
7
|
-
# dir_config( "sqlite3", "/usr/local" )
|
8
|
-
#
|
9
|
-
# if have_header( "sqlite3.h" ) && have_library( "sqlite3", "sqlite3_open" )
|
10
|
-
# create_makefile( "sqlite3_c" )
|
11
|
-
# end
|
12
|
-
|
13
|
-
if RUBY_PLATFORM =~ /darwin/
|
14
|
-
ENV["RC_ARCHS"] = `uname -m`.chomp if `uname -sr` =~ /^Darwin/
|
15
|
-
|
16
|
-
# On PowerPC the defaults are fine
|
17
|
-
ENV["RC_ARCHS"] = '' if `uname -m` =~ /^Power Macintosh/
|
18
|
-
end
|
1
|
+
ENV["RC_ARCHS"] = "" if RUBY_PLATFORM =~ /darwin/
|
19
2
|
|
20
3
|
# Loads mkmf which is used to make makefiles for Ruby extensions
|
21
4
|
require 'mkmf'
|
@@ -23,7 +6,8 @@ require 'mkmf'
|
|
23
6
|
# Give it a name
|
24
7
|
extension_name = 'do_sqlite3_ext'
|
25
8
|
|
26
|
-
|
9
|
+
# Use some default search paths
|
10
|
+
dir_config("sqlite3", ["/usr/local", "/opt/local", "/usr"])
|
27
11
|
|
28
12
|
# NOTE: use GCC flags unless Visual C compiler is used
|
29
13
|
$CFLAGS << ' -Wall ' unless RUBY_PLATFORM =~ /mswin/
|
data/lib/do_sqlite3.rb
CHANGED
@@ -1,35 +1,36 @@
|
|
1
|
-
# HACK: If running on Windows, then add the current directory to the PATH
|
2
|
-
# for the current process so it can find the bundled dlls before the require
|
3
|
-
# of the actual extension file.
|
4
|
-
if RUBY_PLATFORM.match(/mingw|mswin/i)
|
5
|
-
libdir = File.expand_path(File.dirname(__FILE__)).gsub(File::SEPARATOR, File::ALT_SEPARATOR)
|
6
|
-
ENV['PATH'] = "#{libdir};" + ENV['PATH']
|
7
|
-
end
|
8
|
-
|
9
|
-
require 'rubygems'
|
10
1
|
require 'data_objects'
|
11
2
|
if RUBY_PLATFORM =~ /java/
|
12
3
|
require 'do_jdbc'
|
13
4
|
require 'java'
|
14
|
-
|
15
|
-
|
5
|
+
|
6
|
+
driver = 'org.sqlite.JDBC'
|
7
|
+
begin
|
8
|
+
java.lang.Thread.currentThread.getContextClassLoader().loadClass(driver, true)
|
9
|
+
rescue
|
10
|
+
require 'jdbc/sqlite3' # the JDBC driver, packaged as a gem
|
11
|
+
end
|
12
|
+
|
13
|
+
# Another way of loading the JDBC Class. This seems to be more reliable
|
14
|
+
# than Class.forName() or
|
15
|
+
# Thread.currentThread.getContextClassLoader().loadClass() within the
|
16
|
+
# data_objects.Connection Java class, which is currently not working as
|
17
|
+
# expected.
|
18
|
+
java_import driver
|
16
19
|
end
|
17
20
|
|
18
21
|
require 'do_sqlite3_ext'
|
19
|
-
require
|
20
|
-
require
|
22
|
+
require 'do_sqlite3/version'
|
23
|
+
require 'do_sqlite3/transaction'
|
21
24
|
|
22
25
|
if RUBY_PLATFORM =~ /java/
|
23
|
-
# Another way of loading the JDBC Class. This seems to be more reliable
|
24
|
-
# than Class.forName() within the data_objects.Connection Java class,
|
25
|
-
# which is currently not working as expected.
|
26
|
-
import 'org.sqlite.JDBC'
|
27
26
|
|
28
27
|
module DataObjects
|
29
28
|
module Sqlite3
|
30
29
|
class Connection
|
31
30
|
def self.pool_size
|
32
|
-
|
31
|
+
# sqlite3 can have only one write access at a time, with this
|
32
|
+
# concurrent write access will result in "Database locked" errors
|
33
|
+
1
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -5,28 +5,20 @@ module DataObjects
|
|
5
5
|
|
6
6
|
class Transaction < DataObjects::Transaction
|
7
7
|
|
8
|
-
def
|
9
|
-
|
10
|
-
connection.create_command(cmd).execute_non_query
|
8
|
+
def begin_prepared
|
9
|
+
raise NotImplementedError
|
11
10
|
end
|
12
11
|
|
13
|
-
def
|
14
|
-
|
15
|
-
connection.create_command(cmd).execute_non_query
|
16
|
-
end
|
17
|
-
|
18
|
-
def rollback
|
19
|
-
cmd = "ROLLBACK"
|
20
|
-
connection.create_command(cmd).execute_non_query
|
12
|
+
def commit_prepared
|
13
|
+
raise NotImplementedError
|
21
14
|
end
|
22
15
|
|
23
16
|
def rollback_prepared
|
24
|
-
|
25
|
-
connection.create_command(cmd).execute_non_query
|
17
|
+
raise NotImplementedError
|
26
18
|
end
|
27
19
|
|
28
20
|
def prepare
|
29
|
-
|
21
|
+
raise NotImplementedError
|
30
22
|
end
|
31
23
|
|
32
24
|
end
|
data/lib/do_sqlite3/version.rb
CHANGED
data/lib/do_sqlite3_ext.so
CHANGED
Binary file
|
data/spec/result_spec.rb
CHANGED
@@ -3,7 +3,17 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
4
4
|
require 'data_objects/spec/result_spec'
|
5
5
|
|
6
|
+
# splitting the descibe into two separate declaration avoids
|
7
|
+
# concurrent execution of the "it_should_behave_like ....." calls
|
8
|
+
# which would lock the database
|
9
|
+
|
10
|
+
# TODO
|
11
|
+
# the locked database created a deadlock which is worth exploring since
|
12
|
+
# such situation could appear in the wild too
|
6
13
|
describe DataObjects::Sqlite3::Result do
|
7
14
|
it_should_behave_like 'a Result'
|
15
|
+
end
|
16
|
+
|
17
|
+
describe DataObjects::Sqlite3::Result do
|
8
18
|
it_should_behave_like 'a Result which returns inserted keys'
|
9
19
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -11,21 +11,24 @@ require 'ostruct'
|
|
11
11
|
require 'pathname'
|
12
12
|
require 'fileutils'
|
13
13
|
|
14
|
+
dir = File.dirname(__FILE__)
|
15
|
+
lib_path = File.expand_path("#{dir}/../lib")
|
16
|
+
$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
|
14
17
|
# put data_objects from repository in the load path
|
15
18
|
# DO NOT USE installed gem of data_objects!
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
DATAOBJECTS_SPEC_ROOT = Pathname(__FILE__).dirname.parent.parent + 'data_objects' + 'spec'
|
20
|
-
Pathname.glob((DATAOBJECTS_SPEC_ROOT + 'lib/**/*.rb').to_s).each { |f| require f }
|
19
|
+
do_lib_path = File.expand_path("#{dir}/../../data_objects/lib")
|
20
|
+
$LOAD_PATH.unshift do_lib_path unless $LOAD_PATH.include?(do_lib_path)
|
21
21
|
|
22
22
|
if JRUBY
|
23
|
-
|
23
|
+
jdbc_lib_path = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'do_jdbc', 'lib'))
|
24
|
+
$LOAD_PATH.unshift jdbc_lib_path unless $LOAD_PATH.include?(jdbc_lib_path)
|
24
25
|
require 'do_jdbc'
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
require 'data_objects'
|
29
|
+
|
30
|
+
DATAOBJECTS_SPEC_ROOT = Pathname(__FILE__).dirname.parent.parent + 'data_objects' + 'spec'
|
31
|
+
Pathname.glob((DATAOBJECTS_SPEC_ROOT + 'lib/**/*.rb').to_s).each { |f| require f }
|
29
32
|
require 'do_sqlite3'
|
30
33
|
|
31
34
|
log_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'log', 'do.log'))
|
@@ -79,6 +82,8 @@ module DataObjectsSpecHelpers
|
|
79
82
|
);
|
80
83
|
EOF
|
81
84
|
|
85
|
+
local_offset = Rational(Time.local(2008, 2, 14).utc_offset, 86400)
|
86
|
+
t = DateTime.civil(2008, 2, 14, 00, 31, 12, local_offset)
|
82
87
|
conn.create_command(<<-EOF).execute_non_query
|
83
88
|
CREATE TABLE "widgets" (
|
84
89
|
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
|
@@ -91,7 +96,7 @@ module DataObjectsSpecHelpers
|
|
91
96
|
"ad_image" blob NULL,
|
92
97
|
"whitepaper_text" text NULL,
|
93
98
|
"cad_drawing" blob,
|
94
|
-
"flags"
|
99
|
+
"flags" boolean default 'f',
|
95
100
|
"number_in_stock" smallint default 500,
|
96
101
|
"number_sold" integer default 0,
|
97
102
|
"super_number" bigint default 9223372036854775807,
|
@@ -99,7 +104,7 @@ module DataObjectsSpecHelpers
|
|
99
104
|
"cost1" double precision default 10.23,
|
100
105
|
"cost2" decimal(8,2) default 50.23,
|
101
106
|
"release_date" date default '2008-02-14',
|
102
|
-
"release_datetime" timestamp default '
|
107
|
+
"release_datetime" timestamp default '#{t.to_s}',
|
103
108
|
"release_timestamp" timestamp with time zone default '2008-02-14 00:31:31'
|
104
109
|
);
|
105
110
|
EOF
|
@@ -118,6 +123,30 @@ module DataObjectsSpecHelpers
|
|
118
123
|
update widgets set ad_description = NULL where id = 3
|
119
124
|
EOF
|
120
125
|
|
126
|
+
conn.create_command(<<-EOF).execute_non_query
|
127
|
+
update widgets set flags = NULL where id = 4
|
128
|
+
EOF
|
129
|
+
|
130
|
+
conn.create_command(<<-EOF).execute_non_query
|
131
|
+
update widgets set cost1 = NULL where id = 5
|
132
|
+
EOF
|
133
|
+
|
134
|
+
conn.create_command(<<-EOF).execute_non_query
|
135
|
+
update widgets set cost2 = NULL where id = 6
|
136
|
+
EOF
|
137
|
+
|
138
|
+
conn.create_command(<<-EOF).execute_non_query
|
139
|
+
update widgets set release_date = NULL where id = 7
|
140
|
+
EOF
|
141
|
+
|
142
|
+
conn.create_command(<<-EOF).execute_non_query
|
143
|
+
update widgets set release_datetime = NULL where id = 8
|
144
|
+
EOF
|
145
|
+
|
146
|
+
conn.create_command(<<-EOF).execute_non_query
|
147
|
+
update widgets set release_timestamp = NULL where id = 9
|
148
|
+
EOF
|
149
|
+
|
121
150
|
conn.close
|
122
151
|
end
|
123
152
|
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
4
|
require 'data_objects/spec/typecast/bigdecimal_spec'
|
5
5
|
|
6
|
+
# Sqlite3 doesn't support decimals natively, so autocasting is not available:
|
7
|
+
# http://www.sqlite.org/datatype3.html
|
8
|
+
|
6
9
|
describe 'DataObjects::Sqlite3 with BigDecimal' do
|
7
10
|
it_should_behave_like 'supporting BigDecimal'
|
8
11
|
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
4
|
require 'data_objects/spec/typecast/boolean_spec'
|
5
5
|
|
6
|
+
# Sqlite3 doesn't support booleans natively, so autocasting is not available:
|
7
|
+
# http://www.sqlite.org/datatype3.html
|
8
|
+
|
6
9
|
describe 'DataObjects::Sqlite3 with Boolean' do
|
7
10
|
it_should_behave_like 'supporting Boolean'
|
8
11
|
end
|
data/spec/typecast/date_spec.rb
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
4
|
require 'data_objects/spec/typecast/date_spec'
|
5
5
|
|
6
|
+
# Sqlite3 doesn't support dates natively, so autocasting is not available:
|
7
|
+
# http://www.sqlite.org/datatype3.html
|
8
|
+
|
6
9
|
describe 'DataObjects::Sqlite3 with Date' do
|
7
10
|
it_should_behave_like 'supporting Date'
|
8
11
|
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
4
|
require 'data_objects/spec/typecast/datetime_spec'
|
5
5
|
|
6
|
+
# Sqlite3 doesn't support datetimes natively, so autocasting is not available:
|
7
|
+
# http://www.sqlite.org/datatype3.html
|
8
|
+
|
6
9
|
describe 'DataObjects::Sqlite3 with DateTime' do
|
7
10
|
it_should_behave_like 'supporting DateTime'
|
8
11
|
end
|
data/spec/typecast/float_spec.rb
CHANGED
data/spec/typecast/nil_spec.rb
CHANGED
@@ -3,8 +3,18 @@
|
|
3
3
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
4
|
require 'data_objects/spec/typecast/nil_spec'
|
5
5
|
|
6
|
+
# splitting the descibe into two separate declaration avoids
|
7
|
+
# concurrent execution of the "it_should_behave_like ....." calls
|
8
|
+
# which would lock the database
|
9
|
+
|
6
10
|
describe 'DataObjects::Sqlite3 with Nil' do
|
7
11
|
it_should_behave_like 'supporting Nil'
|
8
|
-
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'DataObjects::Sqlite3 with Nil' do
|
15
|
+
it_should_behave_like 'supporting writing an Nil'
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'DataObjects::Sqlite3 with Nil' do
|
9
19
|
it_should_behave_like 'supporting Nil autocasting'
|
10
20
|
end
|
data/tasks/gem.rake
CHANGED
@@ -1,61 +1,8 @@
|
|
1
1
|
require 'rubygems/package_task'
|
2
2
|
|
3
|
-
GEM_SPEC =
|
4
|
-
# basic information
|
5
|
-
s.name = "do_sqlite3"
|
6
|
-
s.version = DataObjects::Sqlite3::VERSION
|
7
|
-
|
8
|
-
# description and details
|
9
|
-
s.summary = 'DataObjects Sqlite3 Driver'
|
10
|
-
s.description = "Implements the DataObjects API for Sqlite3"
|
11
|
-
|
12
|
-
# dependencies
|
13
|
-
s.add_dependency "addressable", "~>2.0.0"
|
14
|
-
s.add_dependency "extlib", "~>0.9.12"
|
15
|
-
s.add_dependency "data_objects", DataObjects::Sqlite3::VERSION
|
16
|
-
|
17
|
-
if JRUBY
|
18
|
-
s.add_dependency "jdbc-sqlite3", ">=3.5.8"
|
19
|
-
s.add_dependency "do_jdbc", DataObjects::Sqlite3::VERSION
|
20
|
-
s.platform = "java"
|
21
|
-
# components, files and paths
|
22
|
-
s.files = FileList["lib/**/*.rb", "spec/**/*.rb", "tasks/**/*.rake",
|
23
|
-
"LICENSE", "Rakefile", "*.{rdoc,txt,yml}", "lib/*.jar"]
|
24
|
-
else
|
25
|
-
s.platform = Gem::Platform::RUBY
|
26
|
-
s.extensions << 'ext/do_sqlite3_ext/extconf.rb'
|
27
|
-
# components, files and paths
|
28
|
-
s.files = FileList["lib/**/*.rb", "spec/**/*.rb", "tasks/**/*.rake", "ext/**/*.{rb,c}",
|
29
|
-
"LICENSE", "Rakefile", "*.{rdoc,txt,yml}"]
|
30
|
-
end
|
31
|
-
|
32
|
-
# development dependencies
|
33
|
-
s.add_development_dependency 'rspec', '~>1.2.0'
|
34
|
-
|
35
|
-
|
36
|
-
s.require_path = 'lib'
|
37
|
-
|
38
|
-
# documentation
|
39
|
-
s.has_rdoc = false
|
40
|
-
|
41
|
-
# project information
|
42
|
-
s.homepage = 'http://github.com/datamapper/do'
|
43
|
-
s.rubyforge_project = 'dorb'
|
44
|
-
|
45
|
-
# author and contributors
|
46
|
-
s.author = 'Dirkjan Bussink'
|
47
|
-
s.email = 'd.bussink@gmail.com'
|
48
|
-
end
|
3
|
+
GEM_SPEC = eval(File.read('do_sqlite3.gemspec'))
|
49
4
|
|
50
5
|
gem_package = Gem::PackageTask.new(GEM_SPEC) do |pkg|
|
51
6
|
pkg.need_tar = false
|
52
7
|
pkg.need_zip = false
|
53
8
|
end
|
54
|
-
|
55
|
-
file "#{GEM_SPEC.name}.gemspec" => ['Rakefile', 'tasks/gem.rake'] do |t|
|
56
|
-
puts "Generating #{t.name}"
|
57
|
-
File.open(t.name, 'w') { |f| f.puts GEM_SPEC.to_yaml }
|
58
|
-
end
|
59
|
-
|
60
|
-
desc "Generate or update the standalone gemspec file for the project"
|
61
|
-
task :gemspec => ["#{GEM_SPEC.name}.gemspec"]
|
data/tasks/release.rake
CHANGED
@@ -8,7 +8,7 @@ end
|
|
8
8
|
if defined?(RubyForge) then
|
9
9
|
if defined?(GEM_SPEC) then
|
10
10
|
desc 'Package and upload to RubyForge'
|
11
|
-
task :release
|
11
|
+
task :release do |t|
|
12
12
|
ver = ENV['VERSION'] or fail "Must supply VERSION (rake release VERSION=x.y.z)."
|
13
13
|
|
14
14
|
# compare versions to avoid mistakes
|
@@ -26,19 +26,19 @@ if defined?(RubyForge) then
|
|
26
26
|
|
27
27
|
# read project info and overview
|
28
28
|
notes = begin
|
29
|
-
r = File.read("README.
|
30
|
-
r.split(/^(
|
29
|
+
r = File.read("README.markdown")
|
30
|
+
r.split(/^(.*\n\-+)/)[1..4].join.strip
|
31
31
|
rescue
|
32
|
-
warn "Missing README.
|
32
|
+
warn "Missing README.markdown"
|
33
33
|
''
|
34
34
|
end
|
35
35
|
|
36
36
|
# read changes
|
37
37
|
changes = begin
|
38
|
-
h = File.read("
|
39
|
-
h.split(/^(
|
38
|
+
h = File.read("HISTORY.markdown")
|
39
|
+
h.split(/^(##+ .*)/)[1..2].join.strip
|
40
40
|
rescue
|
41
|
-
warn "Missing
|
41
|
+
warn "Missing HISTORY.markdown"
|
42
42
|
''
|
43
43
|
end
|
44
44
|
|
data/tasks/retrieve.rake
CHANGED
@@ -36,7 +36,7 @@ begin
|
|
36
36
|
url = "http://www.sqlite.org/#{File.basename(t.name)}"
|
37
37
|
when_writing "downloading #{t.name}" do
|
38
38
|
cd File.dirname(t.name) do
|
39
|
-
system "wget -c #{url} || curl -C - -O #{url}"
|
39
|
+
system "wget -c #{url} || curl -L -C - -O #{url}"
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -46,7 +46,7 @@ begin
|
|
46
46
|
url = "http://www.sqlite.org/#{File.basename(t.name)}"
|
47
47
|
when_writing "downloading #{t.name}" do
|
48
48
|
cd File.dirname(t.name) do
|
49
|
-
system "wget -c #{url} || curl -C - -O #{url}"
|
49
|
+
system "wget -c #{url} || curl -L -C - -O #{url}"
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
data/tasks/spec.rake
CHANGED
@@ -5,6 +5,7 @@ desc 'Run specifications'
|
|
5
5
|
Spec::Rake::SpecTask.new(:spec => [ :clean, :compile ]) do |t|
|
6
6
|
t.spec_opts << '--options' << ROOT + 'spec/spec.opts'
|
7
7
|
t.spec_files = Pathname.glob(ENV['FILES'] || 'spec/**/*_spec.rb').map { |f| f.to_s }
|
8
|
+
t.libs << 'lib'
|
8
9
|
|
9
10
|
begin
|
10
11
|
# RCov is run by default, except on the JRuby platform
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: do_sqlite3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: x86-mswin32-60
|
6
6
|
authors:
|
7
7
|
- Dirkjan Bussink
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-15 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 2.0
|
23
|
+
version: "2.0"
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: extlib
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - "="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.10.0
|
44
44
|
version:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: rspec
|
@@ -91,13 +91,14 @@ files:
|
|
91
91
|
- tasks/spec.rake
|
92
92
|
- ext/do_sqlite3_ext/extconf.rb
|
93
93
|
- ext/do_sqlite3_ext/do_sqlite3_ext.c
|
94
|
+
- ext/do_sqlite3_ext/error.h
|
94
95
|
- LICENSE
|
95
96
|
- Rakefile
|
96
|
-
-
|
97
|
+
- HISTORY.markdown
|
98
|
+
- README.markdown
|
97
99
|
- Manifest.txt
|
98
|
-
- README.txt
|
99
100
|
- lib/do_sqlite3_ext.so
|
100
|
-
has_rdoc:
|
101
|
+
has_rdoc: false
|
101
102
|
homepage: http://github.com/datamapper/do
|
102
103
|
licenses: []
|
103
104
|
|
@@ -108,9 +109,9 @@ require_paths:
|
|
108
109
|
- lib
|
109
110
|
required_ruby_version: !ruby/object:Gem::Requirement
|
110
111
|
requirements:
|
111
|
-
- -
|
112
|
+
- - ">="
|
112
113
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
114
|
+
version: "0"
|
114
115
|
version:
|
115
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
117
|
requirements:
|
@@ -121,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
122
|
requirements: []
|
122
123
|
|
123
124
|
rubyforge_project: dorb
|
124
|
-
rubygems_version: 1.3.
|
125
|
+
rubygems_version: 1.3.5
|
125
126
|
signing_key:
|
126
127
|
specification_version: 3
|
127
128
|
summary: DataObjects Sqlite3 Driver
|