Add SQLite support
- UUID support - Schema compatibility layer, ignore MySQL specific options - Search not working yet
This commit is contained in:
+25
-4
@@ -1,4 +1,7 @@
|
||||
<%
|
||||
database_adapter = ENV.fetch("DATABASE_ADAPTER", "mysql")
|
||||
use_sqlite = database_adapter == "sqlite"
|
||||
|
||||
if ENV["MIGRATE"].present?
|
||||
mysql_app_user_key = "MYSQL_ALTER_USER"
|
||||
mysql_app_password_key = "MYSQL_ALTER_PASSWORD"
|
||||
@@ -12,13 +15,24 @@
|
||||
%>
|
||||
|
||||
default: &default
|
||||
<% if use_sqlite %>
|
||||
adapter: sqlite3
|
||||
pool: 50
|
||||
timeout: 5000
|
||||
<% else %>
|
||||
adapter: trilogy
|
||||
host: <%= ENV.fetch "FIZZY_DB_HOST", "127.0.0.1" %>
|
||||
port: <%= ENV.fetch "FIZZY_DB_PORT", 3306 %>
|
||||
pool: 50
|
||||
timeout: 5000
|
||||
<% end %>
|
||||
|
||||
development:
|
||||
<% if use_sqlite %>
|
||||
primary:
|
||||
<<: *default
|
||||
database: db/development.sqlite3
|
||||
<% else %>
|
||||
primary:
|
||||
<<: *default
|
||||
database: fizzy_development
|
||||
@@ -26,28 +40,34 @@ development:
|
||||
replica:
|
||||
<<: *default
|
||||
database: fizzy_development
|
||||
replica: true
|
||||
port: <%= ENV.fetch "FIZZY_DB_PORT", 33380 %>
|
||||
replica: true
|
||||
cable:
|
||||
<<: *default
|
||||
database: development_cable
|
||||
migrations_paths: db/cable_migrate
|
||||
port: <%= ENV.fetch "FIZZY_DB_PORT", 33380 %>
|
||||
migrations_paths: db/cable_migrate
|
||||
cache:
|
||||
<<: *default
|
||||
database: development_cache
|
||||
migrations_paths: db/cache_migrate
|
||||
port: <%= ENV.fetch "FIZZY_DB_PORT", 33380 %>
|
||||
migrations_paths: db/cache_migrate
|
||||
queue:
|
||||
<<: *default
|
||||
database: development_queue
|
||||
migrations_paths: db/queue_migrate
|
||||
port: <%= ENV.fetch "FIZZY_DB_PORT", 33380 %>
|
||||
migrations_paths: db/queue_migrate
|
||||
<% end %>
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
# Do not set this db to the same as development or production.
|
||||
test:
|
||||
<% if use_sqlite %>
|
||||
primary:
|
||||
<<: *default
|
||||
database: db/test.sqlite3
|
||||
<% else %>
|
||||
primary:
|
||||
<<: *default
|
||||
database: fizzy_test
|
||||
@@ -57,6 +77,7 @@ test:
|
||||
database: fizzy_test
|
||||
port: <%= ENV.fetch "FIZZY_DB_PORT", 33380 %>
|
||||
replica: true
|
||||
<% end %>
|
||||
|
||||
production: &production
|
||||
primary:
|
||||
|
||||
@@ -6,7 +6,12 @@ end
|
||||
|
||||
# Use DB read/write splitting for Active Storage models
|
||||
ActiveSupport.on_load(:active_storage_record) do
|
||||
connects_to database: { writing: :primary, reading: :replica }
|
||||
# SQLite doesn't use separate replica databases
|
||||
if ENV.fetch("DATABASE_ADAPTER", "mysql") == "sqlite"
|
||||
connects_to database: { writing: :primary, reading: :primary }
|
||||
else
|
||||
connects_to database: { writing: :primary, reading: :replica }
|
||||
end
|
||||
end
|
||||
|
||||
module ActiveStorageControllerExtensions
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# SQLite compatibility layer - filters out MySQL-specific options when using SQLite
|
||||
|
||||
# Define modules outside on_load so they're available immediately
|
||||
module SQLiteCompatibility
|
||||
module SQLiteTableDefinitionCompatibility
|
||||
# Override column method to filter out MySQL-specific options
|
||||
def column(name, type, **options)
|
||||
# Check if we're using SQLite by checking the connection adapter
|
||||
if @conn.is_a?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
||||
# Remove MySQL-specific options that SQLite doesn't support
|
||||
options = options.except(:size, :charset, :collation, :unsigned)
|
||||
end
|
||||
super(name, type, **options)
|
||||
end
|
||||
|
||||
# Override index method to filter out MySQL-specific index options
|
||||
def index(column_name, **options)
|
||||
if @conn.is_a?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
||||
# Skip fulltext indexes entirely for SQLite
|
||||
return if options[:type] == :fulltext
|
||||
# SQLite doesn't support length-limited indexes
|
||||
options = options.except(:length)
|
||||
end
|
||||
super(column_name, **options)
|
||||
end
|
||||
end
|
||||
|
||||
module SQLiteSchemaStatementCompatibility
|
||||
# Override create_table to filter out MySQL-specific table options
|
||||
def create_table(table_name, **options)
|
||||
if is_a?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
||||
# Remove MySQL-specific table options
|
||||
options = options.except(:charset, :collation)
|
||||
end
|
||||
super(table_name, **options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Apply the prepends - both in on_load callback and immediately
|
||||
def apply_sqlite_compatibility
|
||||
if defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
||||
ActiveRecord::ConnectionAdapters::TableDefinition.prepend(SQLiteCompatibility::SQLiteTableDefinitionCompatibility)
|
||||
ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(SQLiteCompatibility::SQLiteSchemaStatementCompatibility)
|
||||
end
|
||||
end
|
||||
|
||||
# Run immediately if ActiveRecord is already loaded
|
||||
apply_sqlite_compatibility
|
||||
|
||||
# Also run when ActiveRecord loads (for cases where it loads later)
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
apply_sqlite_compatibility
|
||||
end
|
||||
@@ -16,7 +16,42 @@ ActiveSupport.on_load(:active_record) do
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(MysqlUuidAdapter)
|
||||
if defined?(ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter)
|
||||
ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.prepend(MysqlUuidAdapter)
|
||||
end
|
||||
|
||||
module SqliteUuidAdapter
|
||||
# Add UUID to SQLite's native database types
|
||||
def native_database_types
|
||||
@native_database_types_with_uuid ||= super.merge(uuid: { name: "blob", limit: 16 })
|
||||
end
|
||||
|
||||
# Override lookup_cast_type to recognize BLOB as UUID type
|
||||
def lookup_cast_type(sql_type)
|
||||
if sql_type == "blob(16)"
|
||||
ActiveRecord::Type.lookup(:uuid, adapter: :sqlite3)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
# Override fetch_type_metadata to preserve UUID type and limit
|
||||
def fetch_type_metadata(sql_type)
|
||||
if sql_type == "blob(16)"
|
||||
ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(
|
||||
sql_type: sql_type,
|
||||
type: :uuid,
|
||||
limit: 16
|
||||
)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
||||
ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(SqliteUuidAdapter)
|
||||
end
|
||||
|
||||
module SchemaDumperUuidType
|
||||
# Map binary(16) columns to :uuid type in schema.rb
|
||||
@@ -29,7 +64,9 @@ ActiveSupport.on_load(:active_record) do
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::ConnectionAdapters::MySQL::SchemaDumper.prepend(SchemaDumperUuidType)
|
||||
if defined?(ActiveRecord::ConnectionAdapters::MySQL::SchemaDumper)
|
||||
ActiveRecord::ConnectionAdapters::MySQL::SchemaDumper.prepend(SchemaDumperUuidType)
|
||||
end
|
||||
|
||||
module TableDefinitionUuidSupport
|
||||
def uuid(name, **options)
|
||||
|
||||
Reference in New Issue
Block a user