sqlite3-ruby 1.3.1-x86-mswin32-60 → 1.3.2-x86-mswin32-60

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: x86-mswin32-60
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,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.6.23.1.
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-3_6_23_1.zip
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
- - 6
171
- version: 1.8.6
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.6
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/test_sqlite3.rb
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/test_statement.rb
195
- - test/test_integration_pending.rb
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