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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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