sequel 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGELOG +48 -0
  2. data/Rakefile +16 -6
  3. data/bin/sequel +0 -0
  4. data/doc/cheat_sheet.rdoc +4 -4
  5. data/doc/schema.rdoc +9 -0
  6. data/lib/sequel_core/adapters/jdbc.rb +7 -7
  7. data/lib/sequel_core/adapters/mysql.rb +6 -11
  8. data/lib/sequel_core/adapters/shared/mssql.rb +21 -1
  9. data/lib/sequel_core/adapters/shared/mysql.rb +19 -27
  10. data/lib/sequel_core/adapters/shared/postgres.rb +67 -11
  11. data/lib/sequel_core/adapters/shared/sqlite.rb +11 -22
  12. data/lib/sequel_core/adapters/sqlite.rb +8 -4
  13. data/lib/sequel_core/core_sql.rb +4 -4
  14. data/lib/sequel_core/database.rb +56 -31
  15. data/lib/sequel_core/database/schema.rb +13 -5
  16. data/lib/sequel_core/dataset/convenience.rb +1 -1
  17. data/lib/sequel_core/dataset/sql.rb +30 -15
  18. data/lib/sequel_core/migration.rb +7 -0
  19. data/lib/sequel_core/schema/generator.rb +13 -2
  20. data/lib/sequel_core/schema/sql.rb +27 -81
  21. data/lib/sequel_core/sql.rb +5 -2
  22. data/lib/sequel_model.rb +8 -2
  23. data/lib/sequel_model/associations.rb +7 -4
  24. data/lib/sequel_model/base.rb +10 -1
  25. data/lib/sequel_model/eager_loading.rb +29 -10
  26. data/lib/sequel_model/record.rb +19 -5
  27. data/spec/adapters/mysql_spec.rb +2 -2
  28. data/spec/adapters/postgres_spec.rb +26 -5
  29. data/spec/adapters/sqlite_spec.rb +42 -8
  30. data/spec/integration/eager_loader_test.rb +51 -58
  31. data/spec/integration/schema_test.rb +28 -4
  32. data/spec/sequel_core/core_sql_spec.rb +3 -0
  33. data/spec/sequel_core/database_spec.rb +24 -0
  34. data/spec/sequel_core/dataset_spec.rb +25 -17
  35. data/spec/sequel_core/schema_spec.rb +58 -26
  36. data/spec/sequel_model/eager_loading_spec.rb +65 -0
  37. data/spec/sequel_model/hooks_spec.rb +1 -1
  38. data/spec/sequel_model/model_spec.rb +1 -0
  39. data/spec/sequel_model/record_spec.rb +74 -1
  40. data/spec/sequel_model/spec_helper.rb +8 -0
  41. metadata +5 -3
data/CHANGELOG CHANGED
@@ -1,3 +1,51 @@
1
+ === 2.6.0 (2008-10-11)
2
+
3
+ * Make the sqlite adapter respect the Sequel.datetime_class setting, for timestamp and datetime types (jeremyevans)
4
+
5
+ * Enhance the CASE statement support to include an optional expression (jarredholman)
6
+
7
+ * Default to using the simple language if no language is specified for a full text index on PostgreSQL (michalbugno)
8
+
9
+ * Add Model.raise_on_typecast_failure=, which makes it possible to not raise errors on invalid typecasts (michalbugno)
10
+
11
+ * Add schema.rdoc file, which provides an brief description of the various parts of Sequel related to schema modification (jeremyevans)
12
+
13
+ * Fix constraint generation when not using a proc or interpolated string (jeremyevans)
14
+
15
+ * Make eager_graph respect associations' :order options (use :order_eager_graph=>false to disable) (jeremyevans)
16
+
17
+ * Cache negative lookup when eagerly loading many_to_one associations where no objects have an associated object (jeremyevans)
18
+
19
+ * Allow string keys to be used when using Dataset#multi_insert (jeremyevans)
20
+
21
+ * Fix join_table when doing the first join for a dataset where the first source is a dataset when using unqualified columns (jeremyevans)
22
+
23
+ * Fix a few corner cases in eager_graph (jeremyevans)
24
+
25
+ * Support transactions on MSSQL (jeremyevans)
26
+
27
+ * Use string literals in AS clauses on SQLite (jeremyevans) (#241)
28
+
29
+ * AlterTableGenerator#set_column_allow_null was added to SET/DROP NOT NULL for columns (divoxx)
30
+
31
+ * Database#tables now works for MySQL databases using the JDBC adapter (jeremyevans)
32
+
33
+ * Database#drop_view can now take multiple arguments to drop multiple views at once (jeremyevans)
34
+
35
+ * Schema modification methods (e.g. drop_table, create_table!) now remove the cached schema entry (jeremyevans)
36
+
37
+ * Models can now determine their primary keys by looking at the schema (jeremyevans)
38
+
39
+ * No longer include :numeric_precision and :max_chars entries in the schema column hashes, use the :db_type entry instead (jeremyevans)
40
+
41
+ * Make schema parsing on PostgreSQL handle implicit schemas (e.g. schema(:schema__table)), so it works with models for tables outside the public schema (jeremyevans)
42
+
43
+ * Significantly speed up schema parsing on MySQL (jeremyevans)
44
+
45
+ * Include primary key information when parsing the schema (jeremyevans)
46
+
47
+ * Fix schema generation of composite foreign keys on MySQL (clivecrous, jeremyevans)
48
+
1
49
  === 2.5.0 (2008-09-03)
2
50
 
3
51
  * Add Dataset #set_defaults and #set_overrides, used for scoping the values used in insert/update statements (jeremyevans)
data/Rakefile CHANGED
@@ -1,14 +1,18 @@
1
1
  require "rake"
2
2
  require "rake/clean"
3
3
  require "rake/gempackagetask"
4
- require "rake/rdoctask"
5
- require "fileutils"
6
4
  require "spec/rake/spectask"
5
+ begin
6
+ require "hanna/rdoctask"
7
+ rescue LoadError
8
+ require "rake/rdoctask"
9
+ end
10
+ require "fileutils"
7
11
 
8
12
  include FileUtils
9
13
 
10
14
  NAME = 'sequel'
11
- VERS = '2.5.0'
15
+ VERS = '2.6.0'
12
16
  CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage", "www/public/*.html"]
13
17
  RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
14
18
  'Sequel: The Database Toolkit for Ruby', '--main', 'README']
@@ -73,14 +77,20 @@ end
73
77
 
74
78
  ### Website
75
79
 
76
- desc "Update sequel.rubyforge.org"
77
- task :website => [:rdoc]
78
- task :website do
80
+ desc "Update Non-RDoc section of sequel.rubyforge.org"
81
+ task :website_base do
79
82
  sh %{www/make_www.rb}
80
83
  sh %{scp -r www/public/* rubyforge.org:/var/www/gforge-projects/sequel/}
84
+ end
85
+
86
+ desc "Update RDoc section of sequel.rubyforge.org"
87
+ task :website_rdoc=>[:rerdoc] do
81
88
  sh %{scp -r rdoc/* rubyforge.org:/var/www/gforge-projects/sequel/rdoc/}
82
89
  end
83
90
 
91
+ desc "Update sequel.rubyforge.org"
92
+ task :website=>[:website_base, :website_rdoc]
93
+
84
94
  ### Specs
85
95
 
86
96
  lib_dir = File.join(File.dirname(__FILE__), 'lib')
data/bin/sequel CHANGED
File without changes
@@ -5,10 +5,10 @@
5
5
  require 'rubygems'
6
6
  require 'sequel'
7
7
 
8
- DB = Sequel.sqlite 'my_blog.db'
9
- DB = Sequel('postgres://user:password@localhost/my_db')
10
- DB = Sequel.mysql 'my_db', :user => 'user', :password => 'password', :host => 'localhost'
11
- DB = Sequel.ado 'mydb'
8
+ DB = Sequel.sqlite('my_blog.db')
9
+ DB = Sequel.connect('postgres://user:password@localhost/my_db')
10
+ DB = Sequel.mysql('my_db', :user => 'user', :password => 'password', :host => 'localhost')
11
+ DB = Sequel.ado('mydb')
12
12
 
13
13
  == Open an SQLite memory database
14
14
 
@@ -0,0 +1,9 @@
1
+ = Schema Modifications with Sequel
2
+
3
+ In addition to its support for getting data from databases, Sequel has good support for modifying the schema of databases. Unfortunately, the documentation from this is spread out in various places in the Sequel RDoc.
4
+
5
+ The recommended way to set up schema modifications in Sequel is through migrations. Migrations are modifications to the schema that handle modifying the schema in two directions, up and down, with down reversing the changes made by up. Migrations are stored in sequentially numbered files inside a directory (see the Sequel::Migrator documentation for file naming format details). The migrations can be run on the database using the sequel command line tool (the -m and -M switches).
6
+
7
+ The format of the individual migration files themselves is explained in the Sequel::Migration documentation. Each migration file contains a single migration class. The migration class acts a proxy for the related database (given on the command line if the sequel command line tool is used, or by the db argument to Sequel::Migration#apply if the API is used). The methods that can be used inside Sequel::Migration#up or Sequel::Migration#down are just Sequel::Database instance methods, such as create_table, drop_table, and alter_table. Most database methods that alter the schema take regular arguments, but create_table and alter_table take a block. The methods you can use inside the create_table block are documented in Sequel::Schema::Generator, and the methods you can use inside the alter_table block are documented in Sequel::Schema::AlterTableGenerator.
8
+
9
+ Migrations are not required, you can just call the schema modification methods directly on the database object. This is often done in test code and examples. However, it is recommended that you use the migration framework unless the database schema will not be changing in the future, as it provides a way to easily handle modifications to existing database schema.
@@ -154,18 +154,18 @@ module Sequel
154
154
  return yield(conn) if @transactions.include?(Thread.current)
155
155
  stmt = conn.createStatement
156
156
  begin
157
- log_info(Sequel::Database::SQL_BEGIN)
158
- stmt.execute(Sequel::Database::SQL_BEGIN)
157
+ log_info(begin_transaction_sql)
158
+ stmt.execute(begin_transaction_sql)
159
159
  @transactions << Thread.current
160
160
  yield(conn)
161
161
  rescue Exception => e
162
- log_info(Sequel::Database::SQL_ROLLBACK)
163
- stmt.execute(Sequel::Database::SQL_ROLLBACK)
164
- raise e unless Error::Rollback === e
162
+ log_info(rollback_transaction_sql)
163
+ stmt.execute(rollback_transaction_sql)
164
+ transaction_error(e)
165
165
  ensure
166
166
  unless e
167
- log_info(Sequel::Database::SQL_COMMIT)
168
- stmt.execute(Sequel::Database::SQL_COMMIT)
167
+ log_info(commit_transaction_sql)
168
+ stmt.execute(commit_transaction_sql)
169
169
  end
170
170
  stmt.close
171
171
  @transactions.delete(Thread.current)
@@ -146,28 +146,23 @@ module Sequel
146
146
  @server_version ||= (synchronize(server){|conn| conn.server_version if conn.respond_to?(:server_version)} || super)
147
147
  end
148
148
 
149
- # Return an array of symbols specifying table names in the current database.
150
- def tables(server=nil)
151
- synchronize(server){|conn| conn.list_tables.map {|t| t.to_sym}}
152
- end
153
-
154
149
  # Support single level transactions on MySQL.
155
150
  def transaction(server=nil)
156
151
  synchronize(server) do |conn|
157
152
  return yield(conn) if @transactions.include?(Thread.current)
158
- log_info(SQL_BEGIN)
159
- conn.query(SQL_BEGIN)
153
+ log_info(begin_transaction_sql)
154
+ conn.query(begin_transaction_sql)
160
155
  begin
161
156
  @transactions << Thread.current
162
157
  yield(conn)
163
158
  rescue ::Exception => e
164
- log_info(SQL_ROLLBACK)
165
- conn.query(SQL_ROLLBACK)
159
+ log_info(rollback_transaction_sql)
160
+ conn.query(rollback_transaction_sql)
166
161
  transaction_error(e, Mysql::Error)
167
162
  ensure
168
163
  unless e
169
- log_info(SQL_COMMIT)
170
- conn.query(SQL_COMMIT)
164
+ log_info(commit_transaction_sql)
165
+ conn.query(commit_transaction_sql)
171
166
  end
172
167
  @transactions.delete(Thread.current)
173
168
  end
@@ -2,16 +2,36 @@ module Sequel
2
2
  module MSSQL
3
3
  module DatabaseMethods
4
4
  AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
5
+ SQL_BEGIN = "BEGIN TRANSACTION".freeze
6
+ SQL_COMMIT = "COMMIT TRANSACTION".freeze
7
+ SQL_ROLLBACK = "ROLLBACK TRANSACTION".freeze
5
8
 
6
9
  def auto_increment_sql
7
10
  AUTO_INCREMENT
8
11
  end
9
-
12
+
10
13
  def dataset(opts = nil)
11
14
  ds = super
12
15
  ds.extend(DatasetMethods)
13
16
  ds
14
17
  end
18
+
19
+ private
20
+
21
+ # SQL to BEGIN a transaction.
22
+ def begin_transaction_sql
23
+ SQL_BEGIN
24
+ end
25
+
26
+ # SQL to COMMIT a transaction.
27
+ def commit_transaction_sql
28
+ SQL_COMMIT
29
+ end
30
+
31
+ # SQL to ROLLBACK a transaction.
32
+ def rollback_transaction_sql
33
+ SQL_ROLLBACK
34
+ end
15
35
  end
16
36
 
17
37
  module DatasetMethods
@@ -7,9 +7,6 @@ module Sequel
7
7
  NOT_NULL = Sequel::Schema::SQL::NOT_NULL
8
8
  NULL = Sequel::Schema::SQL::NULL
9
9
  PRIMARY_KEY = Sequel::Schema::SQL::PRIMARY_KEY
10
- SQL_BEGIN = Sequel::Database::SQL_BEGIN
11
- SQL_COMMIT = Sequel::Database::SQL_COMMIT
12
- SQL_ROLLBACK = Sequel::Database::SQL_ROLLBACK
13
10
  TYPES = Sequel::Schema::SQL::TYPES
14
11
  UNIQUE = Sequel::Schema::SQL::UNIQUE
15
12
  UNSIGNED = Sequel::Schema::SQL::UNSIGNED
@@ -38,7 +35,7 @@ module Sequel
38
35
 
39
36
  # Handle MySQL specific syntax for column references
40
37
  def column_references_sql(column)
41
- ", FOREIGN KEY (#{quote_identifier(column[:name])})#{super(column)}"
38
+ "#{", FOREIGN KEY (#{quote_identifier(column[:name])})" unless column[:type] == :check}#{super(column)}"
42
39
  end
43
40
 
44
41
  # Handle MySQL specific index SQL syntax
@@ -62,6 +59,11 @@ module Sequel
62
59
  @server_version ||= (m[1].to_i * 10000) + (m[2].to_i * 100) + m[3].to_i
63
60
  end
64
61
 
62
+ # Return an array of symbols specifying table names in the current database.
63
+ def tables(server=nil)
64
+ self['SHOW TABLES'].server(server).map{|r| r.values.first.to_sym}
65
+ end
66
+
65
67
  # Changes the database in use by issuing a USE statement. I would be
66
68
  # very careful if I used this.
67
69
  def use(db_name)
@@ -73,27 +75,18 @@ module Sequel
73
75
 
74
76
  private
75
77
 
76
- # Always quote identifiers for the schema parser dataset.
77
- def schema_ds_dataset
78
- ds = schema_utility_dataset.clone
79
- ds.quote_identifiers = true
80
- ds
81
- end
82
-
83
- # Allow other database schema's to be queried using the :database
84
- # option. Allow all database's schema to be used by setting
85
- # the :database option to nil. If the database option is not specified,
86
- # uses the currently connected database.
87
- def schema_ds_filter(table_name, opts)
88
- filt = super
89
- # Restrict it to the given or current database, unless specifically requesting :database = nil
90
- filt = SQL::BooleanExpression.new(:AND, filt, {:c__table_schema=>opts[:database] || database_name}) if opts[:database] || !opts.include?(:database)
91
- filt
92
- end
93
-
94
- # MySQL doesn't support table catalogs, so just join on schema and table name.
95
- def schema_ds_join(table_name, opts)
96
- [:information_schema__columns, {:table_schema => :table_schema, :table_name => :table_name}, :c]
78
+ # Use the MySQL specific DESCRIBE syntax to get a table description.
79
+ def schema_parse_table(table_name, opts)
80
+ self["DESCRIBE ?", table_name].map do |row|
81
+ row.delete(:Extra)
82
+ row[:allow_null] = row.delete(:Null) == 'YES'
83
+ row[:default] = row.delete(:Default)
84
+ row[:primary_key] = row.delete(:Key) == 'PRI'
85
+ row[:default] = nil if row[:default].blank?
86
+ row[:db_type] = row.delete(:Type)
87
+ row[:type] = schema_column_type(row[:db_type])
88
+ [row.delete(:Field).to_sym, row]
89
+ end
97
90
  end
98
91
  end
99
92
 
@@ -193,9 +186,8 @@ module Sequel
193
186
 
194
187
  # MySQL specific syntax for inserting multiple values at once.
195
188
  def multi_insert_sql(columns, values)
196
- columns = column_list(columns)
197
189
  values = values.map {|r| literal(Array(r))}.join(COMMA_SEPARATOR)
198
- ["INSERT INTO #{source_list(@opts[:from])} (#{columns}) VALUES #{values}"]
190
+ ["INSERT INTO #{source_list(@opts[:from])} (#{identifier_list(columns)}) VALUES #{values}"]
199
191
  end
200
192
 
201
193
  # MySQL uses the nonstandard ` (backtick) for quoting identifiers.
@@ -128,7 +128,7 @@ module Sequel
128
128
  filter = " WHERE #{filter_expr(filter)}" if filter
129
129
  case index_type
130
130
  when :full_text
131
- lang = index[:language] ? "#{literal(index[:language])}, " : ""
131
+ lang = "#{literal(index[:language] || 'simple')}, "
132
132
  cols = index[:columns].map {|c| literal(c)}.join(" || ")
133
133
  expr = "(to_tsvector(#{lang}#{cols}))"
134
134
  index_type = :gin
@@ -150,6 +150,22 @@ module Sequel
150
150
  synchronize(server){|conn| primary_key_for_table(conn, table)}
151
151
  end
152
152
 
153
+ # Support :schema__table format for table
154
+ def schema(table_name=nil, opts={})
155
+ case table_name
156
+ when Symbol
157
+ t, c, a = dataset.send(:split_symbol, table_name)
158
+ opts[:schema] ||= t
159
+ table_name = c
160
+ when SQL::QualifiedIdentifier
161
+ opts[:schema] ||= table_name.table
162
+ table_name = table_name.column
163
+ when SQL::Identifier
164
+ table_name = table_name.value
165
+ end
166
+ super(table_name, opts)
167
+ end
168
+
153
169
  # PostgreSQL uses SERIAL psuedo-type instead of AUTOINCREMENT for
154
170
  # managing incrementing primary keys.
155
171
  def serial_primary_key_options
@@ -267,14 +283,55 @@ module Sequel
267
283
  @primary_key_sequences.include?(table) ? @primary_key_sequences[table] : (@primary_key_sequences[table] = conn.sequence(table))
268
284
  end
269
285
 
270
- # When the :schema option is used, use the the given schema.
271
- # When the :schema option is nil, return results for all schemas.
272
- # If the :schema option is not used, use the public schema.
273
- def schema_ds_filter(table_name, opts)
274
- filt = super
275
- # Restrict it to the given or public schema, unless specifically requesting :schema = nil
276
- filt = SQL::BooleanExpression.new(:AND, filt, {:c__table_schema=>opts[:schema] || 'public'}) if opts[:schema] || !opts.include?(:schema)
277
- filt
286
+ # Set the default of the row to NULL if it is blank, and set
287
+ # the ruby type for the column based on the database type.
288
+ def schema_parse_rows(rows)
289
+ rows.map do |row|
290
+ row[:default] = nil if row[:default].blank?
291
+ row[:type] = schema_column_type(row[:db_type])
292
+ [row.delete(:name).to_sym, row]
293
+ end
294
+ end
295
+
296
+ # Parse the schema for a single table.
297
+ def schema_parse_table(table_name, opts)
298
+ schema_parse_rows(schema_parser_dataset(table_name, opts))
299
+ end
300
+
301
+ # Parse the schema for multiple tables.
302
+ def schema_parse_tables(opts)
303
+ schemas = {}
304
+ schema_parser_dataset(nil, opts).each do |row|
305
+ (schemas[row.delete(:table).to_sym] ||= []) << row
306
+ end
307
+ schemas.each do |table, rows|
308
+ schemas[table] = schema_parse_rows(rows)
309
+ end
310
+ schemas
311
+ end
312
+
313
+ # The dataset used for parsing table schemas, using the pg_* system catalogs.
314
+ def schema_parser_dataset(table_name, opts)
315
+ ds = dataset.select(:pg_attribute__attname___name,
316
+ SQL::Function.new(:format_type, :pg_type__oid, :pg_attribute__atttypmod).as(:db_type),
317
+ SQL::Function.new(:pg_get_expr, :pg_attrdef__adbin, :pg_class__oid).as(:default),
318
+ SQL::BooleanExpression.new(:NOT, :pg_attribute__attnotnull).as(:allow_null),
319
+ SQL::Function.new(:COALESCE, {:pg_attribute__attnum => SQL::Function.new(:ANY, :pg_index__indkey)}.sql_expr, false).as(:primary_key)).
320
+ from(:pg_class).
321
+ join(:pg_attribute, :attrelid=>:oid).
322
+ join(:pg_type, :oid=>:atttypid).
323
+ left_outer_join(:pg_attrdef, :adrelid=>:pg_class__oid, :adnum=>:pg_attribute__attnum).
324
+ left_outer_join(:pg_index, :indrelid=>:pg_class__oid, :indisprimary=>true).
325
+ filter(:pg_attribute__attisdropped=>false).
326
+ filter(:pg_attribute__attnum > 0).
327
+ order(:pg_attribute__attnum)
328
+ if table_name
329
+ ds.filter!(:pg_class__relname=>table_name.to_s)
330
+ else
331
+ ds.select_more!(:pg_class__relname___table)
332
+ end
333
+ ds.join!(:pg_namespace, :oid=>:pg_class__relnamespace, :nspname=>opts[:schema] || 'public') if opts[:schema] || !opts.include?(:schema)
334
+ ds
278
335
  end
279
336
  end
280
337
 
@@ -409,9 +466,8 @@ module Sequel
409
466
  return super if server_version < 80200
410
467
 
411
468
  # postgresql 8.2 introduces support for multi-row insert
412
- columns = column_list(columns)
413
469
  values = values.map {|r| literal(Array(r))}.join(COMMA_SEPARATOR)
414
- ["INSERT INTO #{source_list(@opts[:from])} (#{columns}) VALUES #{values}"]
470
+ ["INSERT INTO #{source_list(@opts[:from])} (#{identifier_list(columns)}) VALUES #{values}"]
415
471
  end
416
472
 
417
473
  # PostgreSQL assumes unquoted identifiers are lower case by default,
@@ -2,7 +2,6 @@ module Sequel
2
2
  module SQLite
3
3
  module DatabaseMethods
4
4
  AUTO_VACUUM = {'0' => :none, '1' => :full, '2' => :incremental}.freeze
5
- SCHEMA_TYPE_RE = /\A(\w+)\((\d+)\)\z/
6
5
  SYNCHRONOUS = {'0' => :off, '1' => :normal, '2' => :full}.freeze
7
6
  TABLES_FILTER = "type = 'table' AND NOT name = 'sqlite_sequence'"
8
7
  TEMP_STORE = {'0' => :default, '1' => :file, '2' => :memory}.freeze
@@ -86,31 +85,16 @@ module Sequel
86
85
  # SQLite supports schema parsing using the table_info PRAGMA, so
87
86
  # parse the output of that into the format Sequel expects.
88
87
  def schema_parse_table(table_name, opts)
89
- rows = self["PRAGMA table_info(?)", table_name].collect do |row|
88
+ self["PRAGMA table_info(?)", table_name].map do |row|
90
89
  row.delete(:cid)
91
- row[:column] = row.delete(:name)
92
- row[:allow_null] = row.delete(:notnull).to_i == 0 ? 'YES' : 'NO'
90
+ row[:allow_null] = row.delete(:notnull).to_i == 0
93
91
  row[:default] = row.delete(:dflt_value)
94
- row[:primary_key] = row.delete(:pk).to_i == 1 ? true : false
92
+ row[:primary_key] = row.delete(:pk).to_i == 1
93
+ row[:default] = nil if row[:default].blank?
95
94
  row[:db_type] = row.delete(:type)
96
- if m = SCHEMA_TYPE_RE.match(row[:db_type])
97
- row[:db_type] = m[1]
98
- row[:max_chars] = m[2].to_i
99
- else
100
- row[:max_chars] = nil
101
- end
102
- row[:numeric_precision] = nil
103
- row
95
+ row[:type] = schema_column_type(row[:db_type])
96
+ [row.delete(:name).to_sym, row]
104
97
  end
105
- schema_parse_rows(rows)
106
- end
107
-
108
- # SQLite doesn't support getting the schema of all tables at once,
109
- # so loop through the output of #tables to get them.
110
- def schema_parse_tables(opts)
111
- schemas = {}
112
- tables.each{|table| schemas[table] = schema_parse_table(table, opts)}
113
- schemas
114
98
  end
115
99
  end
116
100
 
@@ -169,6 +153,11 @@ module Sequel
169
153
 
170
154
  private
171
155
 
156
+ # SQLite uses string literals instead of identifiers in AS clauses.
157
+ def as_sql(expression, aliaz)
158
+ "#{expression} AS #{literal(aliaz.to_s)}"
159
+ end
160
+
172
161
  # Call execute_insert on the database with the given SQL.
173
162
  def execute_insert(sql, opts={})
174
163
  @db.execute_insert(sql, {:server=>@opts[:server] || :default}.merge(opts))