amalgalite 0.7.7-x86-mswin32-60 → 0.8.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/HISTORY CHANGED
@@ -1,4 +1,13 @@
1
1
  = Amalgalite Changelog
2
+ == Version 0.8.0 - 2009-03-23
3
+
4
+ == Enhancements
5
+
6
+ * Add in support for obtaining limited schema information on temporary tables
7
+ and indexes
8
+ * Add support for returning the primary key columns of a table
9
+ * Other miscellaneous items to support the ActiveRecord adapter
10
+
2
11
  == Version 0.7.7 - 2009-03-03
3
12
 
4
13
  === Bug Fixes
@@ -38,15 +38,6 @@ module Amalgalite
38
38
  # the collation sequence name of the column
39
39
  attr_accessor :collation_sequence_name
40
40
 
41
- # true if the column has a NOT NULL constraint, false otherwise
42
- attr_accessor :not_null_constraint
43
-
44
- # true if the column is part of a primary key, false otherwise
45
- attr_accessor :primary_key
46
-
47
- # true if the column is AUTO INCREMENT, false otherwise
48
- attr_accessor :auto_increment
49
-
50
41
  # The index (starting with 0) of this column in the table definition
51
42
  # or result set
52
43
  attr_accessor :order
@@ -70,22 +61,37 @@ module Amalgalite
70
61
 
71
62
  # true if the column may have a NULL value
72
63
  def nullable?
73
- not_null_constraint == false
64
+ @not_null_constraint == false
65
+ end
66
+
67
+ # set whether or not the column has a not null constraint
68
+ def not_null_constraint=( other )
69
+ @not_null_constraint = Boolean.to_bool( other )
74
70
  end
75
71
 
76
72
  # true if the column as a NOT NULL constraint
77
73
  def not_null_constraint?
78
- not_null_constraint
74
+ @not_null_constraint
75
+ end
76
+
77
+ # set whether or not the column is a primary key column
78
+ def primary_key=( other )
79
+ @primary_key = Boolean.to_bool( other )
79
80
  end
80
81
 
81
82
  # true if the column is a primary key column
82
83
  def primary_key?
83
- primary_key
84
+ @primary_key
85
+ end
86
+
87
+ # set whether or not the column is auto increment
88
+ def auto_increment=( other )
89
+ @auto_increment = Boolean.to_bool( other )
84
90
  end
85
91
 
86
92
  # true if the column is auto increment
87
93
  def auto_increment?
88
- auto_increment
94
+ @auto_increment
89
95
  end
90
96
  end
91
97
  end
@@ -55,7 +55,8 @@ module Amalgalite
55
55
  # load all the tables
56
56
  #
57
57
  def load_tables
58
- @db.execute("SELECT tbl_name FROM sqlite_master WHERE type = 'table'") do |table_info|
58
+ @tables = {}
59
+ @db.execute("SELECT tbl_name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence'") do |table_info|
59
60
  table = load_table( table_info['tbl_name'] )
60
61
  table.indexes = load_indexes( table )
61
62
  @tables[table.name] = table
@@ -74,8 +75,18 @@ module Amalgalite
74
75
  table.columns = load_columns( table )
75
76
  table.schema = self
76
77
  table.indexes = load_indexes( table )
78
+ @tables[table.name] = table
79
+ else
80
+ # might be a temporary table
81
+ table = Amalgalite::Table.new( table_name, nil )
82
+ cols = load_columns( table )
83
+ if cols.size > 0 then
84
+ table.columns = cols
85
+ table.schema = self
86
+ table.indexes = load_indexes( table )
87
+ @tables[table.name] = table
88
+ end
77
89
  end
78
- @tables[table.name] = table
79
90
  return table
80
91
  end
81
92
 
@@ -94,6 +105,12 @@ module Amalgalite
94
105
  @db.execute("PRAGMA index_list( #{@db.quote(table.name)} );") do |idx_list|
95
106
  idx = indexes[idx_list['name']]
96
107
 
108
+ # temporary indexes do not show up in the previous list
109
+ if idx.nil? then
110
+ idx = Amalgalite::Index.new( idx_list['name'], nil, table )
111
+ indexes[idx_list['name']] = idx
112
+ end
113
+
97
114
  idx.sequence_number = idx_list['seq']
98
115
  idx.unique = Boolean.to_bool( idx_list['unique'] )
99
116
 
@@ -113,9 +130,26 @@ module Amalgalite
113
130
  @db.execute("PRAGMA table_info(#{@db.quote(table.name)})") do |row|
114
131
  col = Amalgalite::Column.new( "main", table.name, row['name'], row['cid'])
115
132
 
116
- col.default_value = row['dflt_value']
117
- @db.api.table_column_metadata( "main", table.name, col.name ).each_pair do |key, value|
118
- col.send("#{key}=", value)
133
+ col.default_value = row['dflt_value']
134
+
135
+ col.declared_data_type = row['type']
136
+ col.not_null_constraint = row['notnull']
137
+ col.primary_key = row['pk']
138
+
139
+ # need to remove leading and trailing ' or " from the default value
140
+ if col.default_value and col.default_value.kind_of?( String ) and ( col.default_value.length >= 2 ) then
141
+ fc = col.default_value[0].chr
142
+ lc = col.default_value[-1].chr
143
+ if fc == lc and ( fc == "'" || fc == '"' ) then
144
+ col.default_value = col.default_value[1..-2]
145
+ end
146
+ end
147
+
148
+ unless table.temporary? then
149
+ # get more exact information
150
+ @db.api.table_column_metadata( "main", table.name, col.name ).each_pair do |key, value|
151
+ col.send("#{key}=", value)
152
+ end
119
153
  end
120
154
  col.schema = self
121
155
  cols[col.name] = col
@@ -158,11 +158,11 @@ module Amalgalite
158
158
  check_parameter_count!( params.size )
159
159
  params.each_pair do | param, value |
160
160
  position = param_position_of( param )
161
- if position > 0 then
162
- bind_parameter_to( position, value )
163
- else
164
- raise Amalgalite::Error, "Unable to find parameter '#{param}' in SQL statement [#{sql}]"
165
- end
161
+ if position > 0 then
162
+ bind_parameter_to( position, value )
163
+ else
164
+ raise Amalgalite::Error, "Unable to find parameter '#{param}' in SQL statement [#{sql}]"
165
+ end
166
166
  end
167
167
  end
168
168
 
@@ -280,7 +280,7 @@ module Amalgalite
280
280
  col.schema.table,
281
281
  col.schema.name,
282
282
  @stmt_api.column_int64( @rowid_index ),
283
- "r"),
283
+ "r"),
284
284
  :column => col.schema)
285
285
  else
286
286
  value = Amalgalite::Blob.new( :string => @stmt_api.column_blob( idx ), :column => col.schema )
@@ -406,7 +406,7 @@ module Amalgalite
406
406
  # has been closed.
407
407
  #
408
408
  def close
409
- if open?
409
+ if open? then
410
410
  @stmt_api.close
411
411
  @open = false
412
412
  end
@@ -2,7 +2,7 @@
2
2
  # Copyright (c) 2008 Jeremy Hinegardner
3
3
  # All rights reserved. See LICENSE and/or COPYING for details.
4
4
  #++
5
-
5
+ require 'set'
6
6
  module Amalgalite
7
7
  #
8
8
  # a class representing the meta information about an SQLite table
@@ -25,13 +25,19 @@ module Amalgalite
25
25
  # in this table. keys are the column names
26
26
  attr_accessor :columns
27
27
 
28
- def initialize( name, sql )
28
+ def initialize( name, sql = nil )
29
29
  @name = name
30
30
  @sql = sql
31
31
  @indexes = {}
32
32
  @columns = {}
33
33
  end
34
34
 
35
+ # Is the table a temporary table or not
36
+ def temporary?
37
+ !sql
38
+ end
39
+
40
+
35
41
  # the Columns in original definition order
36
42
  def columns_in_order
37
43
  @columns.values.sort_by { |c| c.order }
@@ -41,6 +47,44 @@ module Amalgalite
41
47
  def column_names
42
48
  columns_in_order.map { |c| c.name }
43
49
  end
50
+
51
+ # the columns that make up the primary key
52
+ def primary_key_columns
53
+ @columns.values.find_all { |c| c.primary_key? }
54
+ end
55
+
56
+ # the array of colmuns that make up the primary key of the table
57
+ # since a primary key has an index, we loop over all the indexes for the
58
+ # table and pick the first one that is unique, and all the columns in the
59
+ # index have primary_key? as true.
60
+ #
61
+ # we do this instead of just looking for the columns where primary key is
62
+ # true because we want the columns in primary key order
63
+ def primary_key
64
+ unless @primary_key
65
+ pk_column_names = Set.new( primary_key_columns.collect { |c| c.name } )
66
+ unique_indexes = indexes.values.find_all { |i| i.unique? }
67
+
68
+ pk_result = []
69
+
70
+ unique_indexes.each do |idx|
71
+ idx_column_names = Set.new( idx.columns.collect { |c| c.name } )
72
+ r = idx_column_names ^ pk_column_names
73
+ if r.size == 0 then
74
+ pk_result = idx.columns
75
+ break
76
+ end
77
+ end
78
+
79
+ # no joy, see about just using all the columns that say the are primary
80
+ # keys
81
+ if pk_result.empty? then
82
+ pk_result = self.primary_key_columns
83
+ end
84
+ @primary_key = pk_result
85
+ end
86
+ return @primary_key
87
+ end
44
88
  end
45
89
  end
46
90
 
@@ -116,7 +116,8 @@ module Amalgalite::TypeMaps
116
116
  end
117
117
 
118
118
  ##
119
- # convert a string to a datetime
119
+ # convert a string to a datetime, if no timzone is found in the parsed
120
+ # string, set it to the local offset.
120
121
  #
121
122
  def datetime( str )
122
123
  DateTime.parse( str )
@@ -8,8 +8,8 @@ module Amalgalite
8
8
  module Version
9
9
 
10
10
  MAJOR = 0
11
- MINOR = 7
12
- BUILD = 7
11
+ MINOR = 8
12
+ BUILD = 0
13
13
 
14
14
  #
15
15
  # return the Version as an array of MAJOR, MINOR, BUILD
data/lib/amalgalite3.so CHANGED
Binary file
data/spec/schema_spec.rb CHANGED
@@ -42,6 +42,14 @@ describe Amalgalite::Schema do
42
42
  @iso_db.schema.views["v1"].sql.should eql(sql)
43
43
  end
44
44
 
45
+ it "removes quotes from around default values in columns" do
46
+ sql = "CREATE TABLE t1( d1 default 't' )"
47
+ @iso_db.execute( sql )
48
+ @iso_db.schema.dirty!
49
+ tt = @iso_db.schema.tables['t1']
50
+ tt.columns['d1'].default_value.should == "t"
51
+ end
52
+
45
53
  it "loads the tables and columns" do
46
54
  ct = @iso_db.schema.tables['country']
47
55
  ct.name.should eql("country")
@@ -59,6 +67,35 @@ describe Amalgalite::Schema do
59
67
  ct.columns['id'].should_not be_auto_increment
60
68
  end
61
69
 
70
+ it "knows what the primary key of a table is" do
71
+ ct = @iso_db.schema.tables['country']
72
+ ct.primary_key.should == [ ct.columns['two_letter'] ]
73
+ end
74
+
75
+ it "knows the primary key of a table even without an explicity unique index" do
76
+ sql = "CREATE TABLE u( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , other text )"
77
+ @iso_db.execute( sql )
78
+ @iso_db.schema.dirty!
79
+ ut = @iso_db.schema.tables['u']
80
+ ut.primary_key.should == [ ut.columns['id'] ]
81
+ end
82
+
83
+ it "knows the primary key of a temporary table" do
84
+ @iso_db.execute "CREATE TEMPORARY TABLE tt( a, b INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, c )"
85
+ @iso_db.schema.dirty!
86
+ tt = @iso_db.schema.load_table( 'tt' )
87
+ tt.primary_key.should == [ tt.columns['b'] ]
88
+
89
+ end
90
+
91
+ it "knows what the primary key of a table is when it is a multiple column primary key" do
92
+ sql = "CREATE TABLE m ( id1, id2, PRIMARY KEY (id2, id1) )"
93
+ @iso_db.execute( sql )
94
+ @iso_db.schema.dirty!
95
+ mt = @iso_db.schema.tables['m']
96
+ mt.primary_key.should == [ mt.columns['id2'], mt.columns['id1'] ]
97
+ end
98
+
62
99
  it "loads the indexes" do
63
100
  c = @iso_db.schema.tables['country']
64
101
  c.indexes.size.should eql(2)
@@ -72,4 +109,12 @@ describe Amalgalite::Schema do
72
109
  subc.indexes.size.should eql(3)
73
110
  subc.indexes['subcountry_country'].columns.first.should eql(@iso_db.schema.tables['subcountry'].columns['country'])
74
111
  end
112
+
113
+ it "can load the schema of a temporary table" do
114
+ @iso_db.execute "CREATE TEMPORARY TABLE tt( a, b, c )"
115
+ @iso_db.schema.dirty!
116
+ @iso_db.schema.tables['tt'].should be_nil
117
+ @iso_db.schema.load_table('tt').should_not be_nil
118
+ @iso_db.schema.tables['tt'].should be_temporary
119
+ end
75
120
  end
data/spec/tap_spec.rb CHANGED
@@ -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 == "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\ntest[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
data/tasks/config.rb CHANGED
@@ -61,7 +61,7 @@ Configuration.for("rubygem") {
61
61
  Configuration.for('test') {
62
62
  mode "spec"
63
63
  files Configuration.for("packaging").files.test
64
- options %w[ --format progress --color ]
64
+ options %w[ --format profile --color ]
65
65
  ruby_opts %w[ ]
66
66
  }
67
67
 
@@ -18,7 +18,7 @@ if pkg_config = Configuration.for_if_exist?("packaging") then
18
18
 
19
19
  desc "Install as a gem"
20
20
  task :install => [:clobber, :package] do
21
- sh "sudo gem install --local pkg/#{Amalgalite::GEM_SPEC.full_name}.gem"
21
+ sh "sudo gem install --local pkg/#{Amalgalite::GEM_SPEC.full_name}.gem --no-rdoc --no-ri"
22
22
  end
23
23
 
24
24
  desc "Uninstall gem"
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.7.7
4
+ version: 0.8.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-03-04 00:00:00 -07:00
12
+ date: 2009-03-23 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency