amalgalite 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/gemspec.rb CHANGED
@@ -20,10 +20,11 @@ Amalgalite::GEM_SPEC = Gem::Specification.new do |spec|
20
20
  spec.executables = pkg.files.bin.collect { |b| File.basename(b) }
21
21
 
22
22
  # add dependencies here
23
- # spec.add_dependency("rake", ">= 0.8.1")
24
- spec.add_dependency("configuration", ">= 0.0.5")
25
- spec.add_dependency("arrayfields", ">= 4.7.0")
23
+ spec.add_dependency("arrayfields", "~> 4.7.0")
26
24
 
25
+ spec.add_development_dependency("rake", "~> 0.8.4")
26
+ spec.add_development_dependency("configuration", "~> 0.0.5")
27
+ spec.add_development_dependency("rspec", "~> 1.2.2")
27
28
 
28
29
  if ext_conf = Configuration.for_if_exist?("extension") then
29
30
  spec.extensions << ext_conf.configs
@@ -542,7 +542,7 @@ module Amalgalite
542
542
  #
543
543
  # True nexted transactions are available through the _savepoint_ method.
544
544
  #
545
- def transaction( mode = TransactionBehavior::DEFERRED )
545
+ def transaction( mode = TransactionBehavior::DEFERRED, &block )
546
546
  raise Amalgalite::Error, "Invalid transaction behavior mode #{mode}" unless TransactionBehavior.valid?( mode )
547
547
 
548
548
  # if already in a transaction, no need to start a new one.
@@ -566,6 +566,17 @@ module Amalgalite
566
566
  return in_transaction?
567
567
  end
568
568
  end
569
+ alias :deferred_transaction :transaction
570
+
571
+ # helper for an immediate transaction
572
+ def immediate_transaction( &block )
573
+ transaction( TransactionBehavior::IMMEDIATE, &block )
574
+ end
575
+
576
+ # helper for an exclusive transaction
577
+ def exclusive_transaction( &block )
578
+ transaction( TransactionBehavior::EXCLUSIVE, &block )
579
+ end
569
580
 
570
581
  ##
571
582
  # call-seq:
@@ -895,6 +906,38 @@ module Amalgalite
895
906
  def remove_progress_handler
896
907
  @api.progress_handler( nil, nil )
897
908
  end
909
+
910
+ ##
911
+ # call-seq:
912
+ # db.replicate_to( ":memory:" ) -> new_db
913
+ # db.replicate_to( "/some/location/my.db" ) -> new_db
914
+ # db.replicate_to( Amalgalite::Database.new( "/my/backup.db" ) ) -> new_db
915
+ #
916
+ # replicate_to() takes a single argument, either a String or an
917
+ # Amalgalite::Database. It returns the replicated database object. If
918
+ # given a String, it will truncate that database if it already exists.
919
+ #
920
+ # Replicate the current database to another location, this can be used for a
921
+ # number of purposes:
922
+ #
923
+ # * load an sqlite database from disk into memory
924
+ # * snaphost an in memory db and save it to disk
925
+ # * backup on sqlite database to another location
926
+ #
927
+ def replicate_to( location )
928
+ to_db = nil
929
+ case location
930
+ when String
931
+ to_db = Amalgalite::Database.new( location )
932
+ when Amalgalite::Database
933
+ to_db = location
934
+ else
935
+ raise ArgumentError, "replicate_to( #{location} ) must be a String or a Database"
936
+ end
937
+
938
+ @api.replicate_to( to_db.api )
939
+ return to_db
940
+ end
898
941
  end
899
942
  end
900
943
 
@@ -56,6 +56,7 @@ module Amalgalite
56
56
  #
57
57
  def stddev
58
58
  begin
59
+ return 0.0 if ( 1 == @n )
59
60
  Math.sqrt( (@sumsq - ( @sum * @sum / @n)) / (@n-1) )
60
61
  rescue Errno::EDOM
61
62
  return 0.0
@@ -82,7 +83,7 @@ module Amalgalite
82
83
  # return a string containing the sampler summary
83
84
  #
84
85
  def to_s
85
- "[%s] => sum: %d, sumsq: %d, n: %d, mean: %0.6f, stddev: %0.6f, min: %d, max: %d" % to_a
86
+ "[%s] => sum: %d, sumsq: %d, n: %d, mean: %0.6f, stddev: %0.6f, min: %d, max: %d" % self.to_a
86
87
  end
87
88
 
88
89
  end
@@ -41,8 +41,8 @@ module Amalgalite
41
41
  end
42
42
 
43
43
  def dump_profile
44
- samplers.each do |s|
45
- io.puts s.to_s
44
+ samplers.each_pair do |k,v|
45
+ io.puts v.to_s
46
46
  end
47
47
  end
48
48
 
@@ -8,7 +8,7 @@ module Amalgalite
8
8
  module Version
9
9
 
10
10
  MAJOR = 0
11
- MINOR = 8
11
+ MINOR = 9
12
12
  BUILD = 0
13
13
 
14
14
  #
@@ -199,9 +199,11 @@ describe Amalgalite::Database do
199
199
  r.should eql(42)
200
200
  end
201
201
 
202
- it "returns the result of the transaction when a block is yielded" do
203
- db = Amalgalite::Database.new( SpecInfo.test_db )
204
- (db.transaction { 42 }).should eql(42)
202
+ %w[ transaction deferred_transaction immediate_transaction exclusive_transaction ].each do |trans|
203
+ it "returns the result of the #{trans} when a block is yielded" do
204
+ db = Amalgalite::Database.new( SpecInfo.test_db )
205
+ (db.send( trans ){ 42 }).should eql(42)
206
+ end
205
207
  end
206
208
 
207
209
  it "#reload_schema!" do
@@ -295,15 +297,19 @@ describe Amalgalite::Database do
295
297
 
296
298
  describe "#remove_function" do
297
299
  it "unregisters a single function by name and arity" do
298
- @iso_db.define_function( "rtest" ) do
299
- "rtest called"
300
+ @iso_db.define_function( "rtest1" ) do
301
+ "rtest1 called"
300
302
  end
303
+
301
304
  @iso_db.functions.size.should eql(1 )
302
305
 
303
- r = @iso_db.execute( "select rtest() AS r" )
304
- r.first['r'].should eql("rtest called")
305
- @iso_db.remove_function("rtest", -1)
306
- lambda { @iso_db.execute( "select rtest() as r" )}.should raise_error( ::Amalgalite::SQLite3::Error, /no such function: rtest/ )
306
+ r = @iso_db.execute( "select rtest1() AS r" )
307
+ r.first['r'].should eql("rtest1 called")
308
+ #@iso_db.remove_function("rtest1", -1)
309
+ # the arity of rtest1 is different in 1.9 vs. 1.8
310
+ @iso_db.remove_function("rtest1")
311
+
312
+ lambda { @iso_db.execute( "select rtest1() as r" )}.should raise_error( ::Amalgalite::SQLite3::Error, /no such function: rtest1/ )
307
313
  @iso_db.functions.size.should eql(0)
308
314
  end
309
315
 
@@ -345,7 +351,6 @@ describe Amalgalite::Database do
345
351
  end
346
352
 
347
353
  it "can interrupt another thread that is also running in this database" do
348
- had_error = nil
349
354
  executions = 0
350
355
  other = Thread.new( @iso_db ) do |db|
351
356
  loop do
@@ -353,7 +358,7 @@ describe Amalgalite::Database do
353
358
  db.execute("select count(id) from country")
354
359
  executions += 1
355
360
  rescue => e
356
- had_error = e
361
+ Thread.current[:had_error] = e
357
362
  break
358
363
  end
359
364
  end
@@ -367,8 +372,8 @@ describe Amalgalite::Database do
367
372
  rudeness.join
368
373
 
369
374
  executions.should > 10
370
- had_error.should be_an_instance_of( ::Amalgalite::SQLite3::Error )
371
- had_error.message.should =~ / interrupted/
375
+ other[:had_error].should be_an_instance_of( ::Amalgalite::SQLite3::Error )
376
+ other[:had_error].message.should =~ / interrupted/
372
377
  end
373
378
 
374
379
  it "savepoints are considered 'in_transaction'" do
@@ -464,4 +469,26 @@ describe Amalgalite::Database do
464
469
  val.should eql(3995)
465
470
  end
466
471
 
472
+ it "replicates a database to memory" do
473
+ mem_db = @iso_db.replicate_to( ":memory:" )
474
+ @iso_db.close
475
+ val = mem_db.first_value_from("SELECT count(*) from subcountry" )
476
+ val.should eql(3995)
477
+ end
478
+
479
+ it "replicates a database to a database file" do
480
+ all_sub = @iso_db.execute("SELECT count(*) as cnt from subcountry").first['cnt']
481
+
482
+ fdb = Amalgalite::Database.new( SpecInfo.test_db )
483
+ @iso_db.replicate_to( fdb )
484
+ @iso_db.close
485
+
486
+ File.exist?( SpecInfo.test_db ).should == true
487
+ fdb.execute("SELECT count(*) as cnt from subcountry").first['cnt'].should == all_sub
488
+ end
489
+
490
+ it "raises an error if it is given an invalid location to replicate to" do
491
+ lambda { @iso_db.replicate_to( false ) }.should raise_error( ArgumentError, /must be a String or a Database/ )
492
+ end
493
+
467
494
  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 eql(3006010)
8
+ Amalgalite::SQLite3::Version.to_i.should eql(3006012)
9
9
  Amalgalite::SQLite3::Version::MAJOR.should eql(3)
10
10
  Amalgalite::SQLite3::Version::MINOR.should eql(6)
11
- Amalgalite::SQLite3::Version::RELEASE.should eql(10)
11
+ Amalgalite::SQLite3::Version::RELEASE.should eql(12)
12
12
  Amalgalite::SQLite3::Version.to_a.should have(3).items
13
13
  end
14
14
  end
@@ -9,12 +9,12 @@ describe "Amalgalite::SQLite3" do
9
9
 
10
10
  it "knows if an SQL statement is complete" do
11
11
  Amalgalite::SQLite3.complete?("SELECT * FROM sometable;").should eql(true)
12
- Amalgalite::SQLite3.complete?("SELECT * FROM sometable;", :utf16 => true).should eql(true)
12
+ #Amalgalite::SQLite3.complete?("SELECT * FROM sometable;", :utf16 => true).should eql(true)
13
13
  end
14
14
 
15
15
  it "knows if an SQL statement is not complete" do
16
16
  Amalgalite::SQLite3.complete?("SELECT * FROM sometable ").should eql(false)
17
- Amalgalite::SQLite3.complete?("SELECT * FROM sometable WHERE ", :utf16 => true).should eql(false)
17
+ #Amalgalite::SQLite3.complete?("SELECT * FROM sometable WHERE ", :utf16 => true).should eql(false)
18
18
  end
19
19
 
20
20
  it "can produce random data" do
@@ -32,7 +32,7 @@ describe Amalgalite::Taps::StringIO do
32
32
  s = ::Amalgalite::Taps::StringIO.new
33
33
  s.profile( 'test', 42 )
34
34
  s.dump_profile
35
- s.string.should eql("42 : test\ntest[test] => sum: 42, sumsq: 1764, n: 1, mean: 42.000000, stddev: 0.000000, min: 42, max: 42\n")
35
+ s.string.should eql("42 : test\n[test] => sum: 42, sumsq: 1764, n: 1, mean: 42.000000, stddev: 0.000000, min: 42, max: 42\n")
36
36
  end
37
37
 
38
38
  it "has a stdout tap" do
@@ -83,7 +83,7 @@ Configuration.for('rdoc') {
83
83
  files Configuration.for('packaging').files.rdoc
84
84
  main_page files.first
85
85
  title Configuration.for('project').name
86
- options %w[ --line-numbers --inline-source -T darkfish ]
86
+ options %w[ ]
87
87
  output_dir "doc"
88
88
  }
89
89
 
@@ -31,7 +31,6 @@ if ext_config = Configuration.for_if_exist?('extension') then
31
31
  conf = parts.last
32
32
  Dir.chdir(path.dirname) do |d|
33
33
  ruby conf.to_s
34
- #sh "rake default"
35
34
  sh "make"
36
35
  end
37
36
  end
@@ -53,6 +52,20 @@ if ext_config = Configuration.for_if_exist?('extension') then
53
52
  end
54
53
  end
55
54
 
55
+ desc "Build the extension for ruby1.9"
56
+ task :build19 => :clobber do
57
+ ext_config.configs.each do |extension|
58
+ path = Pathname.new( extension )
59
+ parts = path.split
60
+ conf = parts.last
61
+ Dir.chdir( path.dirname ) do |d|
62
+ sh "ruby1.9 -I. extconf.rb"
63
+ sh "make"
64
+ end
65
+
66
+ end
67
+ end
68
+
56
69
  task :clean do
57
70
  ext_config.configs.each do |extension|
58
71
  path = Pathname.new(extension)
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.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Hinegardner
@@ -9,28 +9,48 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-23 00:00:00 -06:00
12
+ date: 2009-04-05 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: configuration
16
+ name: arrayfields
17
17
  type: :runtime
18
18
  version_requirement:
19
19
  version_requirements: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - ">="
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 4.7.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.4
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: configuration
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ~>
22
42
  - !ruby/object:Gem::Version
23
43
  version: 0.0.5
24
44
  version:
25
45
  - !ruby/object:Gem::Dependency
26
- name: arrayfields
27
- type: :runtime
46
+ name: rspec
47
+ type: :development
28
48
  version_requirement:
29
49
  version_requirements: !ruby/object:Gem::Requirement
30
50
  requirements:
31
- - - ">="
51
+ - - ~>
32
52
  - !ruby/object:Gem::Version
33
- version: 4.7.0
53
+ version: 1.2.2
34
54
  version:
35
55
  description: Amalgalite embeds the SQLite database engine in a ruby extension. There is no need to install SQLite separately. Look in the examples/ directory to see * general usage * blob io * schema information * custom functions * custom aggregates * requiring ruby code from a database Also Scroll through Amalgalite::Database for a quick example, and a general overview of the API.
36
56
  email: jeremy@hinegardner.org
@@ -91,7 +111,6 @@ files:
91
111
  - ext/amalgalite3_requires_bootstrap.c
92
112
  - ext/amalgalite3_statement.c
93
113
  - ext/sqlite3.c
94
- - ext/test_error.c
95
114
  - ext/amalgalite3.h
96
115
  - ext/sqlite3.h
97
116
  - ext/sqlite3_options.h
@@ -184,10 +203,6 @@ has_rdoc: true
184
203
  homepage: http://copiousfreetime.rubyforge.org/amalgalite/
185
204
  post_install_message:
186
205
  rdoc_options:
187
- - --line-numbers
188
- - --inline-source
189
- - -T
190
- - darkfish
191
206
  - --main
192
207
  - README
193
208
  require_paths:
@@ -1,62 +0,0 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include "sqlite3.h"
4
- /**
5
- * gcc -o test_error test_error.c sqlite3.c
6
- * ./test_error
7
- */
8
-
9
- int test_progress_callback( void* data )
10
- {
11
- fprintf(stderr, "Progress handler callback\n");
12
- return 1;
13
- }
14
-
15
-
16
- void abort_if_error( sqlite3* db, char* msg, int rc )
17
- {
18
- if ( SQLITE_OK != rc ) {
19
- fprintf( stderr, "%s: [%d] -> %s\n", msg, sqlite3_errcode( db ), sqlite3_errmsg( db ) );
20
- sqlite3_close( db );
21
- exit( 1 );
22
- }
23
- }
24
-
25
- int main( int argc, char **argv )
26
- {
27
- sqlite3 *db;
28
- sqlite3_stmt *stmt;
29
- const char *tail;
30
- char *errmsg;
31
- int rc;
32
-
33
- printf("SQLite Version: %s\n", sqlite3_libversion() );
34
-
35
- rc = sqlite3_open_v2( ":memory:", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL );
36
- abort_if_error( db, "Failure opening database", rc );
37
-
38
- rc = sqlite3_exec( db, "CREATE TABLE t1( c1, c2 );", NULL, NULL, NULL );
39
- abort_if_error( db, "Failure creating table t1", rc );
40
-
41
- sqlite3_progress_handler( db, 5, test_progress_callback, (void*) NULL );
42
-
43
- rc = sqlite3_prepare_v2( db, "SELECT * FROM t1", -1, &stmt, &tail );
44
- abort_if_error( db, "Failure preparing statement", rc );
45
-
46
- rc = sqlite3_step( stmt );
47
- if ( SQLITE_ROW != rc ) {
48
- printf( "Return code from sqlite3_step : %d\n", rc );
49
- printf( "Before finalizing error code is : %d\n", sqlite3_errcode( db ));
50
- printf( "Before finalizing error message is : %s\n", sqlite3_errmsg( db ));
51
- }
52
-
53
- rc = sqlite3_finalize( stmt );
54
- if ( SQLITE_OK != rc ) {
55
- printf( "Return value from sqlite3_finalize : %d\n", rc );
56
- printf( "After finalizing errcode is : %d\n", sqlite3_errcode( db ));
57
- printf( "After finalizing error message is : %s\n", sqlite3_errmsg( db ));
58
- }
59
- sqlite3_close( db );
60
- return 0;
61
-
62
- }