amalgalite 0.7.1 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +27 -20
- data/ext/amalgalite3.c +42 -0
- data/gemspec.rb +1 -1
- data/lib/amalgalite/column.rb +7 -2
- data/lib/amalgalite/database.rb +56 -11
- data/lib/amalgalite/schema.rb +61 -19
- data/lib/amalgalite/statement.rb +4 -3
- data/lib/amalgalite/table.rb +10 -0
- data/lib/amalgalite/type_maps/default_map.rb +1 -1
- data/lib/amalgalite/version.rb +1 -1
- data/spec/database_spec.rb +38 -1
- data/spec/schema_spec.rb +16 -1
- data/spec/sqlite3_spec.rb +18 -0
- metadata +3 -3
data/HISTORY
CHANGED
@@ -1,4 +1,22 @@
|
|
1
|
-
= Changelog
|
1
|
+
= Amalgalite Changelog
|
2
|
+
== Version 0.7.3 - 2009-02-08
|
3
|
+
|
4
|
+
=== Enhancements
|
5
|
+
|
6
|
+
* added Database#first_row_from
|
7
|
+
* added Database#first_value_from
|
8
|
+
|
9
|
+
=== Bug Fixes
|
10
|
+
|
11
|
+
* clean up ruby warnings when run with -w
|
12
|
+
* fix documenation on Database#execute
|
13
|
+
|
14
|
+
== Version 0.7.2 - 2009-01-24
|
15
|
+
=== Enhancements
|
16
|
+
|
17
|
+
* added quoting and escaping of text support, used for database drivers
|
18
|
+
* added ability to access columns of the schame in original definition order
|
19
|
+
|
2
20
|
== Version 0.7.1 - 2009-01-18
|
3
21
|
|
4
22
|
=== Enhancements
|
@@ -15,59 +33,50 @@
|
|
15
33
|
|
16
34
|
== Version 0.6.0 - 2009-01-10
|
17
35
|
|
18
|
-
===
|
36
|
+
=== Enhancements
|
19
37
|
|
20
38
|
* Added ability to define custom SQL functions implemented in Ruby
|
21
39
|
* Added ability to define custom SQL aggregates implemented in Ruby
|
22
40
|
* Added support for Ruby busy handlers
|
23
41
|
* Added database 'interrupt' support
|
24
42
|
* Added support for Ruby progress handlers
|
25
|
-
|
26
|
-
=== Minor Enhancement
|
27
|
-
|
28
43
|
* update to SQLite version 3.6.7
|
29
44
|
|
30
45
|
== Version 0.5.1 - 2008-11-30
|
31
46
|
|
32
|
-
===
|
47
|
+
=== Enhancements
|
33
48
|
|
34
49
|
* update to SQLite version 3.6.6.2
|
35
50
|
|
36
51
|
== Version 0.5.0 - 2008-11-16
|
37
52
|
|
38
|
-
===
|
53
|
+
=== Enhancements
|
39
54
|
|
40
55
|
* amalgalite-pack-into-db has been reworked into amalgalite-pack
|
41
56
|
* ruby code that is packed into a database for later requiring can now be
|
42
57
|
compressed
|
43
|
-
|
44
|
-
=== Minor Enhancement
|
45
|
-
|
46
58
|
* update to SQLite version 3.6.5
|
47
59
|
|
48
60
|
== Version 0.4.2 - 2008-10-12
|
49
61
|
|
50
|
-
===
|
62
|
+
=== Enhancements
|
51
63
|
|
52
64
|
* release of windows gem
|
53
65
|
|
54
66
|
== Version 0.4.1 - 2008-09-28
|
55
67
|
|
56
|
-
===
|
68
|
+
=== Enhancements
|
57
69
|
|
58
70
|
* update to SQLite3 version 3.6.3
|
59
71
|
* change rdoc template to darkfish
|
60
72
|
|
61
73
|
== Version 0.4.0 - 2008-09-14
|
62
74
|
|
63
|
-
===
|
75
|
+
=== Enhancements
|
64
76
|
* update to SQLite3 version 3.6.2 and enable the RTree option by default
|
65
77
|
* Amalgalite::Requires module allowing ruby code to be 'required' from columns in an SQLite database
|
66
78
|
* Amagalite::Requires::Bootstrap extension module enabling low level boot
|
67
79
|
strapping of the pure ruby Amalgalite code from an sqlite database
|
68
|
-
|
69
|
-
=== Minor Enhancements
|
70
|
-
|
71
80
|
* more indepth information about indexes is available via the Index class
|
72
81
|
* add support for sqlite3_status and sqlite3_db_status information
|
73
82
|
|
@@ -108,15 +117,13 @@
|
|
108
117
|
|
109
118
|
== Version 0.2.0 - 2008-07-04
|
110
119
|
|
111
|
-
===
|
120
|
+
=== Enhancements
|
112
121
|
* blob support, both incremental access and normal access
|
113
|
-
|
114
|
-
=== Minor Enhancements
|
115
122
|
* added examples/gem_db.rb script demonstrating taps and prepared statements
|
116
123
|
* added examples/schema-info.rb script demonstrating meta information
|
117
124
|
* added examples/blob.rb demonstrating incremental blob IO
|
118
125
|
* added access to the SQLite3 errcode and errmsg api
|
119
|
-
|
126
|
+
|
120
127
|
=== Bugfixes
|
121
128
|
* added taps.rb for requiring
|
122
129
|
* fixed prepared statement reset
|
data/ext/amalgalite3.c
CHANGED
@@ -81,6 +81,45 @@ VALUE am_sqlite3_set_temp_directory( VALUE self, VALUE new_dir )
|
|
81
81
|
return Qnil;
|
82
82
|
}
|
83
83
|
|
84
|
+
VALUE amalgalite_format_string( char* pattern, VALUE string )
|
85
|
+
{
|
86
|
+
VALUE to_s= rb_funcall( string, rb_intern("to_s"), 0 );
|
87
|
+
VALUE str = StringValue( to_s );
|
88
|
+
char *p = sqlite3_mprintf(pattern, RSTRING(str)->ptr);
|
89
|
+
VALUE rv = Qnil;
|
90
|
+
if ( NULL != p ) {
|
91
|
+
rv = rb_str_new2( p );
|
92
|
+
sqlite3_free( p );
|
93
|
+
} else {
|
94
|
+
rb_raise( rb_eNoMemError, "Unable to quote string" );
|
95
|
+
}
|
96
|
+
|
97
|
+
return rv;
|
98
|
+
}
|
99
|
+
/*
|
100
|
+
* call-seq:
|
101
|
+
* Amalgalite::SQLite.escape( string ) => escaped_string
|
102
|
+
*
|
103
|
+
* Takes the input string and escapes each ' (single quote) character by
|
104
|
+
* doubling it.
|
105
|
+
*/
|
106
|
+
VALUE am_sqlite3_escape( VALUE self, VALUE string )
|
107
|
+
{
|
108
|
+
return ( Qnil == string ) ? Qnil : amalgalite_format_string( "%q", string );
|
109
|
+
}
|
110
|
+
|
111
|
+
/*
|
112
|
+
* call-seq:
|
113
|
+
* Amalgalite::SQLite.quote( string ) => quoted-escaped string
|
114
|
+
*
|
115
|
+
* Takes the input string and surrounds it with single quotes, it also escapes
|
116
|
+
* each embedded single quote with double quotes.
|
117
|
+
*/
|
118
|
+
VALUE am_sqlite3_quote( VALUE self, VALUE string )
|
119
|
+
{
|
120
|
+
return ( Qnil == string ) ? Qnil : amalgalite_format_string( "%Q", string );
|
121
|
+
}
|
122
|
+
|
84
123
|
/*
|
85
124
|
* call-seq:
|
86
125
|
* Amalgalite::SQLite3.complete?( ... , opts = { :utf16 => false }) -> True, False
|
@@ -216,6 +255,9 @@ void Init_amalgalite3()
|
|
216
255
|
rb_define_module_function(mAS, "temp_directory", am_sqlite3_get_temp_directory, 0);
|
217
256
|
rb_define_module_function(mAS, "temp_directory=", am_sqlite3_set_temp_directory, 1);
|
218
257
|
|
258
|
+
rb_define_module_function(mAS, "escape", am_sqlite3_escape, 1);
|
259
|
+
rb_define_module_function(mAS, "quote", am_sqlite3_quote, 1);
|
260
|
+
|
219
261
|
/*
|
220
262
|
* class encapsulating a single Stat
|
221
263
|
*/
|
data/gemspec.rb
CHANGED
@@ -22,7 +22,7 @@ Amalgalite::GEM_SPEC = Gem::Specification.new do |spec|
|
|
22
22
|
# add dependencies here
|
23
23
|
# spec.add_dependency("rake", ">= 0.8.1")
|
24
24
|
spec.add_dependency("configuration", ">= 0.0.5")
|
25
|
-
spec.add_dependency("arrayfields", ">= 4.
|
25
|
+
spec.add_dependency("arrayfields", ">= 4.7.0")
|
26
26
|
|
27
27
|
|
28
28
|
if ext_conf = Configuration.for_if_exist?("extension") then
|
data/lib/amalgalite/column.rb
CHANGED
@@ -47,13 +47,18 @@ module Amalgalite
|
|
47
47
|
# true if the column is AUTO INCREMENT, false otherwise
|
48
48
|
attr_accessor :auto_increment
|
49
49
|
|
50
|
-
|
50
|
+
# The index (starting with 0) of this column in the table definition
|
51
|
+
# or result set
|
52
|
+
attr_accessor :order
|
53
|
+
|
54
|
+
##
|
51
55
|
# Create a column with its name and associated table
|
52
56
|
#
|
53
|
-
def initialize( db, table, name)
|
57
|
+
def initialize( db, table, name, order)
|
54
58
|
@db = db
|
55
59
|
@name = name
|
56
60
|
@table = table
|
61
|
+
@order = Float(order).to_i
|
57
62
|
@declared_data_type = nil
|
58
63
|
@default_value = nil
|
59
64
|
end
|
data/lib/amalgalite/database.rb
CHANGED
@@ -74,11 +74,11 @@ module Amalgalite
|
|
74
74
|
VALID.include? mode
|
75
75
|
end
|
76
76
|
end
|
77
|
-
|
78
|
-
include Amalgalite::SQLite3::Constants
|
79
77
|
|
80
|
-
|
81
|
-
|
78
|
+
include Amalgalite::SQLite3::Constants
|
79
|
+
|
80
|
+
# list of valid modes for opening an Amalgalite::Database
|
81
|
+
VALID_MODES = {
|
82
82
|
"r" => Open::READONLY,
|
83
83
|
"r+" => Open::READWRITE,
|
84
84
|
"w+" => Open::READWRITE | Open::CREATE,
|
@@ -138,6 +138,7 @@ module Amalgalite
|
|
138
138
|
@type_map = ::Amalgalite::TypeMaps::DefaultMap.new
|
139
139
|
@functions = Hash.new
|
140
140
|
@aggregates = Hash.new
|
141
|
+
@utf16 = false
|
141
142
|
|
142
143
|
unless VALID_MODES.keys.include?( mode )
|
143
144
|
raise InvalidModeError, "#{mode} is invalid, must be one of #{VALID_MODES.keys.join(', ')}"
|
@@ -181,15 +182,30 @@ module Amalgalite
|
|
181
182
|
@api.last_insert_rowid
|
182
183
|
end
|
183
184
|
|
185
|
+
##
|
186
|
+
# SQL escape the input string
|
187
|
+
#
|
188
|
+
def escape( s )
|
189
|
+
Amalgalite::SQLite3.escape( s )
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Surround the give string with single-quotes and escape any single-quotes
|
194
|
+
# in the string
|
195
|
+
def quote( s )
|
196
|
+
Amalgalite::SQLite3.quote( s )
|
197
|
+
end
|
198
|
+
|
184
199
|
##
|
185
200
|
# Is the database utf16 or not? A database is utf16 if the encoding is not
|
186
201
|
# UTF-8. Database can only be UTF-8 or UTF-16, and the default is UTF-8
|
187
202
|
#
|
188
203
|
def utf16?
|
189
|
-
unless @utf16.nil?
|
190
|
-
@utf16 = (encoding != "UTF-8")
|
191
|
-
end
|
192
204
|
return @utf16
|
205
|
+
#if @utf16.nil?
|
206
|
+
# @utf16 = (encoding != "UTF-8")
|
207
|
+
#end
|
208
|
+
#return @utf16
|
193
209
|
end
|
194
210
|
|
195
211
|
##
|
@@ -261,8 +277,13 @@ module Amalgalite
|
|
261
277
|
# If called with a block and there are result rows, then they are iteratively
|
262
278
|
# yielded to the block.
|
263
279
|
#
|
264
|
-
# If no block passed
|
265
|
-
#
|
280
|
+
# If no block is passed, then all the results are returned as an arrayfields
|
281
|
+
# instance. This is an array with field name access.
|
282
|
+
#
|
283
|
+
# If no block is passed, and there are no results, then an empty Array is
|
284
|
+
# returned.
|
285
|
+
#
|
286
|
+
# On an error an exception is thrown
|
266
287
|
#
|
267
288
|
# This is just a wrapper around the preparation of an Amalgalite Statement and
|
268
289
|
# iterating over the results.
|
@@ -310,6 +331,31 @@ module Amalgalite
|
|
310
331
|
self.profile_tap = nil
|
311
332
|
end
|
312
333
|
|
334
|
+
##
|
335
|
+
# Execute a sql statment, and only return the first row of results. This
|
336
|
+
# is a shorthand method when you only want a single row of results from a
|
337
|
+
# query.
|
338
|
+
#
|
339
|
+
# It is in all other was, exactly like #execute()
|
340
|
+
#
|
341
|
+
def first_row_from( sql, *bind_params )
|
342
|
+
stmt = prepare( sql )
|
343
|
+
stmt.bind( *bind_params)
|
344
|
+
row = stmt.next_row
|
345
|
+
stmt.close
|
346
|
+
return row
|
347
|
+
end
|
348
|
+
|
349
|
+
##
|
350
|
+
# Execute an sql statement, and return only the first column of the first
|
351
|
+
# row.
|
352
|
+
#
|
353
|
+
# It is in all other ways, exactly like #first_row_from()
|
354
|
+
#
|
355
|
+
def first_value_from( sql, *bind_params )
|
356
|
+
return first_row_from( sql, *bind_params).first
|
357
|
+
end
|
358
|
+
|
313
359
|
##
|
314
360
|
# call-seq:
|
315
361
|
# db.trace_tap = obj
|
@@ -842,7 +888,6 @@ module Amalgalite
|
|
842
888
|
end
|
843
889
|
alias :progress_handler :define_progress_handler
|
844
890
|
|
845
|
-
|
846
891
|
##
|
847
892
|
# call-seq:
|
848
893
|
# db.remove_progress_handler
|
@@ -851,6 +896,6 @@ module Amalgalite
|
|
851
896
|
def remove_progress_handler
|
852
897
|
@api.progress_handler( nil, nil )
|
853
898
|
end
|
854
|
-
|
899
|
+
end
|
855
900
|
end
|
856
901
|
|
data/lib/amalgalite/schema.rb
CHANGED
@@ -17,8 +17,7 @@ module Amalgalite
|
|
17
17
|
|
18
18
|
attr_reader :catalog
|
19
19
|
attr_reader :schema
|
20
|
-
|
21
|
-
attr_reader :views
|
20
|
+
attr_writer :dirty
|
22
21
|
attr_reader :db
|
23
22
|
|
24
23
|
#
|
@@ -28,32 +27,56 @@ module Amalgalite
|
|
28
27
|
@db = db
|
29
28
|
@catalog = catalog
|
30
29
|
@schema = schema
|
31
|
-
|
30
|
+
@tables = {}
|
31
|
+
@views = {}
|
32
|
+
@dirty = true
|
32
33
|
load_schema!
|
33
34
|
end
|
34
35
|
|
36
|
+
def dirty?() @dirty; end
|
37
|
+
def dirty!() @dirty = true; end
|
38
|
+
|
35
39
|
#
|
36
40
|
# load the schema from the database
|
37
41
|
def load_schema!
|
38
42
|
load_tables
|
39
43
|
load_views
|
44
|
+
@dirty = false
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# return the tables, reloading if dirty
|
49
|
+
def tables
|
50
|
+
load_schema! if dirty?
|
51
|
+
return @tables
|
40
52
|
end
|
41
53
|
|
42
54
|
##
|
43
55
|
# load all the tables
|
44
56
|
#
|
45
57
|
def load_tables
|
46
|
-
@
|
47
|
-
|
58
|
+
@db.execute("SELECT tbl_name FROM sqlite_master WHERE type = 'table'") do |table_info|
|
59
|
+
table = load_table( table_info['tbl_name'] )
|
60
|
+
table.indexes = load_indexes( table )
|
61
|
+
@tables[table.name] = table
|
62
|
+
end
|
63
|
+
return @tables
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Load a single table
|
68
|
+
def load_table( table_name )
|
69
|
+
rows = @db.execute("SELECT tbl_name, sql FROM sqlite_master WHERE type = 'table' AND tbl_name = ?", table_name)
|
70
|
+
table_info = rows.first
|
71
|
+
table = nil
|
72
|
+
if table_info then
|
48
73
|
table = Amalgalite::Table.new( table_info['tbl_name'], table_info['sql'] )
|
49
74
|
table.columns = load_columns( table )
|
50
75
|
table.schema = self
|
51
76
|
table.indexes = load_indexes( table )
|
52
|
-
|
53
|
-
@tables[table.name] = table
|
54
77
|
end
|
55
|
-
|
56
|
-
|
78
|
+
@tables[table.name] = table
|
79
|
+
return table
|
57
80
|
end
|
58
81
|
|
59
82
|
##
|
@@ -68,13 +91,13 @@ module Amalgalite
|
|
68
91
|
end
|
69
92
|
end
|
70
93
|
|
71
|
-
@db.execute("PRAGMA index_list( #{table.name} );") do |idx_list|
|
94
|
+
@db.execute("PRAGMA index_list( #{@db.quote(table.name)} );") do |idx_list|
|
72
95
|
idx = indexes[idx_list['name']]
|
73
|
-
|
96
|
+
|
74
97
|
idx.sequence_number = idx_list['seq']
|
75
98
|
idx.unique = Boolean.to_bool( idx_list['unique'] )
|
76
99
|
|
77
|
-
@db.execute("PRAGMA index_info( #{idx.name} );") do |col_info|
|
100
|
+
@db.execute("PRAGMA index_info( #{@db.quote(idx.name)} );") do |col_info|
|
78
101
|
idx.columns << table.columns[col_info['name']]
|
79
102
|
end
|
80
103
|
end
|
@@ -86,8 +109,9 @@ module Amalgalite
|
|
86
109
|
#
|
87
110
|
def load_columns( table )
|
88
111
|
cols = {}
|
89
|
-
|
90
|
-
|
112
|
+
idx = 0
|
113
|
+
@db.execute("PRAGMA table_info(#{@db.quote(table.name)})") do |row|
|
114
|
+
col = Amalgalite::Column.new( "main", table.name, row['name'], row['cid'])
|
91
115
|
|
92
116
|
col.default_value = row['dflt_value']
|
93
117
|
@db.api.table_column_metadata( "main", table.name, col.name ).each_pair do |key, value|
|
@@ -95,21 +119,39 @@ module Amalgalite
|
|
95
119
|
end
|
96
120
|
col.schema = self
|
97
121
|
cols[col.name] = col
|
122
|
+
idx += 1
|
98
123
|
end
|
99
|
-
cols
|
124
|
+
return cols
|
125
|
+
end
|
126
|
+
|
127
|
+
##
|
128
|
+
# return the views, reloading if dirty
|
129
|
+
#
|
130
|
+
def views
|
131
|
+
reload_schema! if dirty?
|
132
|
+
return @views
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# load a single view
|
137
|
+
#
|
138
|
+
def load_view( name )
|
139
|
+
rows = @db.execute("SELECT name, sql FROM sqlite_master WHERE type = 'view' AND name = ?", name )
|
140
|
+
view_info = rows.first
|
141
|
+
view = Amalgalite::View.new( view_info['name'], view_info['sql'] )
|
142
|
+
view.schema = self
|
143
|
+
return view
|
100
144
|
end
|
101
145
|
|
102
146
|
##
|
103
147
|
# load all the views for the database
|
104
148
|
#
|
105
149
|
def load_views
|
106
|
-
@views = {}
|
107
150
|
@db.execute("SELECT name, sql FROM sqlite_master WHERE type = 'view'") do |view_info|
|
108
|
-
view =
|
109
|
-
view.schema = self
|
151
|
+
view = load_view( view_info['name'] )
|
110
152
|
@views[view.name] = view
|
111
153
|
end
|
112
|
-
@views
|
154
|
+
return @views
|
113
155
|
end
|
114
156
|
end
|
115
157
|
end
|
data/lib/amalgalite/statement.rb
CHANGED
@@ -14,7 +14,6 @@ module Amalgalite
|
|
14
14
|
include ::Amalgalite::SQLite3::Constants
|
15
15
|
|
16
16
|
attr_reader :db
|
17
|
-
attr_reader :sql
|
18
17
|
attr_reader :api
|
19
18
|
|
20
19
|
class << self
|
@@ -29,11 +28,13 @@ module Amalgalite
|
|
29
28
|
#
|
30
29
|
def initialize( db, sql )
|
31
30
|
@db = db
|
32
|
-
prepare_method = @db.utf16? ? :prepare16 : :prepare
|
31
|
+
#prepare_method = @db.utf16? ? :prepare16 : :prepare
|
32
|
+
prepare_method = :prepare
|
33
33
|
@param_positions = {}
|
34
34
|
@stmt_api = @db.api.send( prepare_method, sql )
|
35
35
|
@blobs_to_write = []
|
36
36
|
@rowid_index = nil
|
37
|
+
@result_meta = nil
|
37
38
|
end
|
38
39
|
|
39
40
|
##
|
@@ -328,7 +329,7 @@ module Amalgalite
|
|
328
329
|
tbl_name = @stmt_api.column_table_name( idx )
|
329
330
|
col_name = @stmt_api.column_origin_name( idx )
|
330
331
|
|
331
|
-
column_meta.schema = ::Amalgalite::Column.new( db_name, tbl_name, col_name )
|
332
|
+
column_meta.schema = ::Amalgalite::Column.new( db_name, tbl_name, col_name, idx )
|
332
333
|
column_meta.schema.declared_data_type = @stmt_api.column_declared_type( idx )
|
333
334
|
|
334
335
|
# only check for rowid if we have a table name and it is not the
|
data/lib/amalgalite/table.rb
CHANGED
@@ -31,6 +31,16 @@ module Amalgalite
|
|
31
31
|
@indexes = {}
|
32
32
|
@columns = {}
|
33
33
|
end
|
34
|
+
|
35
|
+
# the Columns in original definition order
|
36
|
+
def columns_in_order
|
37
|
+
@columns.values.sort_by { |c| c.order }
|
38
|
+
end
|
39
|
+
|
40
|
+
# the column names in original definition order
|
41
|
+
def column_names
|
42
|
+
columns_in_order.map { |c| c.name }
|
43
|
+
end
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
@@ -22,7 +22,7 @@ module Amalgalite::TypeMaps
|
|
22
22
|
@methods_handling_sql_types ||= {
|
23
23
|
'date' => %w[ date ],
|
24
24
|
'datetime' => %w[ datetime ],
|
25
|
-
'time' => %w[ timestamp ],
|
25
|
+
'time' => %w[ timestamp time ],
|
26
26
|
'float' => %w[ double real numeric decimal ],
|
27
27
|
'integer' => %w[ integer tinyint smallint int int2 int4 int8 bigint serial bigserial ],
|
28
28
|
'string' => %w[ text char varchar character ],
|
data/lib/amalgalite/version.rb
CHANGED
data/spec/database_spec.rb
CHANGED
@@ -330,7 +330,6 @@ describe Amalgalite::Database do
|
|
330
330
|
end
|
331
331
|
|
332
332
|
rudeness.join
|
333
|
-
other.join
|
334
333
|
|
335
334
|
executions.should > 10
|
336
335
|
had_error.should be_an_instance_of( ::Amalgalite::SQLite3::Error )
|
@@ -381,4 +380,42 @@ describe Amalgalite::Database do
|
|
381
380
|
@iso_db.rollback
|
382
381
|
@iso_db.should_not be_in_transaction
|
383
382
|
end
|
383
|
+
|
384
|
+
it "can escape quoted strings" do
|
385
|
+
@iso_db.escape( "It's a happy day!" ).should == "It''s a happy day!"
|
386
|
+
end
|
387
|
+
|
388
|
+
it "can quote and escape single quoted strings" do
|
389
|
+
@iso_db.quote( "It's a happy day!" ).should == "'It''s a happy day!'"
|
390
|
+
end
|
391
|
+
|
392
|
+
it "can escape a symbol" do
|
393
|
+
@iso_db.escape( :stuff ).should == "stuff"
|
394
|
+
end
|
395
|
+
|
396
|
+
it "can quote a symbol" do
|
397
|
+
@iso_db.quote( :stuff ).should == "'stuff'"
|
398
|
+
end
|
399
|
+
|
400
|
+
it "returns the first row of results as a convenience" do
|
401
|
+
row = @iso_db.first_row_from("SELECT c.name, c.two_letter, count(*) AS count
|
402
|
+
FROM country c
|
403
|
+
JOIN subcountry sc
|
404
|
+
ON c.two_letter = sc.country
|
405
|
+
GROUP BY c.name, c.two_letter
|
406
|
+
ORDER BY count DESC")
|
407
|
+
row.length.should == 3
|
408
|
+
row[0].should == "United Kingdom"
|
409
|
+
row[1].should == "GB"
|
410
|
+
row[2].should == 232
|
411
|
+
row['name'].should == "United Kingdom"
|
412
|
+
row['two_letter'].should == "GB"
|
413
|
+
row['count'].should == 232
|
414
|
+
end
|
415
|
+
|
416
|
+
it "returns the first value of results as a conveinience" do
|
417
|
+
val = @iso_db.first_value_from("SELECT count(*) from subcountry ")
|
418
|
+
val.should == 3995
|
419
|
+
end
|
420
|
+
|
384
421
|
end
|
data/spec/schema_spec.rb
CHANGED
@@ -20,24 +20,39 @@ describe Amalgalite::Schema do
|
|
20
20
|
|
21
21
|
it "loads the schema of a database" do
|
22
22
|
schema = @iso_db.schema
|
23
|
+
schema.load_tables
|
23
24
|
schema.tables.size.should == 2
|
24
25
|
end
|
25
26
|
|
27
|
+
it "lazily loads new table schema" do
|
28
|
+
@iso_db.schema.tables.size.should == 2
|
29
|
+
sql = "CREATE TABLE t1 ( a, b, c )"
|
30
|
+
@iso_db.execute( sql )
|
31
|
+
@iso_db.schema.tables.size.should == 2
|
32
|
+
@iso_db.schema.dirty!
|
33
|
+
@iso_db.schema.tables['t1'].column_names.should == %w[ a b c ]
|
34
|
+
@iso_db.schema.tables.size.should == 3
|
35
|
+
end
|
36
|
+
|
26
37
|
it "loads the views in the database" do
|
27
38
|
sql = "CREATE VIEW v1 AS SELECT c.name, c.two_letter, s.name, s.subdivision FROM country AS c JOIN subcountry AS s ON c.two_letter = s.country"
|
28
39
|
@iso_db.execute( sql )
|
40
|
+
@iso_db.schema.load_views
|
29
41
|
@iso_db.schema.views.size.should == 1
|
30
42
|
@iso_db.schema.views["v1"].sql.should == sql
|
31
43
|
end
|
32
44
|
|
33
45
|
it "loads the tables and columns" do
|
34
|
-
@iso_db.schema.tables.size.should == 2
|
35
46
|
ct = @iso_db.schema.tables['country']
|
36
47
|
ct.name.should == "country"
|
37
48
|
ct.columns.size.should == 3
|
38
49
|
ct.indexes.size.should == 2
|
50
|
+
ct.column_names.should == %w[ name two_letter id ]
|
51
|
+
@iso_db.schema.tables.size.should == 2
|
52
|
+
|
39
53
|
|
40
54
|
ct.columns['two_letter'].should be_primary_key
|
55
|
+
ct.columns['two_letter'].declared_data_type.should == "TEXT"
|
41
56
|
ct.columns['name'].should_not be_nullable
|
42
57
|
ct.columns['name'].should be_not_null_constraint
|
43
58
|
ct.columns['name'].should_not be_has_default_value
|
data/spec/sqlite3_spec.rb
CHANGED
@@ -32,4 +32,22 @@ describe "Amalgalite::SQLite3" do
|
|
32
32
|
Amalgalite::SQLite3.temp_directory = nil
|
33
33
|
Amalgalite::SQLite3.temp_directory.should == nil
|
34
34
|
end
|
35
|
+
|
36
|
+
it "can escape quoted strings" do
|
37
|
+
Amalgalite::SQLite3.escape( "It's a happy day!" ).should == "It''s a happy day!"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can escape a symble into a string" do
|
41
|
+
Amalgalite::SQLite3.escape( :stuff ).should == "stuff"
|
42
|
+
Amalgalite::SQLite3.escape( :"stuff'n" ).should == "stuff''n"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can quote and escape single quoted strings" do
|
46
|
+
Amalgalite::SQLite3.quote( "It's a happy day!" ).should == "'It''s a happy day!'"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can quote and escape symbols" do
|
50
|
+
Amalgalite::SQLite3.quote( :stuff ).should == "'stuff'"
|
51
|
+
Amalgalite::SQLite3.quote( :"stuff'n" ).should == "'stuff''n'"
|
52
|
+
end
|
35
53
|
end
|
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.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
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-
|
12
|
+
date: 2009-02-08 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 4.
|
33
|
+
version: 4.7.0
|
34
34
|
version:
|
35
35
|
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
36
|
email: jeremy@hinegardner.org
|