activerecord 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +102 -1
- data/dev-utils/eval_debugger.rb +12 -7
- data/lib/active_record.rb +2 -0
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/associations.rb +74 -53
- data/lib/active_record/associations.rb.orig +555 -0
- data/lib/active_record/associations/association_collection.rb +74 -15
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +86 -25
- data/lib/active_record/associations/has_many_association.rb +48 -50
- data/lib/active_record/base.rb +56 -24
- data/lib/active_record/connection_adapters/abstract_adapter.rb +46 -3
- data/lib/active_record/connection_adapters/mysql_adapter.rb +15 -15
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +128 -135
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +76 -78
- data/lib/active_record/deprecated_associations.rb +1 -1
- data/lib/active_record/fixtures.rb +137 -54
- data/lib/active_record/observer.rb +1 -1
- data/lib/active_record/support/inflector.rb +8 -0
- data/lib/active_record/transactions.rb +31 -14
- data/rakefile +13 -5
- data/test/abstract_unit.rb +7 -1
- data/test/associations_test.rb +99 -27
- data/test/base_test.rb +15 -1
- data/test/connections/native_sqlite/connection.rb +24 -14
- data/test/deprecated_associations_test.rb +3 -4
- data/test/deprecated_associations_test.rb.orig +334 -0
- data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
- data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
- data/test/fixtures/bad_fixtures/blank_line +3 -0
- data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
- data/test/fixtures/bad_fixtures/missing_value +1 -0
- data/test/fixtures/company_in_module.rb +15 -1
- data/test/fixtures/db_definitions/mysql.sql +2 -1
- data/test/fixtures/db_definitions/postgresql.sql +2 -1
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/developers_projects/david_action_controller +2 -1
- data/test/fixtures/developers_projects/david_active_record +2 -1
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/project.rb +2 -1
- data/test/fixtures/projects/action_controller +1 -1
- data/test/fixtures/topics/second +1 -1
- data/test/fixtures_test.rb +63 -4
- data/test/inflector_test.rb +17 -0
- data/test/modules_test.rb +8 -0
- data/test/transactions_test.rb +16 -4
- metadata +10 -2
@@ -1,6 +1,29 @@
|
|
1
1
|
require 'benchmark'
|
2
2
|
require 'date'
|
3
3
|
|
4
|
+
# Method that requires a library, ensuring that rubygems is loaded
|
5
|
+
# This is used in the database adaptors to require DB drivers. Reasons:
|
6
|
+
# (1) database drivers are the only third-party library that Rails depend upon
|
7
|
+
# (2) they are often installed as gems
|
8
|
+
def require_library_or_gem(library_name)
|
9
|
+
begin
|
10
|
+
require library_name
|
11
|
+
rescue LoadError => cannot_require
|
12
|
+
# 1. Requiring the module is unsuccessful, maybe it's a gem and nobody required rubygems yet. Try.
|
13
|
+
begin
|
14
|
+
require 'rubygems'
|
15
|
+
rescue LoadError => rubygems_not_installed
|
16
|
+
raise cannot_require
|
17
|
+
end
|
18
|
+
# 2. Rubygems is installed and loaded. Try to load the library again
|
19
|
+
begin
|
20
|
+
require library_name
|
21
|
+
rescue LoadError => gem_not_installed
|
22
|
+
raise cannot_require
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
4
27
|
module ActiveRecord
|
5
28
|
class Base
|
6
29
|
class ConnectionSpecification #:nodoc:
|
@@ -9,7 +32,7 @@ module ActiveRecord
|
|
9
32
|
@config, @adapter_method = config, adapter_method
|
10
33
|
end
|
11
34
|
end
|
12
|
-
|
35
|
+
|
13
36
|
# The class -> [adapter_method, config] map
|
14
37
|
@@defined_connections = {}
|
15
38
|
|
@@ -251,6 +274,21 @@ module ActiveRecord
|
|
251
274
|
return rt
|
252
275
|
end
|
253
276
|
|
277
|
+
# Wrap a block in a transaction. Returns result of block.
|
278
|
+
def transaction
|
279
|
+
begin
|
280
|
+
if block_given?
|
281
|
+
begin_db_transaction
|
282
|
+
result = yield
|
283
|
+
commit_db_transaction
|
284
|
+
result
|
285
|
+
end
|
286
|
+
rescue Exception => database_transaction_rollback
|
287
|
+
rollback_db_transaction
|
288
|
+
raise
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
254
292
|
# Begins the transaction (and turns off auto-committing).
|
255
293
|
def begin_db_transaction() end
|
256
294
|
|
@@ -263,16 +301,20 @@ module ActiveRecord
|
|
263
301
|
|
264
302
|
def quote(value, column = nil)
|
265
303
|
case value
|
266
|
-
when String then "'#{value
|
304
|
+
when String then "'#{quote_string(value)}'" # ' (for ruby-mode)
|
267
305
|
when NilClass then "NULL"
|
268
306
|
when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
|
269
307
|
when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
|
270
308
|
when Float, Fixnum, Bignum, Date then "'#{value.to_s}'"
|
271
309
|
when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
|
272
|
-
else "'#{value.to_yaml
|
310
|
+
else "'#{quote_string(value.to_yaml)}'"
|
273
311
|
end
|
274
312
|
end
|
275
313
|
|
314
|
+
def quote_string(s)
|
315
|
+
s.gsub(/\\/, '\&\&').gsub(/'/, "''") # ' (for ruby-mode)
|
316
|
+
end
|
317
|
+
|
276
318
|
def quote_column_name(name)
|
277
319
|
return name
|
278
320
|
end
|
@@ -322,5 +364,6 @@ module ActiveRecord
|
|
322
364
|
log_entry
|
323
365
|
end
|
324
366
|
end
|
367
|
+
|
325
368
|
end
|
326
369
|
end
|
@@ -1,25 +1,29 @@
|
|
1
1
|
require 'active_record/connection_adapters/abstract_adapter'
|
2
2
|
require 'parsedate'
|
3
3
|
|
4
|
-
begin
|
5
|
-
begin
|
6
|
-
# Only include the MySQL driver if one hasn't already been loaded
|
7
|
-
require 'mysql' unless self.class.const_defined?(:Mysql)
|
8
|
-
rescue LoadError
|
9
|
-
# Only use the supplied backup Ruby/MySQL driver if no driver is already in place
|
10
|
-
require 'active_record/vendor/mysql'
|
11
|
-
end
|
12
|
-
|
13
4
|
module ActiveRecord
|
14
5
|
class Base
|
15
6
|
# Establishes a connection to the database that's used by all Active Record objects
|
16
7
|
def self.mysql_connection(config) # :nodoc:
|
8
|
+
unless self.class.const_defined?(:Mysql)
|
9
|
+
begin
|
10
|
+
# Only include the MySQL driver if one hasn't already been loaded
|
11
|
+
require_library_or_gem 'mysql'
|
12
|
+
rescue LoadError => cannot_require_mysql
|
13
|
+
# Only use the supplied backup Ruby/MySQL driver if no driver is already in place
|
14
|
+
begin
|
15
|
+
require 'active_record/vendor/mysql'
|
16
|
+
rescue LoadError
|
17
|
+
raise cannot_require_mysql
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
17
21
|
symbolize_strings_in_hash(config)
|
18
22
|
host = config[:host]
|
19
23
|
port = config[:port]
|
20
24
|
socket = config[:socket]
|
21
|
-
username = config[:username]
|
22
|
-
password = config[:password]
|
25
|
+
username = config[:username] ? config[:username].to_s : 'root'
|
26
|
+
password = config[:password].to_s
|
23
27
|
|
24
28
|
if config.has_key?(:database)
|
25
29
|
database = config[:database]
|
@@ -125,7 +129,3 @@ module ActiveRecord
|
|
125
129
|
end
|
126
130
|
end
|
127
131
|
end
|
128
|
-
|
129
|
-
rescue LoadError
|
130
|
-
# MySQL is not available, so neither should the adapter be
|
131
|
-
end
|
@@ -13,165 +13,158 @@
|
|
13
13
|
require 'active_record/connection_adapters/abstract_adapter'
|
14
14
|
require 'parsedate'
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
database = config[:database]
|
32
|
-
else
|
33
|
-
raise ArgumentError, "No database specified. Missing argument: database."
|
34
|
-
end
|
35
|
-
|
36
|
-
ConnectionAdapters::PostgreSQLAdapter.new(
|
37
|
-
PGconn.connect(host, port, "", "", database, username, password), logger
|
38
|
-
)
|
16
|
+
module ActiveRecord
|
17
|
+
class Base
|
18
|
+
# Establishes a connection to the database that's used by all Active Record objects
|
19
|
+
def self.postgresql_connection(config) # :nodoc:
|
20
|
+
require_library_or_gem 'postgres' unless self.class.const_defined?(:PGconn)
|
21
|
+
symbolize_strings_in_hash(config)
|
22
|
+
host = config[:host]
|
23
|
+
port = config[:port] || 5432 unless host.nil?
|
24
|
+
username = config[:username].to_s
|
25
|
+
password = config[:password].to_s
|
26
|
+
|
27
|
+
if config.has_key?(:database)
|
28
|
+
database = config[:database]
|
29
|
+
else
|
30
|
+
raise ArgumentError, "No database specified. Missing argument: database."
|
39
31
|
end
|
32
|
+
|
33
|
+
ConnectionAdapters::PostgreSQLAdapter.new(
|
34
|
+
PGconn.connect(host, port, "", "", database, username, password), logger
|
35
|
+
)
|
40
36
|
end
|
37
|
+
end
|
41
38
|
|
42
|
-
|
43
|
-
|
39
|
+
module ConnectionAdapters
|
40
|
+
class PostgreSQLAdapter < AbstractAdapter # :nodoc:
|
41
|
+
def select_all(sql, name = nil)
|
42
|
+
select(sql, name)
|
43
|
+
end
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
def select_one(sql, name = nil)
|
46
|
+
result = select(sql, name)
|
47
|
+
result.nil? ? nil : result.first
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
50
|
+
def columns(table_name, name = nil)
|
51
|
+
table_structure(table_name).inject([]) do |columns, field|
|
52
|
+
columns << Column.new(field[0], field[2], field[1])
|
53
|
+
columns
|
52
54
|
end
|
55
|
+
end
|
53
56
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
57
|
+
def insert(sql, name = nil, pk = nil, id_value = nil)
|
58
|
+
execute(sql, name = nil)
|
59
|
+
table = sql.split(" ", 4)[2]
|
60
|
+
return id_value || last_insert_id(table, pk)
|
61
|
+
end
|
60
62
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
return id_value || last_insert_id(table, pk)
|
65
|
-
end
|
63
|
+
def execute(sql, name = nil)
|
64
|
+
log(sql, name, @connection) { |connection| connection.query(sql) }
|
65
|
+
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
67
|
+
alias_method :update, :execute
|
68
|
+
alias_method :delete, :execute
|
70
69
|
|
71
|
-
|
72
|
-
|
70
|
+
def begin_db_transaction() execute "BEGIN" end
|
71
|
+
def commit_db_transaction() execute "COMMIT" end
|
72
|
+
def rollback_db_transaction() execute "ROLLBACK" end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
def quote_column_name(name)
|
75
|
+
return "\"#{name}\""
|
76
|
+
end
|
77
77
|
|
78
|
-
|
79
|
-
|
78
|
+
private
|
79
|
+
def last_insert_id(table, column = "id")
|
80
|
+
sequence_name = "#{table}_#{column || 'id'}_seq"
|
81
|
+
@connection.exec("SELECT currval('#{sequence_name}')")[0][0].to_i
|
80
82
|
end
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
if results.length > 0
|
95
|
-
fields = res.fields
|
96
|
-
results.each do |row|
|
97
|
-
hashed_row = {}
|
98
|
-
row.each_index { |cel_index| hashed_row[fields[cel_index]] = row[cel_index] }
|
99
|
-
rows << hashed_row
|
100
|
-
end
|
84
|
+
def select(sql, name = nil)
|
85
|
+
res = nil
|
86
|
+
log(sql, name, @connection) { |connection| res = connection.exec(sql) }
|
87
|
+
|
88
|
+
results = res.result
|
89
|
+
rows = []
|
90
|
+
if results.length > 0
|
91
|
+
fields = res.fields
|
92
|
+
results.each do |row|
|
93
|
+
hashed_row = {}
|
94
|
+
row.each_index { |cel_index| hashed_row[fields[cel_index]] = row[cel_index] }
|
95
|
+
rows << hashed_row
|
101
96
|
end
|
102
|
-
return rows
|
103
97
|
end
|
98
|
+
return rows
|
99
|
+
end
|
104
100
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
return [schema_name, table_name]
|
101
|
+
def split_table_schema(table_name)
|
102
|
+
schema_split = table_name.split('.')
|
103
|
+
schema_name = "public"
|
104
|
+
if schema_split.length > 1
|
105
|
+
schema_name = schema_split.first.strip
|
106
|
+
table_name = schema_split.last.strip
|
113
107
|
end
|
108
|
+
return [schema_name, table_name]
|
109
|
+
end
|
114
110
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
111
|
+
def table_structure(table_name)
|
112
|
+
database_name = @connection.db
|
113
|
+
schema_name, table_name = split_table_schema(table_name)
|
114
|
+
|
115
|
+
# Grab a list of all the default values for the columns.
|
116
|
+
sql = "SELECT column_name, column_default, character_maximum_length, data_type "
|
117
|
+
sql << " FROM information_schema.columns "
|
118
|
+
sql << " WHERE table_catalog = '#{database_name}' "
|
119
|
+
sql << " AND table_schema = '#{schema_name}' "
|
120
|
+
sql << " AND table_name = '#{table_name}';"
|
121
|
+
|
122
|
+
column_defaults = nil
|
123
|
+
log(sql, nil, @connection) { |connection| column_defaults = connection.query(sql) }
|
124
|
+
column_defaults.collect do |row|
|
125
|
+
field = row[0]
|
126
|
+
type = type_as_string(row[3], row[2])
|
127
|
+
default = default_value(row[1])
|
128
|
+
length = row[2]
|
129
|
+
|
130
|
+
[field, type, default, length]
|
136
131
|
end
|
132
|
+
end
|
137
133
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
134
|
+
def type_as_string(field_type, field_length)
|
135
|
+
type = case field_type
|
136
|
+
when 'numeric', 'real', 'money' then 'float'
|
137
|
+
when 'character varying', 'interval' then 'string'
|
138
|
+
when 'timestamp without time zone' then 'datetime'
|
139
|
+
else field_type
|
140
|
+
end
|
145
141
|
|
146
|
-
|
142
|
+
size = field_length.nil? ? "" : "(#{field_length})"
|
147
143
|
|
148
|
-
|
149
|
-
|
144
|
+
return type + size
|
145
|
+
end
|
150
146
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
end
|
147
|
+
def default_value(value)
|
148
|
+
# Boolean types
|
149
|
+
return "t" if value =~ /true/i
|
150
|
+
return "f" if value =~ /false/i
|
151
|
+
|
152
|
+
# Char/String type values
|
153
|
+
return $1 if value =~ /^'(.*)'::(bpchar|text|character varying)$/
|
154
|
+
|
155
|
+
# Numeric values
|
156
|
+
return value if value =~ /^[0-9]+(\.[0-9]*)?/
|
157
|
+
|
158
|
+
# Date / Time magic values
|
159
|
+
return Time.now.to_s if value =~ /^\('now'::text\)::(date|timestamp)/
|
160
|
+
|
161
|
+
# Fixed dates / times
|
162
|
+
return $1 if value =~ /^'(.+)'::(date|timestamp)/
|
163
|
+
|
164
|
+
# Anything else is blank, some user type, or some function
|
165
|
+
# and we can't know the value of that, so return nil.
|
166
|
+
return nil
|
167
|
+
end
|
173
168
|
end
|
174
169
|
end
|
175
|
-
rescue LoadError
|
176
|
-
# PostgreSQL driver is not availible
|
177
170
|
end
|
@@ -3,105 +3,103 @@
|
|
3
3
|
|
4
4
|
require 'active_record/connection_adapters/abstract_adapter'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
raise ArgumentError, "No database file specified. Missing argument: dbfile"
|
16
|
-
end
|
6
|
+
module ActiveRecord
|
7
|
+
class Base
|
8
|
+
# Establishes a connection to the database that's used by all Active Record objects
|
9
|
+
def self.sqlite_connection(config) # :nodoc:
|
10
|
+
require_library_or_gem('sqlite') unless self.class.const_defined?(:SQLite)
|
11
|
+
symbolize_strings_in_hash(config)
|
12
|
+
unless config.has_key?(:dbfile)
|
13
|
+
raise ArgumentError, "No database file specified. Missing argument: dbfile"
|
14
|
+
end
|
17
15
|
|
18
|
-
|
16
|
+
db = SQLite::Database.new(config[:dbfile], 0)
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
db.show_datatypes = "ON" if !defined? SQLite::Version
|
19
|
+
db.results_as_hash = true if defined? SQLite::Version
|
20
|
+
db.type_translation = false
|
23
21
|
|
24
|
-
|
25
|
-
end
|
22
|
+
ConnectionAdapters::SQLiteAdapter.new(db, logger)
|
26
23
|
end
|
24
|
+
end
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
module ConnectionAdapters
|
27
|
+
class SQLiteAdapter < AbstractAdapter # :nodoc:
|
28
|
+
def select_all(sql, name = nil)
|
29
|
+
select(sql, name)
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
def select_one(sql, name = nil)
|
33
|
+
result = select(sql, name)
|
34
|
+
result.nil? ? nil : result.first
|
35
|
+
end
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
37
|
+
def columns(table_name, name = nil)
|
38
|
+
table_structure(table_name).inject([]) do |columns, field|
|
39
|
+
columns << Column.new(field['name'], field['dflt_value'], field['type'])
|
40
|
+
columns
|
44
41
|
end
|
42
|
+
end
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
def insert(sql, name = nil, pk = nil, id_value = nil)
|
45
|
+
execute(sql, name = nil)
|
46
|
+
id_value || @connection.send( defined?( SQLite::Version ) ? :last_insert_row_id : :last_insert_rowid )
|
47
|
+
end
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
else
|
61
|
-
connection.execute( sql )
|
49
|
+
def execute(sql, name = nil)
|
50
|
+
log(sql, name, @connection) do |connection|
|
51
|
+
if defined?( SQLite::Version )
|
52
|
+
case sql
|
53
|
+
when "BEGIN" then connection.transaction
|
54
|
+
when "COMMIT" then connection.commit
|
55
|
+
when "ROLLBACK" then connection.rollback
|
56
|
+
else connection.execute(sql)
|
62
57
|
end
|
58
|
+
else
|
59
|
+
connection.execute( sql )
|
63
60
|
end
|
64
61
|
end
|
62
|
+
end
|
65
63
|
|
66
|
-
|
67
|
-
|
64
|
+
alias_method :update, :execute
|
65
|
+
alias_method :delete, :execute
|
68
66
|
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
def begin_db_transaction() execute "BEGIN" end
|
68
|
+
def commit_db_transaction() execute "COMMIT" end
|
69
|
+
def rollback_db_transaction() execute "ROLLBACK" end
|
72
70
|
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def quote_string(s)
|
72
|
+
SQLite::Database.quote(s)
|
73
|
+
end
|
74
|
+
|
75
|
+
def quote_column_name(name)
|
76
|
+
return "'#{name}'"
|
77
|
+
end
|
76
78
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
79
|
+
private
|
80
|
+
def select(sql, name = nil)
|
81
|
+
results = nil
|
82
|
+
log(sql, name, @connection) { |connection| results = connection.execute(sql) }
|
81
83
|
|
82
|
-
|
84
|
+
rows = []
|
83
85
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
rows << hash_only_row
|
86
|
+
results.each do |row|
|
87
|
+
hash_only_row = {}
|
88
|
+
row.each_key do |key|
|
89
|
+
hash_only_row[key.sub(/\w+\./, "")] = row[key] unless key.class == Fixnum
|
90
90
|
end
|
91
|
-
|
92
|
-
return rows
|
91
|
+
rows << hash_only_row
|
93
92
|
end
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
94
|
+
return rows
|
95
|
+
end
|
96
|
+
|
97
|
+
def table_structure(table_name)
|
98
|
+
sql = "PRAGMA table_info(#{table_name});"
|
99
|
+
results = nil
|
100
|
+
log(sql, nil, @connection) { |connection| results = connection.execute(sql) }
|
101
|
+
return results
|
102
|
+
end
|
102
103
|
end
|
103
104
|
end
|
104
|
-
|
105
|
-
retry if require('rubygems') rescue LoadError
|
106
|
-
# SQLite driver is not availible
|
107
|
-
end
|
105
|
+
end
|