aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-01-10 23:09:51 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-01-10 23:09:51 +0000
commita133f3e64f927780d4eac062ba996dffc174431a (patch)
tree9988538b383a105b25231ac0d7e4be72b2bf3a49 /activerecord/lib
parent903dcefbaff8cf3a0e9db61048aebd9e753835ea (diff)
downloadrails-a133f3e64f927780d4eac062ba996dffc174431a.tar.gz
rails-a133f3e64f927780d4eac062ba996dffc174431a.tar.bz2
rails-a133f3e64f927780d4eac062ba996dffc174431a.zip
Added SQLite3 compatibility through the sqlite3-ruby adapter by Jamis Buck #381 [bitsweat]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@374 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib')
-rwxr-xr-xactiverecord/lib/active_record.rb2
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb21
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb167
3 files changed, 106 insertions, 84 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index 7a7b39890a..0b7a6b4c76 100755
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -24,7 +24,7 @@
$:.unshift(File.dirname(__FILE__))
-require 'action_controller/support/core_ext'
+require 'active_record/support/core_ext'
require 'active_record/support/clean_logger'
require 'active_record/support/misc'
require 'active_record/support/dependencies'
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index 547c98911a..9eaac85571 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -89,7 +89,7 @@ module ActiveRecord
raise AdapterNotSpecified, "#{spec} database is not configured"
end
else
- spec = symbolize_strings_in_hash(spec)
+ spec = spec.symbolize_keys
unless spec.key?(:adapter) then raise AdapterNotSpecified, "database configuration does not specify adapter" end
adapter_method = "#{spec[:adapter]}_connection"
unless respond_to?(adapter_method) then raise AdapterNotFound, "database configuration specifies nonexistent #{spec[:adapter]} adapter" end
@@ -152,10 +152,7 @@ module ActiveRecord
# Converts all strings in a hash to symbols.
def self.symbolize_strings_in_hash(hash)
- hash.inject({}) do |hash_with_symbolized_strings, pair|
- hash_with_symbolized_strings[pair.first.to_sym] = pair.last
- hash_with_symbolized_strings
- end
+ hash.symbolize_keys
end
end
@@ -356,7 +353,7 @@ module ActiveRecord
end
def quote_column_name(name)
- return name
+ name
end
# Returns a string of the CREATE TABLE SQL statements for recreating the entire structure of the database.
@@ -367,16 +364,20 @@ module ActiveRecord
end
protected
- def log(sql, name, connection, &action)
+ def log(sql, name, connection = nil)
+ connection ||= @connection
begin
if @logger.nil? || @logger.level > Logger::INFO
- action.call(connection)
- else
+ yield connection
+ elsif block_given?
result = nil
- bm = measure { result = action.call(connection) }
+ bm = measure { result = yield connection }
@runtime += bm.real
log_info(sql, name, bm.real)
result
+ else
+ log_info(sql, name, 0)
+ nil
end
rescue => e
log_info("#{e.message}: #{sql}", name, 0)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 4dc8d634b3..b8a91929c7 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -1,33 +1,67 @@
# sqlite_adapter.rb
-# author: Luke Holden <lholden@cablelan.net>
+# author: Luke Holden <lholden@cablelan.net>
+# updated for SQLite3: Jamis Buck <jamis_buck@byu.edu>
require 'active_record/connection_adapters/abstract_adapter'
module ActiveRecord
class Base
- # Establishes a connection to the database that's used by all Active Record objects
- def self.sqlite_connection(config) # :nodoc:
- require_library_or_gem('sqlite') unless self.class.const_defined?(:SQLite)
- symbolize_strings_in_hash(config)
- unless config.has_key?(:dbfile)
- raise ArgumentError, "No database file specified. Missing argument: dbfile"
+ class << self
+ # sqlite3 adapter reuses sqlite_connection.
+ def sqlite3_connection(config) # :nodoc:
+ parse_config!(config)
+
+ unless self.class.const_defined?(:SQLite3)
+ require_library_or_gem(config[:adapter])
+ end
+
+ db = SQLite3::Database.new(
+ config[:dbfile],
+ :results_as_hash => true,
+ :type_translation => false
+ )
+ ConnectionAdapters::SQLiteAdapter.new(db, logger)
+ end
+
+ # Establishes a connection to the database that's used by all Active Record objects
+ def sqlite_connection(config) # :nodoc:
+ parse_config!(config)
+
+ unless self.class.const_defined?(:SQLite)
+ require_library_or_gem(config[:adapter])
+
+ db = SQLite::Database.new(config[:dbfile], 0)
+ db.show_datatypes = "ON" if !defined? SQLite::Version
+ db.results_as_hash = true if defined? SQLite::Version
+ db.type_translation = false
+
+ # "Downgrade" deprecated sqlite API
+ if SQLite.const_defined?(:Version)
+ ConnectionAdapters::SQLiteAdapter.new(db, logger)
+ else
+ ConnectionAdapters::DeprecatedSQLiteAdapter.new(db, logger)
+ end
+ end
end
-
- config[:dbfile] = File.expand_path(config[:dbfile], RAILS_ROOT) if Object.const_defined?(:RAILS_ROOT)
- db = SQLite::Database.new(config[:dbfile], 0)
- db.show_datatypes = "ON" if !defined? SQLite::Version
- db.results_as_hash = true if defined? SQLite::Version
- db.type_translation = false
+ private
+ def parse_config!(config)
+ # Require dbfile.
+ unless config.has_key?(:dbfile)
+ raise ArgumentError, "No database file specified. Missing argument: dbfile"
+ end
- ConnectionAdapters::SQLiteAdapter.new(db, logger)
+ # Allow database path relative to RAILS_ROOT.
+ if Object.const_defined?(:RAILS_ROOT)
+ config[:dbfile] = File.expand_path(config[:dbfile], RAILS_ROOT)
+ end
+ end
end
end
module ConnectionAdapters
class SQLiteColumn < Column
-
def string_to_binary(value)
value.gsub(/(\0|\%)/) do
case $1
@@ -45,92 +79,79 @@ module ActiveRecord
end
end
end
-
end
+
class SQLiteAdapter < AbstractAdapter # :nodoc:
- def select_all(sql, name = nil)
- select(sql, name)
+ def execute(sql, name = nil)
+ log(sql, name) { @connection.execute(sql) }
end
- def select_one(sql, name = nil)
- result = select(sql, name)
- result.nil? ? nil : result.first
+ def update(sql, name = nil)
+ execute(sql, name)
+ @connection.changes
end
- def columns(table_name, name = nil)
- table_structure(table_name).inject([]) do |columns, field|
- columns << SQLiteColumn.new(field['name'], field['dflt_value'], field['type'])
- columns
- end
+ def delete(sql, name = nil)
+ sql += " WHERE 1=1" unless sql =~ /WHERE/i
+ execute(sql, name)
+ @connection.changes
end
def insert(sql, name = nil, pk = nil, id_value = nil)
execute(sql, name = nil)
- id_value || @connection.send( defined?( SQLite::Version ) ? :last_insert_row_id : :last_insert_rowid )
+ id_value || @connection.last_insert_row_id
end
- def execute(sql, name = nil)
- log(sql, name, @connection) do |connection|
- if defined?( SQLite::Version )
- case sql
- when "BEGIN" then connection.transaction
- when "COMMIT" then connection.commit
- when "ROLLBACK" then connection.rollback
- else connection.execute(sql)
- end
- else
- connection.execute( sql )
+ def select_all(sql, name = nil)
+ execute(sql, name).map do |row|
+ record = {}
+ row.each_key do |key|
+ record[key.sub(/\w+\./, '')] = row[key] unless key.is_a?(Fixnum)
end
+ record
end
end
- def update(sql, name = nil)
- execute(sql, name)
- @connection.changes
+ def select_one(sql, name = nil)
+ result = select_all(sql, name)
+ result.nil? ? nil : result.first
end
-
- def delete(sql, name = nil)
- sql += " WHERE 1=1" unless sql =~ /WHERE/i
- execute(sql, name)
- @connection.changes
+
+
+ def begin_db_transaction() @connection.transaction end
+ def commit_db_transaction() @connection.commit end
+ def rollback_db_transaction() @connection.rollback end
+
+
+ def tables
+ execute('.table').map { |table| Table.new(table) }
end
- def begin_db_transaction() execute "BEGIN" end
- def commit_db_transaction() execute "COMMIT" end
- def rollback_db_transaction() execute "ROLLBACK" end
+ def columns(table_name, name = nil)
+ table_structure(table_name).map { |field|
+ SQLiteColumn.new(field['name'], field['dflt_value'], field['type'])
+ }
+ end
def quote_string(s)
- SQLite::Database.quote(s)
+ @connection.class.quote(s)
end
-
+
def quote_column_name(name)
return "'#{name}'"
end
- private
- def select(sql, name = nil)
- results = nil
- log(sql, name, @connection) { |connection| results = connection.execute(sql) }
-
- rows = []
-
- results.each do |row|
- hash_only_row = {}
- row.each_key do |key|
- hash_only_row[key.sub(/\w+\./, "")] = row[key] unless key.class == Fixnum
- end
- rows << hash_only_row
- end
-
- return rows
- end
-
+ protected
def table_structure(table_name)
- sql = "PRAGMA table_info(#{table_name});"
- results = nil
- log(sql, nil, @connection) { |connection| results = connection.execute(sql) }
- return results
+ execute "PRAGMA table_info(#{table_name})"
end
end
+
+ class DeprecatedSQLiteAdapter < SQLiteAdapter # :nodoc:
+ def insert(sql, name = nil, pk = nil, id_value = nil)
+ execute(sql, name = nil)
+ id_value || @connection.last_insert_rowid
+ end
+ end
end
end