amalgalite 0.7.7-x86-mswin32-60 → 0.8.0-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +9 -0
- data/lib/amalgalite/column.rb +19 -13
- data/lib/amalgalite/schema.rb +39 -5
- data/lib/amalgalite/statement.rb +7 -7
- data/lib/amalgalite/table.rb +46 -2
- data/lib/amalgalite/type_maps/default_map.rb +2 -1
- data/lib/amalgalite/version.rb +2 -2
- data/lib/amalgalite3.so +0 -0
- data/spec/schema_spec.rb +45 -0
- data/spec/tap_spec.rb +1 -1
- data/tasks/config.rb +1 -1
- data/tasks/distribution.rake +1 -1
- metadata +2 -2
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
|
data/lib/amalgalite/column.rb
CHANGED
@@ -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
|
data/lib/amalgalite/schema.rb
CHANGED
@@ -55,7 +55,8 @@ module Amalgalite
|
|
55
55
|
# load all the tables
|
56
56
|
#
|
57
57
|
def load_tables
|
58
|
-
@
|
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
|
117
|
-
|
118
|
-
|
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
|
data/lib/amalgalite/statement.rb
CHANGED
@@ -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
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
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
|
data/lib/amalgalite/table.rb
CHANGED
@@ -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 )
|
data/lib/amalgalite/version.rb
CHANGED
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
|
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
data/tasks/distribution.rake
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2009-03-23 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|