sqlite3-ruby 1.3.1-x86-mingw32 → 1.3.2-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/API_CHANGES.rdoc +2 -0
- data/CHANGELOG.rdoc +21 -0
- data/Manifest.txt +4 -0
- data/ext/sqlite3/backup.c +164 -0
- data/ext/sqlite3/backup.h +15 -0
- data/ext/sqlite3/database.c +10 -8
- data/ext/sqlite3/extconf.rb +6 -6
- data/ext/sqlite3/sqlite3.c +3 -0
- data/ext/sqlite3/sqlite3_ruby.h +1 -0
- data/lib/sqlite3/1.8/sqlite3_native.so +0 -0
- data/lib/sqlite3/1.9/sqlite3_native.so +0 -0
- data/lib/sqlite3/database.rb +37 -20
- data/lib/sqlite3/pragmas.rb +1 -1
- data/lib/sqlite3/translator.rb +4 -0
- data/lib/sqlite3/version.rb +11 -2
- data/tasks/gem.rake +1 -1
- data/tasks/native.rake +1 -1
- data/test/test_backup.rb +33 -0
- data/test/test_database.rb +17 -0
- data/test/test_database_readonly.rb +29 -0
- data/test/test_integration.rb +0 -1
- data/test/test_integration_resultset.rb +6 -33
- metadata +39 -21
data/API_CHANGES.rdoc
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= API Changes
|
2
2
|
|
3
|
+
* SQLite3::Database#execute only accepts an array for bind parameters.
|
4
|
+
|
3
5
|
* SQLite3::ResultSet used to query the database for the first row, regardless
|
4
6
|
of whether the user asked for it or not. I have removed that so that rows
|
5
7
|
will not be returned until the user asks for them. This is a subtle but
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
=== 1.3.2 / 2010-10-30 / RubyConf Uruguay Edition!
|
2
|
+
|
3
|
+
* Enhancements:
|
4
|
+
* Windows: build against 3.7.3 version of SQLite3
|
5
|
+
* SQLite3::Database can now be open as readonly
|
6
|
+
|
7
|
+
db = SQLite3::Database.new('my.db', :readonly => true)
|
8
|
+
|
9
|
+
* Added SQLite3::SQLITE_VERSION and SQLite3::SQLITE_VERSION_NUMBER [nurse]
|
10
|
+
|
11
|
+
* Bugfixes
|
12
|
+
* type_translation= works along with Database#execute and a block
|
13
|
+
* defined functions are kept in a hash to prevent GC. #7
|
14
|
+
* Removed GCC specific flags from extconf.
|
15
|
+
|
16
|
+
* DEPRECATIONS
|
17
|
+
* SQLite3::Database#type_translation= will be deprecated in the future with
|
18
|
+
no replacement.
|
19
|
+
* SQlite3::Version will be deprecated in 2.0.0 with SQLite3::VERSION as the
|
20
|
+
replacement.
|
21
|
+
|
1
22
|
=== 1.3.1 / 2010-07-09
|
2
23
|
|
3
24
|
* Enhancements
|
data/Manifest.txt
CHANGED
@@ -5,6 +5,8 @@ LICENSE
|
|
5
5
|
Manifest.txt
|
6
6
|
README.rdoc
|
7
7
|
Rakefile
|
8
|
+
ext/sqlite3/backup.c
|
9
|
+
ext/sqlite3/backup.h
|
8
10
|
ext/sqlite3/database.c
|
9
11
|
ext/sqlite3/database.h
|
10
12
|
ext/sqlite3/exception.c
|
@@ -32,8 +34,10 @@ tasks/gem.rake
|
|
32
34
|
tasks/native.rake
|
33
35
|
tasks/vendor_sqlite3.rake
|
34
36
|
test/helper.rb
|
37
|
+
test/test_backup.rb
|
35
38
|
test/test_collation.rb
|
36
39
|
test/test_database.rb
|
40
|
+
test/test_database_readonly.rb
|
37
41
|
test/test_deprecated.rb
|
38
42
|
test/test_encoding.rb
|
39
43
|
test/test_integration.rb
|
@@ -0,0 +1,164 @@
|
|
1
|
+
#include <sqlite3_ruby.h>
|
2
|
+
|
3
|
+
#define REQUIRE_OPEN_BACKUP(_ctxt) \
|
4
|
+
if(!_ctxt->p) \
|
5
|
+
rb_raise(rb_path2class("SQLite3::Exception"), "cannot use a closed backup");
|
6
|
+
|
7
|
+
VALUE cSqlite3Backup;
|
8
|
+
|
9
|
+
static void deallocate(void * ctx)
|
10
|
+
{
|
11
|
+
sqlite3BackupRubyPtr c = (sqlite3BackupRubyPtr)ctx;
|
12
|
+
xfree(c);
|
13
|
+
}
|
14
|
+
|
15
|
+
static VALUE allocate(VALUE klass)
|
16
|
+
{
|
17
|
+
sqlite3BackupRubyPtr ctx = xcalloc((size_t)1, sizeof(sqlite3BackupRuby));
|
18
|
+
return Data_Wrap_Struct(klass, NULL, deallocate, ctx);
|
19
|
+
}
|
20
|
+
|
21
|
+
/* call-seq: SQLite3::Backup.new(dstdb, dstname, srcdb, srcname)
|
22
|
+
*
|
23
|
+
* Initialize backup the backup.
|
24
|
+
*
|
25
|
+
* dstdb:
|
26
|
+
* the destination SQLite3::Database object.
|
27
|
+
* dstname:
|
28
|
+
* the destination's database name.
|
29
|
+
* srcdb:
|
30
|
+
* the source SQLite3::Database object.
|
31
|
+
* srcname:
|
32
|
+
* the source's database name.
|
33
|
+
*
|
34
|
+
* The database name is "main", "temp", or the name specified in an
|
35
|
+
* ATTACH statement.
|
36
|
+
*
|
37
|
+
* This feature requires SQLite 3.6.11 or later.
|
38
|
+
*
|
39
|
+
* require 'sqlite3'
|
40
|
+
* sdb = SQLite3::Database.new('src.sqlite3')
|
41
|
+
*
|
42
|
+
* ddb = SQLite3::Database.new(':memory:')
|
43
|
+
* b = SQLite3::Backup.new(ddb, 'main', sdb, 'main')
|
44
|
+
* p [b.remaining, b.pagecount] # invalid value; for example [0, 0]
|
45
|
+
* begin
|
46
|
+
* p b.step(1) #=> OK or DONE
|
47
|
+
* p [b.remaining, b.pagecount]
|
48
|
+
* end while b.remaining > 0
|
49
|
+
* b.finish
|
50
|
+
*
|
51
|
+
* ddb = SQLite3::Database.new(':memory:')
|
52
|
+
* b = SQLite3::Backup.new(ddb, 'main', sdb, 'main')
|
53
|
+
* b.step(-1) #=> DONE
|
54
|
+
* b.finish
|
55
|
+
*
|
56
|
+
*/
|
57
|
+
static VALUE initialize(VALUE self, VALUE dstdb, VALUE dstname, VALUE srcdb, VALUE srcname)
|
58
|
+
{
|
59
|
+
sqlite3BackupRubyPtr ctx;
|
60
|
+
sqlite3RubyPtr ddb_ctx, sdb_ctx;
|
61
|
+
sqlite3_backup *pBackup;
|
62
|
+
|
63
|
+
Data_Get_Struct(self, sqlite3BackupRuby, ctx);
|
64
|
+
Data_Get_Struct(dstdb, sqlite3Ruby, ddb_ctx);
|
65
|
+
Data_Get_Struct(srcdb, sqlite3Ruby, sdb_ctx);
|
66
|
+
|
67
|
+
if(!sdb_ctx->db)
|
68
|
+
rb_raise(rb_eArgError, "cannot backup from a closed database");
|
69
|
+
if(!ddb_ctx->db)
|
70
|
+
rb_raise(rb_eArgError, "cannot backup to a closed database");
|
71
|
+
|
72
|
+
pBackup = sqlite3_backup_init(ddb_ctx->db, StringValuePtr(dstname),
|
73
|
+
sdb_ctx->db, StringValuePtr(srcname));
|
74
|
+
if( pBackup ){
|
75
|
+
ctx->p = pBackup;
|
76
|
+
}
|
77
|
+
else {
|
78
|
+
CHECK(ddb_ctx->db, sqlite3_errcode(ddb_ctx->db));
|
79
|
+
}
|
80
|
+
|
81
|
+
return self;
|
82
|
+
}
|
83
|
+
|
84
|
+
/* call-seq: SQLite3::Backup#step(nPage)
|
85
|
+
*
|
86
|
+
* Copy database pages up to +nPage+.
|
87
|
+
* If negative, copy all remaining source pages.
|
88
|
+
*
|
89
|
+
* If all pages are copied, it returns SQLite3::Constants::ErrorCode::DONE.
|
90
|
+
* When coping is not done, it returns SQLite3::Constants::ErrorCode::OK.
|
91
|
+
* When some errors occur, it returns the error code.
|
92
|
+
*/
|
93
|
+
static VALUE step(VALUE self, VALUE nPage)
|
94
|
+
{
|
95
|
+
sqlite3BackupRubyPtr ctx;
|
96
|
+
int status;
|
97
|
+
|
98
|
+
Data_Get_Struct(self, sqlite3BackupRuby, ctx);
|
99
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
100
|
+
status = sqlite3_backup_step(ctx->p, NUM2INT(nPage));
|
101
|
+
return INT2NUM(status);
|
102
|
+
}
|
103
|
+
|
104
|
+
/* call-seq: SQLite3::Backup#finish
|
105
|
+
*
|
106
|
+
* Destroy the backup object.
|
107
|
+
*/
|
108
|
+
static VALUE finish(VALUE self)
|
109
|
+
{
|
110
|
+
sqlite3BackupRubyPtr ctx;
|
111
|
+
|
112
|
+
Data_Get_Struct(self, sqlite3BackupRuby, ctx);
|
113
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
114
|
+
(void)sqlite3_backup_finish(ctx->p);
|
115
|
+
ctx->p = NULL;
|
116
|
+
return Qnil;
|
117
|
+
}
|
118
|
+
|
119
|
+
/* call-seq: SQLite3::Backup#remaining
|
120
|
+
*
|
121
|
+
* Returns the number of pages still to be backed up.
|
122
|
+
*
|
123
|
+
* Note that the value is only updated after step() is called,
|
124
|
+
* so before calling step() returned value is invalid.
|
125
|
+
*/
|
126
|
+
static VALUE remaining(VALUE self)
|
127
|
+
{
|
128
|
+
sqlite3BackupRubyPtr ctx;
|
129
|
+
|
130
|
+
Data_Get_Struct(self, sqlite3BackupRuby, ctx);
|
131
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
132
|
+
return INT2NUM(sqlite3_backup_remaining(ctx->p));
|
133
|
+
}
|
134
|
+
|
135
|
+
/* call-seq: SQLite3::Backup#pagecount
|
136
|
+
*
|
137
|
+
* Returns the total number of pages in the source database file.
|
138
|
+
*
|
139
|
+
* Note that the value is only updated after step() is called,
|
140
|
+
* so before calling step() returned value is invalid.
|
141
|
+
*/
|
142
|
+
static VALUE pagecount(VALUE self)
|
143
|
+
{
|
144
|
+
sqlite3BackupRubyPtr ctx;
|
145
|
+
|
146
|
+
Data_Get_Struct(self, sqlite3BackupRuby, ctx);
|
147
|
+
REQUIRE_OPEN_BACKUP(ctx);
|
148
|
+
return INT2NUM(sqlite3_backup_pagecount(ctx->p));
|
149
|
+
}
|
150
|
+
|
151
|
+
void init_sqlite3_backup()
|
152
|
+
{
|
153
|
+
#if 0
|
154
|
+
VALUE mSqlite3 = rb_define_module("SQLite3");
|
155
|
+
#endif
|
156
|
+
cSqlite3Backup = rb_define_class_under(mSqlite3, "Backup", rb_cObject);
|
157
|
+
|
158
|
+
rb_define_alloc_func(cSqlite3Backup, allocate);
|
159
|
+
rb_define_method(cSqlite3Backup, "initialize", initialize, 4);
|
160
|
+
rb_define_method(cSqlite3Backup, "step", step, 1);
|
161
|
+
rb_define_method(cSqlite3Backup, "finish", finish, 0);
|
162
|
+
rb_define_method(cSqlite3Backup, "remaining", remaining, 0);
|
163
|
+
rb_define_method(cSqlite3Backup, "pagecount", pagecount, 0);
|
164
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef SQLITE3_BACKUP_RUBY
|
2
|
+
#define SQLITE3_BACKUP_RUBY
|
3
|
+
|
4
|
+
#include <sqlite3_ruby.h>
|
5
|
+
|
6
|
+
struct _sqlite3BackupRuby {
|
7
|
+
sqlite3_backup *p;
|
8
|
+
};
|
9
|
+
|
10
|
+
typedef struct _sqlite3BackupRuby sqlite3BackupRuby;
|
11
|
+
typedef sqlite3BackupRuby * sqlite3BackupRubyPtr;
|
12
|
+
|
13
|
+
void init_sqlite3_backup();
|
14
|
+
|
15
|
+
#endif
|
data/ext/sqlite3/database.c
CHANGED
@@ -11,14 +11,8 @@ static void deallocate(void * ctx)
|
|
11
11
|
{
|
12
12
|
sqlite3RubyPtr c = (sqlite3RubyPtr)ctx;
|
13
13
|
sqlite3 * db = c->db;
|
14
|
-
sqlite3_stmt * stmt;
|
15
14
|
|
16
|
-
if(db)
|
17
|
-
while((stmt = sqlite3_next_stmt(db, NULL)) != NULL) {
|
18
|
-
sqlite3_finalize(stmt);
|
19
|
-
}
|
20
|
-
sqlite3_close(db);
|
21
|
-
}
|
15
|
+
if(db) sqlite3_close(db);
|
22
16
|
xfree(c);
|
23
17
|
}
|
24
18
|
|
@@ -50,6 +44,7 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
|
|
50
44
|
VALUE file;
|
51
45
|
VALUE opts;
|
52
46
|
VALUE zvfs;
|
47
|
+
int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
|
53
48
|
int status;
|
54
49
|
|
55
50
|
Data_Get_Struct(self, sqlite3Ruby, ctx);
|
@@ -73,10 +68,13 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
|
|
73
68
|
}
|
74
69
|
#endif
|
75
70
|
|
71
|
+
if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) {
|
72
|
+
mode = SQLITE_OPEN_READONLY;
|
73
|
+
}
|
76
74
|
status = sqlite3_open_v2(
|
77
75
|
StringValuePtr(file),
|
78
76
|
&ctx->db,
|
79
|
-
|
77
|
+
mode,
|
80
78
|
NIL_P(zvfs) ? NULL : StringValuePtr(zvfs)
|
81
79
|
);
|
82
80
|
}
|
@@ -92,8 +90,10 @@ static VALUE initialize(int argc, VALUE *argv, VALUE self)
|
|
92
90
|
rb_iv_set(self, "@encoding", Qnil);
|
93
91
|
rb_iv_set(self, "@busy_handler", Qnil);
|
94
92
|
rb_iv_set(self, "@collations", rb_hash_new());
|
93
|
+
rb_iv_set(self, "@functions", rb_hash_new());
|
95
94
|
rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash));
|
96
95
|
rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation));
|
96
|
+
rb_iv_set(self, "@readonly", mode == SQLITE_OPEN_READONLY ? Qtrue : Qfalse);
|
97
97
|
|
98
98
|
if(rb_block_given_p()) {
|
99
99
|
rb_yield(self);
|
@@ -358,6 +358,8 @@ static VALUE define_function(VALUE self, VALUE name)
|
|
358
358
|
|
359
359
|
CHECK(ctx->db, status);
|
360
360
|
|
361
|
+
rb_hash_aset(rb_iv_get(self, "@functions"), name, block);
|
362
|
+
|
361
363
|
return self;
|
362
364
|
}
|
363
365
|
|
data/ext/sqlite3/extconf.rb
CHANGED
@@ -6,13 +6,10 @@ require 'mkmf'
|
|
6
6
|
|
7
7
|
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
8
8
|
|
9
|
-
sqlite = dir_config('sqlite3', ['/usr/local', '/opt/local', '/usr'])
|
9
|
+
sqlite = dir_config('sqlite3', ['/usr/local', '/opt/local', '/sw/local', '/usr'])
|
10
10
|
|
11
11
|
if RUBY_PLATFORM =~ /mswin/
|
12
12
|
$CFLAGS << ' -W3'
|
13
|
-
else
|
14
|
-
$CFLAGS << ' -O3 -Wall -Wcast-qual -Wwrite-strings -Wconversion' <<
|
15
|
-
' -Wmissing-noreturn -Winline'
|
16
13
|
end
|
17
14
|
|
18
15
|
def asplode missing
|
@@ -20,8 +17,11 @@ def asplode missing
|
|
20
17
|
abort "#{missing} is missing. Install SQLite3 from " +
|
21
18
|
"http://www.sqlite.org/ first."
|
22
19
|
else
|
23
|
-
abort
|
24
|
-
|
20
|
+
abort <<-error
|
21
|
+
#{missing} is missing. Try 'port install sqlite3 +universal'
|
22
|
+
or 'yum install sqlite3-devel' and check your shared library search path (the
|
23
|
+
location where your sqlite3 shared library is located).
|
24
|
+
error
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
data/ext/sqlite3/sqlite3.c
CHANGED
@@ -28,6 +28,9 @@ void Init_sqlite3_native()
|
|
28
28
|
|
29
29
|
init_sqlite3_database();
|
30
30
|
init_sqlite3_statement();
|
31
|
+
init_sqlite3_backup();
|
31
32
|
|
32
33
|
rb_define_singleton_method(mSqlite3, "libversion", libversion, 0);
|
34
|
+
rb_define_const(mSqlite3, "SQLITE_VERSION", rb_str_new2(SQLITE_VERSION));
|
35
|
+
rb_define_const(mSqlite3, "SQLITE_VERSION_NUMBER", INT2FIX(SQLITE_VERSION_NUMBER));
|
33
36
|
}
|
data/ext/sqlite3/sqlite3_ruby.h
CHANGED
Binary file
|
Binary file
|
data/lib/sqlite3/database.rb
CHANGED
@@ -54,9 +54,15 @@ module SQLite3
|
|
54
54
|
# as hashes or not. By default, rows are returned as arrays.
|
55
55
|
attr_accessor :results_as_hash
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
def type_translation= value # :nodoc:
|
58
|
+
warn(<<-eowarn) if $VERBOSE
|
59
|
+
#{caller[0]} is calling SQLite3::Database#type_translation=
|
60
|
+
SQLite3::Database#type_translation= is deprecated and will be removed
|
61
|
+
in version 2.0.0.
|
62
|
+
eowarn
|
63
|
+
@type_translation = value
|
64
|
+
end
|
65
|
+
attr_reader :type_translation # :nodoc:
|
60
66
|
|
61
67
|
# Return the type translator employed by this database instance. Each
|
62
68
|
# database instance has its own type translator; this allows for different
|
@@ -121,22 +127,19 @@ module SQLite3
|
|
121
127
|
warn(<<-eowarn) if $VERBOSE
|
122
128
|
#{caller[0]} is calling SQLite3::Database#execute with nil or multiple bind params
|
123
129
|
without using an array. Please switch to passing bind parameters as an array.
|
130
|
+
Support for bind parameters as *args will be removed in 2.0.0.
|
124
131
|
eowarn
|
125
132
|
end
|
126
133
|
|
127
134
|
prepare( sql ) do |stmt|
|
128
135
|
stmt.bind_params(bind_vars)
|
129
|
-
|
130
|
-
|
131
|
-
end
|
136
|
+
columns = stmt.columns
|
137
|
+
stmt = ResultSet.new(self, stmt).to_a if type_translation
|
132
138
|
|
133
139
|
if block_given?
|
134
140
|
stmt.each do |row|
|
135
141
|
if @results_as_hash
|
136
|
-
|
137
|
-
row.each_with_index { |r, i| h[i] = r }
|
138
|
-
|
139
|
-
yield h
|
142
|
+
yield type_translation ? row : ordered_map_for(columns, row)
|
140
143
|
else
|
141
144
|
yield row
|
142
145
|
end
|
@@ -144,8 +147,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
144
147
|
else
|
145
148
|
if @results_as_hash
|
146
149
|
stmt.map { |row|
|
147
|
-
h =
|
148
|
-
row.each_with_index { |r, i| h[i] = r }
|
150
|
+
h = type_translation ? row : ordered_map_for(columns, row)
|
149
151
|
|
150
152
|
# FIXME UGH TERRIBLE HACK!
|
151
153
|
h['unique'] = h['unique'].to_s if hack
|
@@ -197,7 +199,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
197
199
|
warn(<<-eowarn) if $VERBOSE
|
198
200
|
#{caller[0]} is calling SQLite3::Database#execute_batch with bind parameters
|
199
201
|
that are not a list of a hash. Please switch to passing bind parameters as an
|
200
|
-
array or hash.
|
202
|
+
array or hash. Support for this behavior will be removed in version 2.0.0.
|
201
203
|
eowarn
|
202
204
|
end
|
203
205
|
|
@@ -212,6 +214,7 @@ array or hash.
|
|
212
214
|
warn(<<-eowarn) if $VERBOSE
|
213
215
|
#{caller[0]} is calling SQLite3::Database#execute_batch with nil or multiple bind params
|
214
216
|
without using an array. Please switch to passing bind parameters as an array.
|
217
|
+
Support for this behavior will be removed in version 2.0.0.
|
215
218
|
eowarn
|
216
219
|
end
|
217
220
|
|
@@ -239,7 +242,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
239
242
|
#
|
240
243
|
# You must be sure to call +close+ on the ResultSet instance that is
|
241
244
|
# returned, or you could have problems with locks on the table. If called
|
242
|
-
# with a block, +close+ will be invoked implicitly when the block
|
245
|
+
# with a block, +close+ will be invoked implicitly when the block
|
243
246
|
# terminates.
|
244
247
|
def query( sql, bind_vars = [], *args )
|
245
248
|
|
@@ -253,6 +256,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
253
256
|
warn(<<-eowarn) if $VERBOSE
|
254
257
|
#{caller[0]} is calling SQLite3::Database#query with nil or multiple bind params
|
255
258
|
without using an array. Please switch to passing bind parameters as an array.
|
259
|
+
Support for this will be removed in version 2.0.0.
|
256
260
|
eowarn
|
257
261
|
end
|
258
262
|
|
@@ -273,8 +277,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
273
277
|
#
|
274
278
|
# See also #get_first_value.
|
275
279
|
def get_first_row( sql, *bind_vars )
|
276
|
-
execute( sql, *bind_vars )
|
277
|
-
nil
|
280
|
+
execute( sql, *bind_vars ).first
|
278
281
|
end
|
279
282
|
|
280
283
|
# A convenience method for obtaining the first value of the first row of a
|
@@ -298,7 +301,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
298
301
|
# arguments it needs (up to its arity).
|
299
302
|
#
|
300
303
|
# The block does not return a value directly. Instead, it will invoke
|
301
|
-
# the FunctionProxy#
|
304
|
+
# the FunctionProxy#result= method on the +func+ parameter and
|
302
305
|
# indicate the return value that way.
|
303
306
|
#
|
304
307
|
# Example:
|
@@ -337,7 +340,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
337
340
|
#
|
338
341
|
# The +finalize+ parameter must be a +proc+ object that accepts only a
|
339
342
|
# single parameter, the FunctionProxy instance representing the current
|
340
|
-
# function invocation. It should invoke FunctionProxy#
|
343
|
+
# function invocation. It should invoke FunctionProxy#result= to
|
341
344
|
# store the result of the function.
|
342
345
|
#
|
343
346
|
# Example:
|
@@ -349,7 +352,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
349
352
|
# end
|
350
353
|
#
|
351
354
|
# finalize do |func|
|
352
|
-
# func.
|
355
|
+
# func.result = func[ :total ] || 0
|
353
356
|
# end
|
354
357
|
# end
|
355
358
|
#
|
@@ -435,7 +438,7 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
435
438
|
# end
|
436
439
|
#
|
437
440
|
# def finalize( ctx )
|
438
|
-
# ctx.
|
441
|
+
# ctx.result = @total
|
439
442
|
# end
|
440
443
|
# end
|
441
444
|
#
|
@@ -521,6 +524,12 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
521
524
|
@transaction_active
|
522
525
|
end
|
523
526
|
|
527
|
+
# Returns +true+ if the database has been open in readonly mode
|
528
|
+
# A helper to check before performing any operation
|
529
|
+
def readonly?
|
530
|
+
@readonly
|
531
|
+
end
|
532
|
+
|
524
533
|
# A helper class for dealing with custom functions (see #create_function,
|
525
534
|
# #create_aggregate, and #create_aggregate_handler). It encapsulates the
|
526
535
|
# opaque function object that represents the current invocation. It also
|
@@ -566,5 +575,13 @@ without using an array. Please switch to passing bind parameters as an array.
|
|
566
575
|
@context[ key ] = value
|
567
576
|
end
|
568
577
|
end
|
578
|
+
|
579
|
+
private
|
580
|
+
|
581
|
+
def ordered_map_for columns, row
|
582
|
+
h = Hash[*columns.zip(row).flatten]
|
583
|
+
row.each_with_index { |r, i| h[i] = r }
|
584
|
+
h
|
585
|
+
end
|
569
586
|
end
|
570
587
|
end
|
data/lib/sqlite3/pragmas.rb
CHANGED
data/lib/sqlite3/translator.rb
CHANGED
@@ -35,6 +35,10 @@ module SQLite3
|
|
35
35
|
#
|
36
36
|
# The block should return the translated value.
|
37
37
|
def add_translator( type, &block ) # :yields: type, value
|
38
|
+
warn(<<-eowarn) if $VERBOSE
|
39
|
+
#{caller[0]} is calling `add_translator`.
|
40
|
+
Built in translators are deprecated and will be removed in version 2.0.0
|
41
|
+
eowarn
|
38
42
|
@translators[ type_name( type ) ] = block
|
39
43
|
end
|
40
44
|
|
data/lib/sqlite3/version.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module SQLite3
|
2
2
|
|
3
|
-
|
3
|
+
VERSION = '1.3.2'
|
4
|
+
|
5
|
+
module VersionProxy
|
4
6
|
|
5
7
|
MAJOR = 1
|
6
8
|
MINOR = 3
|
@@ -10,7 +12,14 @@ module SQLite3
|
|
10
12
|
STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." )
|
11
13
|
#:beta-tag:
|
12
14
|
|
13
|
-
VERSION =
|
15
|
+
VERSION = ::SQLite3::VERSION
|
14
16
|
end
|
15
17
|
|
18
|
+
def self.const_missing(name)
|
19
|
+
return super unless name == :Version
|
20
|
+
warn(<<-eowarn) if $VERBOSE
|
21
|
+
#{caller[0]}: SQLite::Version will be removed in sqlite3-ruby version 2.0.0
|
22
|
+
eowarn
|
23
|
+
VersionProxy
|
24
|
+
end
|
16
25
|
end
|
data/tasks/gem.rake
CHANGED
@@ -17,7 +17,7 @@ HOE = Hoe.spec 'sqlite3-ruby' do
|
|
17
17
|
self.history_file = 'CHANGELOG.rdoc'
|
18
18
|
self.extra_rdoc_files = FileList['*.rdoc', 'ext/**/*.c']
|
19
19
|
|
20
|
-
spec_extras[:required_ruby_version] = Gem::Requirement.new('>= 1.8.
|
20
|
+
spec_extras[:required_ruby_version] = Gem::Requirement.new('>= 1.8.7')
|
21
21
|
spec_extras[:required_rubygems_version] = '>= 1.3.5'
|
22
22
|
spec_extras[:extensions] = ["ext/sqlite3/extconf.rb"]
|
23
23
|
|
data/tasks/native.rake
CHANGED
@@ -4,7 +4,7 @@ require 'rake/extensiontask'
|
|
4
4
|
# NOTE: version used by cross compilation of Windows native extension
|
5
5
|
# It do not affect compilation under other operating systems
|
6
6
|
# The version indicated is the minimum DLL suggested for correct functionality
|
7
|
-
BINARY_VERSION = '3.
|
7
|
+
BINARY_VERSION = '3.7.3'
|
8
8
|
URL_VERSION = BINARY_VERSION.gsub('.', '_')
|
9
9
|
|
10
10
|
# build sqlite3_native C extension
|
data/test/test_backup.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
module SQLite3
|
4
|
+
class TestBackup < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@sdb = SQLite3::Database.new(':memory:')
|
7
|
+
@ddb = SQLite3::Database.new(':memory:')
|
8
|
+
@sdb.execute('CREATE TABLE foo (idx, val);');
|
9
|
+
@data = ('A'..'Z').map{|x|x * 40}
|
10
|
+
@data.each_with_index do |v, i|
|
11
|
+
@sdb.execute('INSERT INTO foo (idx, val) VALUES (?, ?);', [i, v])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_backup_step
|
16
|
+
b = SQLite3::Backup.new(@ddb, 'main', @sdb, 'main')
|
17
|
+
while b.step(1) == SQLite3::Constants::ErrorCode::OK
|
18
|
+
assert_not_equal(0, b.remaining)
|
19
|
+
end
|
20
|
+
assert_equal(0, b.remaining)
|
21
|
+
b.finish
|
22
|
+
assert_equal(@data.length, @ddb.execute('SELECT * FROM foo;').length)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_backup_all
|
26
|
+
b = SQLite3::Backup.new(@ddb, 'main', @sdb, 'main')
|
27
|
+
assert_equal(SQLite3::Constants::ErrorCode::DONE, b.step(-1))
|
28
|
+
assert_equal(0, b.remaining)
|
29
|
+
b.finish
|
30
|
+
assert_equal(@data.length, @ddb.execute('SELECT * FROM foo;').length)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/test_database.rb
CHANGED
@@ -7,6 +7,23 @@ module SQLite3
|
|
7
7
|
@db = SQLite3::Database.new(':memory:')
|
8
8
|
end
|
9
9
|
|
10
|
+
def test_get_first_row
|
11
|
+
assert_equal [1], @db.get_first_row('SELECT 1')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_get_first_row_with_type_translation_and_hash_results
|
15
|
+
@db.results_as_hash = true
|
16
|
+
assert_equal({0=>1, "1"=>1}, @db.get_first_row('SELECT 1'))
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_execute_with_type_translation_and_hash
|
20
|
+
@db.results_as_hash = true
|
21
|
+
rows = []
|
22
|
+
@db.execute('SELECT 1') { |row| rows << row }
|
23
|
+
|
24
|
+
assert_equal({0=>1, "1"=>1}, rows.first)
|
25
|
+
end
|
26
|
+
|
10
27
|
def test_encoding
|
11
28
|
assert @db.encoding, 'database has encoding'
|
12
29
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module SQLite3
|
4
|
+
class TestDatabaseReadonly < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
File.unlink 'test-readonly.db' if File.exists?('test-readonly.db')
|
7
|
+
@db = SQLite3::Database.new('test-readonly.db')
|
8
|
+
@db.execute("CREATE TABLE foos (id integer)")
|
9
|
+
@db.close
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
@db.close unless @db.closed?
|
14
|
+
File.unlink 'test-readonly.db'
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_open_readonly_database
|
18
|
+
@db = SQLite3::Database.new('test-readonly.db', :readonly => true)
|
19
|
+
assert @db.readonly?
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_insert_readonly_database
|
23
|
+
@db = SQLite3::Database.new('test-readonly.db', :readonly => true)
|
24
|
+
assert_raise(SQLite3::ReadOnlyException) do
|
25
|
+
@db.execute("INSERT INTO foos (id) VALUES (12)")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/test_integration.rb
CHANGED
@@ -59,58 +59,31 @@ class TC_ResultSet < Test::Unit::TestCase
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def test_next_type_translation
|
62
|
-
@db.type_translation = true
|
63
62
|
@result.reset( 1 )
|
64
63
|
assert_equal [ 1, "foo" ], @result.next
|
65
64
|
end
|
66
65
|
|
67
66
|
def test_next_type_translation_with_untyped_column
|
68
|
-
@db.type_translation = true
|
69
67
|
@db.query( "select count(*) from foo" ) do |result|
|
70
68
|
assert_equal [3], result.next
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
|
-
def test_type_translation_execute
|
75
|
-
@db.type_translation = true
|
76
|
-
@db.execute "create table bar ( a integer, b america )"
|
77
|
-
@db.execute "insert into bar (a, b) values (NULL, '1974-07-25 14:39:00')"
|
78
|
-
|
79
|
-
@db.translator.add_translator('america') do |type, thing|
|
80
|
-
'america'
|
81
|
-
end
|
82
|
-
|
83
|
-
assert_equal [[nil, 'america']], @db.execute("select * from bar")
|
84
|
-
end
|
85
|
-
|
86
72
|
def test_type_translation_with_null_column
|
87
|
-
|
73
|
+
time = '1974-07-25 14:39:00'
|
74
|
+
|
88
75
|
@db.execute "create table bar ( a integer, b time, c string )"
|
89
|
-
@db.execute "insert into bar (a, b, c) values (NULL, '
|
76
|
+
@db.execute "insert into bar (a, b, c) values (NULL, '#{time}', 'hello')"
|
90
77
|
@db.execute "insert into bar (a, b, c) values (1, NULL, 'hello')"
|
91
|
-
@db.execute "insert into bar (a, b, c) values (2, '
|
78
|
+
@db.execute "insert into bar (a, b, c) values (2, '#{time}', NULL)"
|
92
79
|
@db.query( "select * from bar" ) do |result|
|
93
|
-
assert_equal [nil,
|
80
|
+
assert_equal [nil, time, 'hello'], result.next
|
94
81
|
assert_equal [1, nil, 'hello'], result.next
|
95
|
-
assert_equal [2,
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_date_and_time_translation
|
100
|
-
@db.type_translation = true
|
101
|
-
@db.execute "create table bar ( a date, b datetime, c time, d timestamp )"
|
102
|
-
@db.execute "insert into bar (a, b, c, d) values ('1999-01-08', '1997-12-17 07:37:16', '07:37:16', '2004-10-19 10:23:54')"
|
103
|
-
@db.query( "select * from bar" ) do |result|
|
104
|
-
result = result.next
|
105
|
-
assert result[0].is_a?(Date)
|
106
|
-
assert result[1].is_a?(DateTime)
|
107
|
-
assert result[2].is_a?(Time)
|
108
|
-
assert result[3].is_a?(Time)
|
82
|
+
assert_equal [2, time, nil], result.next
|
109
83
|
end
|
110
84
|
end
|
111
85
|
|
112
86
|
def test_real_translation
|
113
|
-
@db.type_translation = true
|
114
87
|
@db.execute('create table foo_real(a real)')
|
115
88
|
@db.execute('insert into foo_real values (42)' )
|
116
89
|
@db.query('select a, sum(a), typeof(a), typeof(sum(a)) from foo_real') do |result|
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlite3-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 31
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
8
|
- 3
|
8
|
-
-
|
9
|
-
version: 1.3.
|
9
|
+
- 2
|
10
|
+
version: 1.3.2
|
10
11
|
platform: x86-mingw32
|
11
12
|
authors:
|
12
13
|
- Jamis Buck
|
@@ -16,16 +17,18 @@ autorequire:
|
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2010-
|
20
|
+
date: 2010-10-30 00:00:00 -07:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
23
24
|
name: rubyforge
|
24
25
|
prerelease: false
|
25
26
|
requirement: &id001 !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
26
28
|
requirements:
|
27
29
|
- - ">="
|
28
30
|
- !ruby/object:Gem::Version
|
31
|
+
hash: 7
|
29
32
|
segments:
|
30
33
|
- 2
|
31
34
|
- 0
|
@@ -37,9 +40,11 @@ dependencies:
|
|
37
40
|
name: rake-compiler
|
38
41
|
prerelease: false
|
39
42
|
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
40
44
|
requirements:
|
41
45
|
- - ~>
|
42
46
|
- !ruby/object:Gem::Version
|
47
|
+
hash: 3
|
43
48
|
segments:
|
44
49
|
- 0
|
45
50
|
- 7
|
@@ -51,14 +56,16 @@ dependencies:
|
|
51
56
|
name: hoe
|
52
57
|
prerelease: false
|
53
58
|
requirement: &id003 !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
54
60
|
requirements:
|
55
61
|
- - ">="
|
56
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 19
|
57
64
|
segments:
|
58
65
|
- 2
|
59
66
|
- 6
|
60
|
-
-
|
61
|
-
version: 2.6.
|
67
|
+
- 2
|
68
|
+
version: 2.6.2
|
62
69
|
type: :development
|
63
70
|
version_requirements: *id003
|
64
71
|
description: |-
|
@@ -78,12 +85,13 @@ extensions: []
|
|
78
85
|
extra_rdoc_files:
|
79
86
|
- Manifest.txt
|
80
87
|
- API_CHANGES.rdoc
|
81
|
-
- README.rdoc
|
82
88
|
- CHANGELOG.rdoc
|
89
|
+
- README.rdoc
|
90
|
+
- ext/sqlite3/backup.c
|
83
91
|
- ext/sqlite3/database.c
|
84
|
-
- ext/sqlite3/statement.c
|
85
|
-
- ext/sqlite3/sqlite3.c
|
86
92
|
- ext/sqlite3/exception.c
|
93
|
+
- ext/sqlite3/sqlite3.c
|
94
|
+
- ext/sqlite3/statement.c
|
87
95
|
files:
|
88
96
|
- API_CHANGES.rdoc
|
89
97
|
- CHANGELOG.rdoc
|
@@ -92,6 +100,8 @@ files:
|
|
92
100
|
- Manifest.txt
|
93
101
|
- README.rdoc
|
94
102
|
- Rakefile
|
103
|
+
- ext/sqlite3/backup.c
|
104
|
+
- ext/sqlite3/backup.h
|
95
105
|
- ext/sqlite3/database.c
|
96
106
|
- ext/sqlite3/database.h
|
97
107
|
- ext/sqlite3/exception.c
|
@@ -119,8 +129,10 @@ files:
|
|
119
129
|
- tasks/native.rake
|
120
130
|
- tasks/vendor_sqlite3.rake
|
121
131
|
- test/helper.rb
|
132
|
+
- test/test_backup.rb
|
122
133
|
- test/test_collation.rb
|
123
134
|
- test/test_database.rb
|
135
|
+
- test/test_database_readonly.rb
|
124
136
|
- test/test_deprecated.rb
|
125
137
|
- test/test_encoding.rb
|
126
138
|
- test/test_integration.rb
|
@@ -142,13 +154,13 @@ post_install_message: |+
|
|
142
154
|
=============================================================================
|
143
155
|
|
144
156
|
You've installed the binary version of sqlite3-ruby.
|
145
|
-
It was built using SQLite3 version 3.
|
157
|
+
It was built using SQLite3 version 3.7.3.
|
146
158
|
It's recommended to use the exact same version to avoid potential issues.
|
147
159
|
|
148
160
|
At the time of building this gem, the necessary DLL files where available
|
149
161
|
in the following download:
|
150
162
|
|
151
|
-
http://www.sqlite.org/sqlitedll-
|
163
|
+
http://www.sqlite.org/sqlitedll-3_7_3.zip
|
152
164
|
|
153
165
|
You can put the sqlite3.dll available in this package in your Ruby bin
|
154
166
|
directory, for example C:\Ruby\bin
|
@@ -161,18 +173,22 @@ rdoc_options:
|
|
161
173
|
require_paths:
|
162
174
|
- lib
|
163
175
|
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
none: false
|
164
177
|
requirements:
|
165
178
|
- - ">="
|
166
179
|
- !ruby/object:Gem::Version
|
180
|
+
hash: 57
|
167
181
|
segments:
|
168
182
|
- 1
|
169
183
|
- 8
|
170
|
-
-
|
171
|
-
version: 1.8.
|
184
|
+
- 7
|
185
|
+
version: 1.8.7
|
172
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
none: false
|
173
188
|
requirements:
|
174
189
|
- - ">="
|
175
190
|
- !ruby/object:Gem::Version
|
191
|
+
hash: 17
|
176
192
|
segments:
|
177
193
|
- 1
|
178
194
|
- 3
|
@@ -181,20 +197,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
197
|
requirements: []
|
182
198
|
|
183
199
|
rubyforge_project: sqlite3-ruby
|
184
|
-
rubygems_version: 1.3.
|
200
|
+
rubygems_version: 1.3.7
|
185
201
|
signing_key:
|
186
202
|
specification_version: 3
|
187
203
|
summary: This module allows Ruby programs to interface with the SQLite3 database engine (http://www.sqlite.org)
|
188
204
|
test_files:
|
189
|
-
- test/
|
190
|
-
- test/test_integration_open_close.rb
|
191
|
-
- test/test_database.rb
|
192
|
-
- test/test_integration.rb
|
205
|
+
- test/test_backup.rb
|
193
206
|
- test/test_collation.rb
|
194
|
-
- test/
|
195
|
-
- test/
|
207
|
+
- test/test_database.rb
|
208
|
+
- test/test_database_readonly.rb
|
196
209
|
- test/test_deprecated.rb
|
197
|
-
- test/test_statement_execute.rb
|
198
|
-
- test/test_integration_statement.rb
|
199
210
|
- test/test_encoding.rb
|
211
|
+
- test/test_integration.rb
|
212
|
+
- test/test_integration_open_close.rb
|
213
|
+
- test/test_integration_pending.rb
|
200
214
|
- test/test_integration_resultset.rb
|
215
|
+
- test/test_integration_statement.rb
|
216
|
+
- test/test_sqlite3.rb
|
217
|
+
- test/test_statement.rb
|
218
|
+
- test/test_statement_execute.rb
|