sqlite3-ruby 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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
@@ -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
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
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
 
@@ -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 "#{missing} is missing. Try 'port install sqlite3 +universal' " +
24
- "or 'yum install sqlite3-devel'"
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
 
@@ -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
  }
@@ -39,5 +39,6 @@ extern VALUE cSqlite3Blob;
39
39
  #include <database.h>
40
40
  #include <statement.h>
41
41
  #include <exception.h>
42
+ #include <backup.h>
42
43
 
43
44
  #endif
@@ -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
- # A boolean indicating whether or not type translation is enabled for this
58
- # database.
59
- attr_accessor :type_translation
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
- if type_translation
130
- stmt = ResultSet.new(self, stmt).to_a
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
- h = Hash[*stmt.columns.zip(row).flatten]
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 = Hash[*stmt.columns.zip(row).flatten]
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 ) { |row| return row }
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#set_result method on the +func+ parameter and
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#set_result to
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.set_result( func[ :total ] || 0 )
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.set_result( @total )
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
@@ -225,7 +225,7 @@ module SQLite3
225
225
 
226
226
  result = [] unless block_given?
227
227
  stmt.each do |row|
228
- new_row = Hash[*columns.zip(row).flatten]
228
+ new_row = Hash[columns.zip(row)]
229
229
 
230
230
  # FIXME: This should be removed but is required for older versions
231
231
  # of rails
@@ -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
 
@@ -1,6 +1,8 @@
1
1
  module SQLite3
2
2
 
3
- module Version
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 = '1.3.1'
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
@@ -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.6')
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
 
@@ -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.6.23.1'
7
+ BINARY_VERSION = '3.7.3'
8
8
  URL_VERSION = BINARY_VERSION.gsub('.', '_')
9
9
 
10
10
  # build sqlite3_native C extension
@@ -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
@@ -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
@@ -16,7 +16,6 @@ class TC_Database_Integration < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  def test_table_info_with_type_translation_active
19
- @db.type_translation = true
20
19
  assert_nothing_raised { @db.table_info("foo") }
21
20
  end
22
21
 
@@ -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
- @db.type_translation = true
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, '1974-07-25 14:39:00', 'hello')"
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, '1974-07-25 14:39:00', NULL)"
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, Time.local(1974, 7, 25, 14, 39, 0), 'hello'], result.next
80
+ assert_equal [nil, time, 'hello'], result.next
94
81
  assert_equal [1, nil, 'hello'], result.next
95
- assert_equal [2, Time.local(1974, 7, 25, 14, 39, 0), nil], result.next
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
- - 1
9
- version: 1.3.1
9
+ - 2
10
+ version: 1.3.2
10
11
  platform: ruby
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-07-10 00:00:00 -03:00
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
- - 0
61
- version: 2.6.0
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,18 +154,22 @@ rdoc_options:
142
154
  require_paths:
143
155
  - lib
144
156
  required_ruby_version: !ruby/object:Gem::Requirement
157
+ none: false
145
158
  requirements:
146
159
  - - ">="
147
160
  - !ruby/object:Gem::Version
161
+ hash: 57
148
162
  segments:
149
163
  - 1
150
164
  - 8
151
- - 6
152
- version: 1.8.6
165
+ - 7
166
+ version: 1.8.7
153
167
  required_rubygems_version: !ruby/object:Gem::Requirement
168
+ none: false
154
169
  requirements:
155
170
  - - ">="
156
171
  - !ruby/object:Gem::Version
172
+ hash: 17
157
173
  segments:
158
174
  - 1
159
175
  - 3
@@ -162,20 +178,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
178
  requirements: []
163
179
 
164
180
  rubyforge_project: sqlite3-ruby
165
- rubygems_version: 1.3.6
181
+ rubygems_version: 1.3.7
166
182
  signing_key:
167
183
  specification_version: 3
168
184
  summary: This module allows Ruby programs to interface with the SQLite3 database engine (http://www.sqlite.org)
169
185
  test_files:
170
- - test/test_sqlite3.rb
171
- - test/test_integration_open_close.rb
172
- - test/test_database.rb
173
- - test/test_integration.rb
186
+ - test/test_backup.rb
174
187
  - test/test_collation.rb
175
- - test/test_statement.rb
176
- - test/test_integration_pending.rb
188
+ - test/test_database.rb
189
+ - test/test_database_readonly.rb
177
190
  - test/test_deprecated.rb
178
- - test/test_statement_execute.rb
179
- - test/test_integration_statement.rb
180
191
  - test/test_encoding.rb
192
+ - test/test_integration.rb
193
+ - test/test_integration_open_close.rb
194
+ - test/test_integration_pending.rb
181
195
  - test/test_integration_resultset.rb
196
+ - test/test_integration_statement.rb
197
+ - test/test_sqlite3.rb
198
+ - test/test_statement.rb
199
+ - test/test_statement_execute.rb