amalgalite 0.7.1-x86-mswin32-60 → 0.7.3-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 +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/lib/amalgalite3.so +0 -0
- 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/lib/amalgalite3.so
CHANGED
Binary file
|
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: 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-
|
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
|