El Martes, 29 de Diciembre de 2009, Jeremy Evans escribió:
> Currently, the conditional is the only way to do it. I'd consider a
> patch to the MySQL adapter that respected a :size option for the
> generic File type that is recognized (i.e.
> File :doc, :size=>:medium). The way Sequel is set up, it doesn't
> complain if you pass unregonized options, so the option would just be
> ignored on other database adapters.
I attach a patch implementing it. It works for me.
Hope it's ok. Thanks a lot.
--
Iñaki Baz Castillo <[email protected]>
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en.
diff --git a/lib/sequel/adapters/shared/mysql.rb b/lib/sequel/adapters/shared/mysql.rb
index 296435b..001344c 100644
--- a/lib/sequel/adapters/shared/mysql.rb
+++ b/lib/sequel/adapters/shared/mysql.rb
@@ -14,7 +14,7 @@ module Sequel
AUTO_INCREMENT = 'AUTO_INCREMENT'.freeze
CAST_TYPES = {String=>:CHAR, Integer=>:SIGNED, Time=>:DATETIME, DateTime=>:DATETIME, Numeric=>:DECIMAL, BigDecimal=>:DECIMAL, File=>:BINARY}
PRIMARY = 'PRIMARY'.freeze
-
+
# MySQL's cast rules are restrictive in that you can't just cast to any possible
# database type.
def cast_type_literal(type)
@@ -53,7 +53,7 @@ module Sequel
m = /(\d+)\.(\d+)\.(\d+)/.match(get(SQL::Function.new(:version)))
@server_version ||= (m[1].to_i * 10000) + (m[2].to_i * 100) + m[3].to_i
end
-
+
# Return an array of symbols specifying table names in the current database.
#
# Options:
@@ -62,7 +62,7 @@ module Sequel
m = output_identifier_meth
metadata_dataset.with_sql('SHOW TABLES').server(opts[:server]).map{|r| m.call(r.values.first)}
end
-
+
# MySQL supports savepoints
def supports_savepoints?
true
@@ -76,9 +76,9 @@ module Sequel
@schemas = {}
self
end
-
+
private
-
+
# Use MySQL specific syntax for rename column, set column type, and
# drop index cases.
def alter_table_sql(table, op)
@@ -107,24 +107,24 @@ module Sequel
super(table, op)
end
end
-
+
# Use MySQL specific AUTO_INCREMENT text.
def auto_increment_sql
AUTO_INCREMENT
end
-
+
# MySQL doesn't allow default values on text columns, so ignore if it the
# generic text type is used
def column_definition_sql(column)
column.delete(:default) if column[:type] == File || (column[:type] == String && column[:text] == true)
super
end
-
+
# MySQL doesn't handle references as column constraints, it must use a separate table constraint
def column_references_column_constraint_sql(column)
"#{", FOREIGN KEY (#{quote_identifier(column[:name])})" unless column[:type] == :check}#{column_references_sql(column)}"
end
-
+
# Use MySQL specific syntax for engine type and character encoding
def create_table_sql(name, generator, options = {})
engine = options.include?(:engine) ? options[:engine] : Sequel::MySQL.default_engine
@@ -137,7 +137,7 @@ module Sequel
def identifier_input_method_default
nil
end
-
+
# MySQL folds unquoted identifiers to lowercase, so it shouldn't need to upcase identifiers on output.
def identifier_output_method_default
nil
@@ -157,7 +157,7 @@ module Sequel
end
"CREATE #{index_type}INDEX #{index_name}#{using} ON #{quote_schema_table(table_name)} #{literal(index[:columns])}"
end
-
+
# MySQL treats integer primary keys as autoincrementing.
def schema_autoincrementing_primary_key?(schema)
super and schema[:db_type] =~ /int/io
@@ -179,6 +179,22 @@ module Sequel
end
end
+ # Allow different sizes.
+ def type_literal_generic_file(column)
+ case column[:size]
+ when :small, :tiny # < 2^8 bytes
+ :tinyblob
+ when :normal # < 2^16 bytes
+ :blob
+ when :medium # < 2^24 bytes
+ :mediumblob
+ when :long, :big # < 2^32 bytes
+ :longblob
+ else
+ :blob
+ end
+ end
+
# MySQL has both datetime and timestamp classes, most people are going
# to want datetime
def type_literal_generic_datetime(column)
@@ -196,7 +212,7 @@ module Sequel
:'tinyint(1)'
end
end
-
+
# Dataset methods shared by datasets that use MySQL databases.
module DatasetMethods
BOOL_TRUE = '1'.freeze
@@ -206,7 +222,7 @@ module Sequel
INSERT_CLAUSE_METHODS = Dataset.clause_methods(:insert, %w'ignore into columns values on_duplicate_key_update')
SELECT_CLAUSE_METHODS = Dataset.clause_methods(:select, %w'distinct columns from join where group having compounds order limit')
UPDATE_CLAUSE_METHODS = Dataset.clause_methods(:update, %w'table set where order limit')
-
+
# MySQL specific syntax for LIKE/REGEXP searches, as well as
# string concatenation.
def complex_expression_sql(op, args)
@@ -228,7 +244,7 @@ module Sequel
def full_text_search(cols, terms, opts = {})
filter(full_text_sql(cols, terms, opts))
end
-
+
# MySQL specific full text search syntax.
def full_text_sql(cols, term, opts = {})
"MATCH #{literal(Array(cols))} AGAINST (#{literal(Array(term).join(' '))}#{" IN BOOLEAN MODE" if opts[:boolean]})"
@@ -238,7 +254,7 @@ module Sequel
def having(*cond, &block)
_filter(:having, *cond, &block)
end
-
+
# Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
# Raises an error on use of :full_outer type, since MySQL doesn't support it.
def join_table(type, table, expr=nil, table_alias={})
@@ -246,7 +262,7 @@ module Sequel
raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN") if type == :full_outer
super(type, table, expr, table_alias)
end
-
+
# Transforms :natural_inner to NATURAL LEFT JOIN and straight to
# STRAIGHT_JOIN.
def join_type_sql(join_type)
@@ -256,7 +272,7 @@ module Sequel
else super
end
end
-
+
# Sets up multi_insert or import to use INSERT IGNORE.
# Useful if you have a unique key and want to just skip
# inserting rows that violate the unique key restriction.
@@ -272,7 +288,7 @@ module Sequel
def insert_ignore
clone(:insert_ignore=>true)
end
-
+
# Sets up multi_insert or import to use ON DUPLICATE KEY UPDATE
# If you pass no arguments, ALL fields will be
# updated with the new values. If you pass the fields you
@@ -305,18 +321,18 @@ module Sequel
def multi_insert_sql(columns, values)
[insert_sql(columns, LiteralString.new('VALUES ' + values.map {|r| literal(Array(r))}.join(COMMA_SEPARATOR)))]
end
-
+
# MySQL uses the nonstandard ` (backtick) for quoting identifiers.
def quoted_identifier(c)
"`#{c}`"
end
-
+
# MySQL specific syntax for REPLACE (aka UPSERT, or update if exists,
# insert if it doesn't).
def replace_sql(*values)
clone(:replace=>true).insert_sql(*values)
end
-
+
# does not support DISTINCT ON
def supports_distinct_on?
false
@@ -326,7 +342,7 @@ module Sequel
def supports_intersect_except?
false
end
-
+
# MySQL supports modifying joined datasets
def supports_modifying_joins?
true
@@ -338,9 +354,9 @@ module Sequel
def supports_timestamp_usecs?
false
end
-
+
protected
-
+
# If this is an replace instead of an insert, use replace instead
def _insert_sql
@opts[:replace] ? clause_sql(:replace) : super
@@ -352,7 +368,7 @@ module Sequel
def delete_clause_methods
DELETE_CLAUSE_METHODS
end
-
+
# Consider the first table in the joined dataset is the table to delete
# from, but include the others for the purposes of selecting rows.
def delete_from_sql(sql)
@@ -416,7 +432,7 @@ module Sequel
def literal_true
BOOL_TRUE
end
-
+
# MySQL specific syntax for ON DUPLICATE KEY UPDATE
def on_duplicate_key_update_sql
if update_cols = opts[:on_duplicate_key_update]