amalgalite 0.6.0-x86-mswin32-60 → 0.7.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
data/ext/sqlite3.h CHANGED
@@ -30,7 +30,7 @@
30
30
  ** the version number) and changes its name to "sqlite3.h" as
31
31
  ** part of the build process.
32
32
  **
33
- ** @(#) $Id: sqlite.h.in,v 1.420 2008/12/16 13:46:30 drh Exp $
33
+ ** @(#) $Id: sqlite.h.in,v 1.421 2008/12/30 06:24:58 danielk1977 Exp $
34
34
  */
35
35
  #ifndef _SQLITE3_H_
36
36
  #define _SQLITE3_H_
@@ -107,8 +107,8 @@ extern "C" {
107
107
  ** with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
108
108
  ** are the major version, minor version, and release number.
109
109
  */
110
- #define SQLITE_VERSION "3.6.7"
111
- #define SQLITE_VERSION_NUMBER 3006007
110
+ #define SQLITE_VERSION "3.6.10"
111
+ #define SQLITE_VERSION_NUMBER 3006010
112
112
 
113
113
  /*
114
114
  ** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
@@ -2397,7 +2397,7 @@ int sqlite3_set_authorizer(
2397
2397
  #define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
2398
2398
  #define SQLITE_READ 20 /* Table Name Column Name */
2399
2399
  #define SQLITE_SELECT 21 /* NULL NULL */
2400
- #define SQLITE_TRANSACTION 22 /* NULL NULL */
2400
+ #define SQLITE_TRANSACTION 22 /* Operation NULL */
2401
2401
  #define SQLITE_UPDATE 23 /* Table Name Column Name */
2402
2402
  #define SQLITE_ATTACH 24 /* Filename NULL */
2403
2403
  #define SQLITE_DETACH 25 /* Database Name NULL */
@@ -2407,6 +2407,7 @@ int sqlite3_set_authorizer(
2407
2407
  #define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
2408
2408
  #define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
2409
2409
  #define SQLITE_FUNCTION 31 /* NULL Function Name */
2410
+ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
2410
2411
  #define SQLITE_COPY 0 /* No longer used */
2411
2412
 
2412
2413
  /*
@@ -12,13 +12,13 @@ module Amalgalite
12
12
  # If you choose to use Aggregate as a parent class of your SQL scalar function
13
13
  # implementation you must:
14
14
  #
15
- # * implement _initalize()_ with 0 arguments
15
+ # * implement _initalize_ with 0 arguments
16
16
  # * set the @arity data member
17
17
  # * set the @name data member
18
18
  # * implement _step_ with arity of +@arity+
19
19
  # * implement _finalize_ with arity of 0
20
20
  #
21
- # For instance to implement a _unique_word_count(X)_ aggregate function you could
21
+ # For instance to implement a <i>unique_word_count(X)</i> aggregate function you could
22
22
  # implement it as:
23
23
  #
24
24
  # class UniqueWordCount < ::Amalgalite::Aggregate
@@ -492,10 +492,12 @@ module Amalgalite
492
492
  #
493
493
  # If no block is passed in then you are on your own.
494
494
  #
495
- # Nested transactions are not supported by SQLite, but they are faked here.
495
+ # Nesting a transaaction via the _transaction_ method are no-ops.
496
496
  # If you call transaction within a transaction, no new transaction is
497
497
  # started, the current one is just continued.
498
- #
498
+ #
499
+ # True nexted transactions are available through the _savepoint_ method.
500
+ #
499
501
  def transaction( mode = TransactionBehavior::DEFERRED )
500
502
  raise Amalgalite::Error, "Invalid transaction behavior mode #{mode}" unless TransactionBehavior.valid?( mode )
501
503
 
@@ -520,18 +522,89 @@ module Amalgalite
520
522
  end
521
523
  end
522
524
 
525
+ ##
526
+ # call-seq:
527
+ # db.savepoint( 'mypoint' ) -> db
528
+ # db.savepoint( 'mypoint' ) do |db_in_savepoint|
529
+ # ...
530
+ # end
531
+ #
532
+ # Much of the following documentation is para-phrased from
533
+ # http://sqlite.org/lang_savepoint.html
534
+ #
535
+ # Savepoints are a method of creating transactions, similar to _transaction_
536
+ # except that they may be nested.
537
+ #
538
+ # * Every savepoint must have a name, +to_s+ is called on the method
539
+ # argument
540
+ # * A savepoint does not need to be initialized inside a _transaction_. If
541
+ # it is not inside a _transaction_ it behaves exactly as if a DEFERRED
542
+ # transaction had been started.
543
+ # * If a block is passed to _saveponit_ then when the block exists, it is
544
+ # guaranteed that either a 'RELEASE' or 'ROLLBACK TO name' has been executed.
545
+ # * If any exception happens during the savepoint transaction, then a
546
+ # 'ROLLOBACK TO' is issued when the block closes.
547
+ # * If no exception happens during the transaction then a 'RELEASE name' is
548
+ # issued upon leaving the block
549
+ #
550
+ # If no block is passed in then you are on your own.
551
+ #
552
+ def savepoint( name )
553
+ point_name = name.to_s.strip
554
+ raise Amalgalite::Error, "Invalid savepoint name '#{name}'" unless point_name and point_name.length > 1
555
+ execute( "SAVEPOINT #{point_name};")
556
+ if block_given? then
557
+ begin
558
+ return ( yield self )
559
+ ensure
560
+ if $! then
561
+ rollback_to( point_name )
562
+ raise $!
563
+ else
564
+ release( point_name )
565
+ end
566
+ end
567
+ else
568
+ return in_transaction?
569
+ end
570
+ end
571
+
572
+ ##
573
+ # call-seq:
574
+ # db.release( 'mypoint' )
575
+ #
576
+ # Release a savepoint. This is similar to a _commit_ but only for
577
+ # savepoints. All savepoints up the savepoint stack and include the name
578
+ # savepoint being released are 'committed' to the transaction. There are
579
+ # several ways of thinking about release and they are all detailed in the
580
+ # sqlite documentation: http://sqlite.org/lang_savepoint.html
581
+ #
582
+ def release( point_name )
583
+ execute( "RELEASE SAVEPOINT #{point_name}" ) if in_transaction?
584
+ end
585
+
586
+ ##
587
+ # call-seq:
588
+ # db.rollback_to( point_name )
589
+ #
590
+ # Rollback to a savepoint. The transaction is not cancelled, the
591
+ # transaction is restarted.
592
+ def rollback_to( point_name )
593
+ execute( "ROLLBACK TO SAVEPOINT #{point_name}" )
594
+ end
595
+
523
596
  ##
524
597
  # Commit a transaction
525
598
  #
526
599
  def commit
527
- execute( "COMMIT" ) if in_transaction?
600
+ execute( "COMMIT TRANSACTION" ) if in_transaction?
528
601
  end
529
602
 
530
603
  ##
531
604
  # Rollback a transaction
532
605
  #
533
606
  def rollback
534
- execute( "ROLLBACK" ) if in_transaction?
607
+ execute( "ROLLBACK TRANSACTION" ) if in_transaction?
535
608
  end
536
609
 
537
610
  ##
@@ -350,8 +350,12 @@ module Amalgalite
350
350
  #
351
351
  def is_column_rowid?( table_name, column_name )
352
352
  column_schema = @db.schema.tables[table_name].columns[column_name]
353
- if column_schema.primary_key? and column_schema.declared_data_type and column_schema.declared_data_type.upcase == "INTEGER" then
354
- return true
353
+ if column_schema then
354
+ if column_schema.primary_key? and column_schema.declared_data_type and column_schema.declared_data_type.upcase == "INTEGER" then
355
+ return true
356
+ end
357
+ else
358
+ return true if Statement.rowid_column_names.include?( column_name.upcase )
355
359
  end
356
360
  return false
357
361
  end
@@ -8,7 +8,7 @@ module Amalgalite
8
8
  module Version
9
9
 
10
10
  MAJOR = 0
11
- MINOR = 6
11
+ MINOR = 7
12
12
  BUILD = 0
13
13
 
14
14
  #
data/lib/amalgalite3.so CHANGED
Binary file
@@ -98,7 +98,7 @@ describe "Aggregate SQL Functions" do
98
98
  it "does not allow outrageous arity" do
99
99
  class AggregateTest3 < AggregateTest1
100
100
  def name() "atest3"; end
101
- def arity() 101; end
101
+ def arity() 128; end
102
102
  end
103
103
  lambda { @iso_db.define_aggregate("atest3", AggregateTest3 ) }.should raise_error( ::Amalgalite::SQLite3::Error, /SQLITE_ERROR .* bad parameters/ )
104
104
  end
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
+ require File.expand_path( File.join( File.dirname(__FILE__), 'spec_helper'))
3
4
 
4
5
  $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
5
6
  require 'amalgalite'
@@ -248,7 +249,7 @@ describe Amalgalite::Database do
248
249
  it "does not allow outrageous arity" do
249
250
  class FunctionTest3 < ::Amalgalite::Function
250
251
  def initialize
251
- super( 'ftest3', 101 )
252
+ super( 'ftest3', 128 )
252
253
  end
253
254
  def call( *args) ; end
254
255
  end
@@ -322,11 +323,62 @@ describe Amalgalite::Database do
322
323
  end
323
324
  end
324
325
  end
325
- sleep 0.01
326
- @iso_db.interrupt!
326
+
327
+ rudeness = Thread.new( @iso_db ) do |db|
328
+ sleep 0.05
329
+ @iso_db.interrupt!
330
+ end
331
+
332
+ rudeness.join
327
333
  other.join
334
+
328
335
  executions.should > 10
329
336
  had_error.should be_an_instance_of( ::Amalgalite::SQLite3::Error )
330
337
  had_error.message.should =~ / interrupted/
331
338
  end
339
+
340
+ it "savepoints are considered 'in_transaction'" do
341
+ @iso_db.savepoint( 'test1' ) do |db|
342
+ db.should be_in_transaction
343
+ end
344
+ end
345
+
346
+ it "releases a savepoint" do
347
+ us_sub = @iso_db.execute( "select count(1) as cnt from subcountry where country = 'US'" ).first['cnt']
348
+ us_sub.should == 57
349
+ other_sub = @iso_db.execute( "select count(1) as cnt from subcountry where country != 'US'" ).first['cnt']
350
+
351
+ @iso_db.transaction
352
+ @iso_db.savepoint( "t1" ) do |s|
353
+ s.execute("DELETE FROM subcountry where country = 'US'")
354
+ end
355
+
356
+ all_sub = @iso_db.execute("SELECT count(*) as cnt from subcountry").first['cnt']
357
+
358
+ all_sub.should == other_sub;
359
+ @iso_db.rollback
360
+ all_sub = @iso_db.execute("SELECT count(*) as cnt from subcountry").first['cnt']
361
+ all_sub.should == ( us_sub + other_sub )
362
+
363
+ end
364
+ it "rolls back a savepoint" do
365
+ all_sub = @iso_db.execute("SELECT count(*) as cnt from subcountry").first['cnt']
366
+ lambda {
367
+ @iso_db.savepoint( "t1" ) do |s|
368
+ s.execute("DELETE FROM subcountry where country = 'US'")
369
+ raise "sample error"
370
+ end
371
+ }.should raise_error( StandardError, /sample error/ )
372
+
373
+ @iso_db.execute("SELECT count(*) as cnt from subcountry").first['cnt'].should == all_sub
374
+ end
375
+
376
+ it "rolling back the outermost savepoint is still 'in_transaction'" do
377
+ @iso_db.savepoint( "t1" )
378
+ @iso_db.execute("DELETE FROM subcountry where country = 'US'")
379
+ @iso_db.rollback_to( "t1" )
380
+ @iso_db.should be_in_transaction
381
+ @iso_db.rollback
382
+ @iso_db.should_not be_in_transaction
383
+ end
332
384
  end
@@ -5,10 +5,10 @@ describe "Amalgalite::SQLite3::Version" do
5
5
  it "should have the sqlite3 version" do
6
6
  Amalgalite::SQLite3::VERSION.should =~ /\d\.\d\.\d/
7
7
  Amalgalite::SQLite3::Version.to_s.should =~ /\d\.\d\.\d/
8
- Amalgalite::SQLite3::Version.to_i.should == 3006007
8
+ Amalgalite::SQLite3::Version.to_i.should == 3006010
9
9
  Amalgalite::SQLite3::Version::MAJOR.should == 3
10
10
  Amalgalite::SQLite3::Version::MINOR.should == 6
11
- Amalgalite::SQLite3::Version::RELEASE.should == 7
11
+ Amalgalite::SQLite3::Version::RELEASE.should == 10
12
12
  Amalgalite::SQLite3::Version.to_a.should have(3).items
13
13
  end
14
14
  end
data/spec/sqlite3_spec.rb CHANGED
@@ -20,4 +20,16 @@ describe "Amalgalite::SQLite3" do
20
20
  it "can produce random data" do
21
21
  Amalgalite::SQLite3.randomness( 42 ).size.should == 42
22
22
  end
23
+
24
+ it "has nil for the default sqlite temporary directory" do
25
+ Amalgalite::SQLite3.temp_directory.should == nil
26
+ end
27
+
28
+ it "can set the temporary directory" do
29
+ Amalgalite::SQLite3.temp_directory.should == nil
30
+ Amalgalite::SQLite3.temp_directory = "/tmp/testing"
31
+ Amalgalite::SQLite3.temp_directory.should == "/tmp/testing"
32
+ Amalgalite::SQLite3.temp_directory = nil
33
+ Amalgalite::SQLite3.temp_directory.should == nil
34
+ end
23
35
  end
@@ -123,6 +123,32 @@ describe Amalgalite::Statement do
123
123
  stmt.close
124
124
  end
125
125
 
126
+ it "can select the rowid from the table" do
127
+ db = Amalgalite::Database.new( ":memory:" )
128
+ db.execute( "create table t1(c1,c2,c3)" )
129
+ db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
130
+ rows = db.execute( "select rowid,* from t1")
131
+ rows.size.should == 1
132
+ rows.first['rowid'].should == 1
133
+ rows.first['c1'].should == 1
134
+ rows.first['c3'].should == 'abc'
135
+ end
136
+
137
+ it "shows that the rowid column is rowid column" do
138
+ db = Amalgalite::Database.new( ":memory:" )
139
+ db.execute( "create table t1(c1,c2,c3)" )
140
+ db.execute("insert into t1(c1,c2,c3) values (1,2,'abc')")
141
+ db.prepare( "select oid,* from t1" ) do |stmt|
142
+ rows = stmt.execute
143
+ stmt.should be_using_rowid_column
144
+ end
145
+
146
+ db.prepare( "select * from t1" ) do |stmt|
147
+ stmt.execute
148
+ stmt.should_not be_using_rowid_column
149
+ end
150
+ end
151
+
126
152
  it "has index based access to the result set" do
127
153
  @iso_db.prepare("SELECT * FROM country WHERE id = ? ORDER BY name ") do |stmt|
128
154
  all_rows = stmt.execute( 891 )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amalgalite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: x86-mswin32-60
6
6
  authors:
7
7
  - Jeremy Hinegardner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-10 00:00:00 -07:00
12
+ date: 2009-01-18 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency