sequel 4.11.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/Rakefile +1 -5
- data/doc/opening_databases.rdoc +5 -1
- data/doc/release_notes/4.12.0.txt +105 -0
- data/lib/sequel/adapters/jdbc.rb +1 -0
- data/lib/sequel/adapters/oracle.rb +1 -0
- data/lib/sequel/adapters/postgres.rb +17 -8
- data/lib/sequel/adapters/shared/cubrid.rb +2 -1
- data/lib/sequel/adapters/shared/db2.rb +1 -0
- data/lib/sequel/adapters/shared/mssql.rb +1 -0
- data/lib/sequel/adapters/shared/postgres.rb +23 -2
- data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -0
- data/lib/sequel/adapters/sqlite.rb +11 -5
- data/lib/sequel/database/query.rb +14 -1
- data/lib/sequel/dataset/prepared_statements.rb +2 -1
- data/lib/sequel/dataset/query.rb +48 -37
- data/lib/sequel/dataset/sql.rb +0 -39
- data/lib/sequel/extensions/pg_interval.rb +1 -1
- data/lib/sequel/extensions/pg_static_cache_updater.rb +11 -5
- data/lib/sequel/model/associations.rb +2 -2
- data/lib/sequel/plugins/auto_validations.rb +16 -4
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +72 -59
- data/lib/sequel/plugins/prepared_statements.rb +16 -5
- data/lib/sequel/plugins/prepared_statements_associations.rb +14 -0
- data/lib/sequel/sql.rb +2 -43
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +49 -20
- data/spec/bin_spec.rb +2 -2
- data/spec/core/dataset_spec.rb +18 -6
- data/spec/core/schema_spec.rb +2 -1
- data/spec/extensions/auto_validations_spec.rb +23 -2
- data/spec/extensions/nested_attributes_spec.rb +32 -1
- data/spec/extensions/pg_static_cache_updater_spec.rb +12 -0
- data/spec/extensions/prepared_statements_associations_spec.rb +17 -17
- data/spec/extensions/prepared_statements_spec.rb +11 -8
- data/spec/integration/plugin_test.rb +43 -0
- data/spec/integration/schema_test.rb +7 -0
- data/spec/model/eager_loading_spec.rb +9 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b15d571f0ccc175749541cfee443b953dcd145fd
|
4
|
+
data.tar.gz: 9dec9dd2f6816432f511c0153737646e44da31a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec94d8b6fcd34fecdb4d4c3cc4f2b4fb0277c8d7289baebde098b8b84cc99ab0bfd0ab28effa316df0a0fbba1a7bf2cc3bc0fbbfc682e68f6d50326652719306
|
7
|
+
data.tar.gz: 919e8651ded7808d66e95788af7993c4b13136487bed14b6e12db2150bca22ab166eef6e0eeb5350b2e2aebdb6f72c36f47ef7dfaef4e3eea2170c396f15f02c
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
=== 4.12.0 (2014-07-01)
|
2
|
+
|
3
|
+
* Support :readonly Database option in sqlite adapter (ippeiukai, jeremyevans) (#832)
|
4
|
+
|
5
|
+
* Automatically setup max_length validations for string columns in the auto_validations plugin (jeremyevans)
|
6
|
+
|
7
|
+
* Add :max_length entry to column schema hashes for string types (jeremyevans)
|
8
|
+
|
9
|
+
* Add :before_thread_exit option to Database#listen_for_static_cache_updates in pg_static_cache_updater extension (jeremyevans)
|
10
|
+
|
11
|
+
* Add Database#values on PostgreSQL to create a dataset that uses VALUES instead of SELECT (jeremyevans)
|
12
|
+
|
13
|
+
* Add Model#set_nested_attributes to nested_attributes, allowing setting nested attributes options per-call (jeremyevans)
|
14
|
+
|
15
|
+
* Use explicit columns when using automatically prepared SELECT statements in the prepared statement plugins (jeremyevans)
|
16
|
+
|
17
|
+
* Make Dataset#insert_select on PostgreSQL respect existing RETURNING clause (jeremyevans)
|
18
|
+
|
19
|
+
* Fix eager loading limited associations via a UNION when an association block is used (jeremyevans)
|
20
|
+
|
21
|
+
* Associate reciprocal object before saving associated object when creating new objects in nested_attributes (chanks, jeremyevans) (#831)
|
22
|
+
|
23
|
+
* Handle intervals containing more than 100 hours in the pg_interval extension's parser (will) (#827)
|
24
|
+
|
25
|
+
* Remove methods/class deprecated in 4.11.0 (jeremyevans)
|
26
|
+
|
27
|
+
* Allow Dataset#natural_join/cross_join and related methods to take a options hash passed to join_table (jeremyevans)
|
28
|
+
|
29
|
+
* Add :reset_implicit_qualifier option to Dataset#join_table, to set false to not reset the implicit qualifier (jeremyevans)
|
30
|
+
|
31
|
+
* Support :notice_receiver Database option when postgres adapter is used with pg driver (jeltz, jeremyevans) (#825)
|
32
|
+
|
1
33
|
=== 4.11.0 (2014-06-03)
|
2
34
|
|
3
35
|
* Add :model_map option to class_table_inheritance plugin so class names don't need to be stored in the database (jeremyevans)
|
data/Rakefile
CHANGED
@@ -33,10 +33,6 @@ RDOC_DEFAULT_OPTS = ["--line-numbers", "--inline-source", '--title', 'Sequel: Th
|
|
33
33
|
|
34
34
|
begin
|
35
35
|
# Sequel uses hanna-nouveau for the website RDoc.
|
36
|
-
# Due to bugs in older versions of RDoc, and the
|
37
|
-
# fact that hanna-nouveau does not support RDoc 4,
|
38
|
-
# a specific version of rdoc is required.
|
39
|
-
gem 'rdoc', '= 3.12.2'
|
40
36
|
gem 'hanna-nouveau'
|
41
37
|
RDOC_DEFAULT_OPTS.concat(['-f', 'hanna'])
|
42
38
|
rescue Gem::LoadError
|
@@ -68,7 +64,7 @@ if rdoc_task_class
|
|
68
64
|
rdoc_task_class.new(:website_rdoc_main) do |rdoc|
|
69
65
|
rdoc.rdoc_dir = "www/public/rdoc"
|
70
66
|
rdoc.options += RDOC_OPTS + %w'--no-ignore-invalid'
|
71
|
-
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/*.rb lib/sequel/*.rb lib/sequel/{connection_pool,dataset,database,model}/*.rb doc/*.rdoc doc/release_notes/*.txt lib/sequel/extensions/migration.rb
|
67
|
+
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/*.rb lib/sequel/*.rb lib/sequel/{connection_pool,dataset,database,model}/*.rb doc/*.rdoc doc/release_notes/*.txt lib/sequel/extensions/migration.rb"
|
72
68
|
end
|
73
69
|
|
74
70
|
rdoc_task_class.new(:website_rdoc_adapters) do |rdoc|
|
data/doc/opening_databases.rdoc
CHANGED
@@ -373,9 +373,12 @@ The following additional options are supported:
|
|
373
373
|
conversion is done, so an error is raised if you attempt to retrieve an infinite
|
374
374
|
timestamp/date. You can set this to :nil to convert to nil, :string to leave
|
375
375
|
as a string, or :float to convert to an infinite float.
|
376
|
-
:encoding :: Set the client_encoding to the given string
|
377
376
|
:connect_timeout :: Set the number of seconds to wait for a connection (default 20, only respected
|
378
377
|
if using the pg library).
|
378
|
+
:encoding :: Set the client_encoding to the given string
|
379
|
+
:notice_receiver :: A proc that be called with the PGresult objects that have notice or warning messages.
|
380
|
+
The default notice receiver just prints the messages to stderr, but this can be used
|
381
|
+
to handle notice/warning messages differently. Only respected if using the pg library).
|
379
382
|
:sslmode :: Set to 'disable', 'allow', 'prefer', 'require' to choose how to treat SSL (only
|
380
383
|
respected if using the pg library)
|
381
384
|
:use_iso_date_format :: This can be set to false to not force the ISO date format. Sequel forces
|
@@ -417,6 +420,7 @@ Examples:
|
|
417
420
|
|
418
421
|
The following additional options are supported:
|
419
422
|
|
423
|
+
:readonly :: open database in read-only mode
|
420
424
|
:timeout :: the busy timeout to use in milliseconds (default: 5000).
|
421
425
|
|
422
426
|
=== swift
|
@@ -0,0 +1,105 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Database#schema now includes :max_length entries for string
|
4
|
+
columns, specifying the size of the string field. The
|
5
|
+
auto_validations plugin now uses this information to
|
6
|
+
automatically set up max_length validations on those fields.
|
7
|
+
|
8
|
+
* The Dataset join methods now support a :reset_implicit_qualifier
|
9
|
+
option. If set to false, this makes the join not reset the
|
10
|
+
implicit qualifier, so that the next join will not consider this
|
11
|
+
table as the last table joined. Example:
|
12
|
+
|
13
|
+
DB[:a].join(:b, :c=>:d).
|
14
|
+
join(:e, :f=>:g)
|
15
|
+
# SELECT * FROM a
|
16
|
+
# INNER JOIN b ON (b.c = a.d)
|
17
|
+
# INNER JOIN e ON (e.f = b.g)
|
18
|
+
|
19
|
+
DB[:a].join(:b, {:c=>:d}, :reset_implicit_qualifier=>false).
|
20
|
+
join(:e, :f=>:g)
|
21
|
+
# SELECT * FROM a
|
22
|
+
# INNER JOIN b ON (b.c = a.d)
|
23
|
+
# INNER JOIN e ON (e.f = a.g)
|
24
|
+
|
25
|
+
* The Dataset cross and natural join methods now accept an options
|
26
|
+
hash. Example:
|
27
|
+
|
28
|
+
DB[:a].cross_join(:b, :table_alias=>:c)
|
29
|
+
# SELECT * FROM a CROSS JOIN b AS c
|
30
|
+
|
31
|
+
* Model#set_nested_attributes has been added to the nested_attributes
|
32
|
+
plugin, which allows you to to set the nested_attributes options to
|
33
|
+
use per-call. This is very helpful if you have multiple forms that
|
34
|
+
handle associated objects, but with different input fields used
|
35
|
+
for the associated objects depending on the form. Example:
|
36
|
+
|
37
|
+
album.set_nested_attributes(:tracks,
|
38
|
+
params[:track_attributes],
|
39
|
+
:fields=>[:a, :b, :c])
|
40
|
+
|
41
|
+
* Database#values has been added on PostgreSQL, which creates a
|
42
|
+
dataset that uses VALUES instead of SELECT. Just as PostgreSQL
|
43
|
+
allows, you can also use orders, limits, and offsets with this
|
44
|
+
dataset.
|
45
|
+
|
46
|
+
* A :notice_receiver option is now supported in the postgres adapter
|
47
|
+
if the pg driver is used. This should be a proc, which will be
|
48
|
+
passed to the pg connection's set_notice_receiver method.
|
49
|
+
|
50
|
+
* A Database :readonly option is now supported in the sqlite adapter,
|
51
|
+
which opens the database in a read-only mode, causing an error
|
52
|
+
if a query is issued that would modify the database.
|
53
|
+
|
54
|
+
* A :before_thread_exit option has been added to
|
55
|
+
Database#listen_for_static_cache_updates in the
|
56
|
+
pg_static_cache_updater extension, allowing you to run code before
|
57
|
+
the created thread exits.
|
58
|
+
|
59
|
+
= Other Improvements
|
60
|
+
|
61
|
+
* Eager loading limited associations using a UNION now works
|
62
|
+
correctly when an association block is used. This fixes a
|
63
|
+
regression that first occurred in 4.10.0, when the union
|
64
|
+
eager loader became the default eager loader.
|
65
|
+
|
66
|
+
* When creating a new associated object in the nested_attributes
|
67
|
+
plugin, where the reciprocal association is a many_to_one
|
68
|
+
association, set the cached reciprocal object in the new
|
69
|
+
associated object before saving it.
|
70
|
+
|
71
|
+
This fixes issues when validations in the associated object
|
72
|
+
require access to the current object, which may not yet be
|
73
|
+
saved in the database.
|
74
|
+
|
75
|
+
* The prepared_statements and prepared_statements_associations
|
76
|
+
plugins now automatically use explicit column references when
|
77
|
+
preparing statements. This fixes issues on PostgreSQL when a
|
78
|
+
column is added to a table while a prepared statement exists
|
79
|
+
that selects * from the table. Previously, all further attempts
|
80
|
+
to use the prepared statement will fail.
|
81
|
+
|
82
|
+
This allows you to run migrations that add columns to tables
|
83
|
+
while concurrently running an application that uses the
|
84
|
+
prepared statements plugins. Note that many other schema
|
85
|
+
modifications can cause issues when running migrations
|
86
|
+
while concurrently running an application, but most of those
|
87
|
+
are not specific to usage of prepared statements.
|
88
|
+
|
89
|
+
* Dataset#insert_select on PostgreSQL now respects an existing
|
90
|
+
RETURNING clause, and won't override it to use RETURNING *.
|
91
|
+
|
92
|
+
A similar fix was applied to the generalized prepared statements
|
93
|
+
support as well.
|
94
|
+
|
95
|
+
* The interval parser in the pg_interval extension now supports
|
96
|
+
intervals with 2-10 digits for hours. Previously, it only
|
97
|
+
supported using 2 digits for hours.
|
98
|
+
|
99
|
+
= Backwards Compatibility
|
100
|
+
|
101
|
+
* The methods and classes deprecated in 4.11.0 have been removed.
|
102
|
+
|
103
|
+
* The nested_attributes internal API has changed significantly. If
|
104
|
+
you were calling any private nested_attributes methods, you'll
|
105
|
+
probably need to update your code.
|
data/lib/sequel/adapters/jdbc.rb
CHANGED
@@ -729,6 +729,7 @@ module Sequel
|
|
729
729
|
metadata(:getColumns, nil, schema, table, nil) do |h|
|
730
730
|
next if schema_parse_table_skip?(h, schema)
|
731
731
|
s = {:type=>schema_column_type(h[:type_name]), :db_type=>h[:type_name], :default=>(h[:column_def] == '' ? nil : h[:column_def]), :allow_null=>(h[:nullable] != 0), :primary_key=>pks.include?(h[:column_name]), :column_size=>h[:column_size], :scale=>h[:decimal_digits]}
|
732
|
+
s[:max_length] = s[:column_size] if s[:type] == :string
|
732
733
|
if s[:db_type] =~ DECIMAL_TYPE_RE && s[:scale] == 0
|
733
734
|
s[:type] = :integer
|
734
735
|
end
|
@@ -198,12 +198,13 @@ module Sequel
|
|
198
198
|
# Connects to the database. In addition to the standard database
|
199
199
|
# options, using the :encoding or :charset option changes the
|
200
200
|
# client encoding for the connection, :connect_timeout is a
|
201
|
-
# connection timeout in seconds,
|
202
|
-
# sslmode
|
203
|
-
#
|
201
|
+
# connection timeout in seconds, :sslmode sets whether postgres's
|
202
|
+
# sslmode, and :notice_receiver handles server notices in a proc.
|
203
|
+
# :connect_timeout, :ssl_mode, and :notice_receiver are only supported
|
204
|
+
# if the pg driver is used.
|
204
205
|
def connect(server)
|
205
206
|
opts = server_opts(server)
|
206
|
-
|
207
|
+
if SEQUEL_POSTGRES_USES_PG
|
207
208
|
connection_params = {
|
208
209
|
:host => opts[:host],
|
209
210
|
:port => opts[:port] || 5432,
|
@@ -213,9 +214,15 @@ module Sequel
|
|
213
214
|
:connect_timeout => opts[:connect_timeout] || 20,
|
214
215
|
:sslmode => opts[:sslmode]
|
215
216
|
}.delete_if { |key, value| blank_object?(value) }
|
216
|
-
Adapter.connect(connection_params)
|
217
|
+
conn = Adapter.connect(connection_params)
|
218
|
+
|
219
|
+
conn.instance_variable_set(:@prepared_statements, {})
|
220
|
+
|
221
|
+
if receiver = opts[:notice_receiver]
|
222
|
+
conn.set_notice_receiver(&receiver)
|
223
|
+
end
|
217
224
|
else
|
218
|
-
Adapter.connect(
|
225
|
+
conn = Adapter.connect(
|
219
226
|
(opts[:host] unless blank_object?(opts[:host])),
|
220
227
|
opts[:port] || 5432,
|
221
228
|
nil, '',
|
@@ -224,6 +231,9 @@ module Sequel
|
|
224
231
|
opts[:password]
|
225
232
|
)
|
226
233
|
end
|
234
|
+
|
235
|
+
conn.instance_variable_set(:@db, self)
|
236
|
+
|
227
237
|
if encoding = opts[:encoding] || opts[:charset]
|
228
238
|
if conn.respond_to?(:set_client_encoding)
|
229
239
|
conn.set_client_encoding(encoding)
|
@@ -231,8 +241,7 @@ module Sequel
|
|
231
241
|
conn.async_exec("set client_encoding to '#{encoding}'")
|
232
242
|
end
|
233
243
|
end
|
234
|
-
|
235
|
-
conn.instance_variable_set(:@prepared_statements, {}) if SEQUEL_POSTGRES_USES_PG
|
244
|
+
|
236
245
|
connection_configuration_sqls.each{|sql| conn.execute(sql)}
|
237
246
|
conn
|
238
247
|
end
|
@@ -51,12 +51,13 @@ module Sequel
|
|
51
51
|
from(:db_attribute).
|
52
52
|
where(:class_name=>m2.call(table_name)).
|
53
53
|
order(:def_order).
|
54
|
-
select(:attr_name, :data_type___db_type, :default_value___default, :is_nullable___allow_null).
|
54
|
+
select(:attr_name, :data_type___db_type, :default_value___default, :is_nullable___allow_null, :prec).
|
55
55
|
map do |row|
|
56
56
|
name = m.call(row.delete(:attr_name))
|
57
57
|
row[:allow_null] = row[:allow_null] == 'YES'
|
58
58
|
row[:primary_key] = pks.include?(name)
|
59
59
|
row[:type] = schema_column_type(row[:db_type])
|
60
|
+
row[:max_length] = row[:prec] if row[:type] == :string
|
60
61
|
[name, row]
|
61
62
|
end
|
62
63
|
end
|
@@ -42,6 +42,7 @@ module Sequel
|
|
42
42
|
column[:allow_null] = column.delete(:nulls) == 'Y'
|
43
43
|
column[:primary_key] = column.delete(:identity) == 'Y' || !column[:keyseq].nil?
|
44
44
|
column[:type] = schema_column_type(column[:db_type])
|
45
|
+
column[:max_length] = column[:longlength] if column[:type] == :string
|
45
46
|
[ m.call(column.delete(:name)), column]
|
46
47
|
end
|
47
48
|
end
|
@@ -524,6 +524,17 @@ module Sequel
|
|
524
524
|
@supported_types.fetch(type){@supported_types[type] = (from(:pg_type).filter(:typtype=>'b', :typname=>type.to_s).count > 0)}
|
525
525
|
end
|
526
526
|
|
527
|
+
# Creates a dataset that uses the VALUES clause:
|
528
|
+
#
|
529
|
+
# DB.values([[1, 2], [3, 4]])
|
530
|
+
# VALUES ((1, 2), (3, 4))
|
531
|
+
#
|
532
|
+
# DB.values([[1, 2], [3, 4]]).order(:column2).limit(1, 1)
|
533
|
+
# VALUES ((1, 2), (3, 4)) ORDER BY column2 LIMIT 1 OFFSET 1
|
534
|
+
def values(v)
|
535
|
+
@default_dataset.clone(:values=>v)
|
536
|
+
end
|
537
|
+
|
527
538
|
# Array of symbols specifying view names in the current database.
|
528
539
|
#
|
529
540
|
# Options:
|
@@ -1147,12 +1158,13 @@ module Sequel
|
|
1147
1158
|
CRLF = "\r\n".freeze
|
1148
1159
|
BLOB_RE = /[\000-\037\047\134\177-\377]/n.freeze
|
1149
1160
|
WINDOW = " WINDOW ".freeze
|
1161
|
+
SELECT_VALUES = "VALUES ".freeze
|
1150
1162
|
EMPTY_STRING = ''.freeze
|
1151
1163
|
LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each{|s| s.freeze}
|
1152
1164
|
|
1153
1165
|
Dataset.def_sql_method(self, :delete, [['if server_version >= 90100', %w'with delete from using where returning'], ['else', %w'delete from using where returning']])
|
1154
1166
|
Dataset.def_sql_method(self, :insert, [['if server_version >= 90100', %w'with insert into columns values returning'], ['else', %w'insert into columns values returning']])
|
1155
|
-
Dataset.def_sql_method(self, :select, [['if server_version >= 80400', %w'with select distinct columns from join where group having window compounds order limit lock'], ['else', %w'select distinct columns from join where group having compounds order limit lock']])
|
1167
|
+
Dataset.def_sql_method(self, :select, [['if opts[:values]', %w'values order limit'], ['elsif server_version >= 80400', %w'with select distinct columns from join where group having window compounds order limit lock'], ['else', %w'select distinct columns from join where group having compounds order limit lock']])
|
1156
1168
|
Dataset.def_sql_method(self, :update, [['if server_version >= 90100', %w'with update table set from where returning'], ['else', %w'update table set from where returning']])
|
1157
1169
|
|
1158
1170
|
# Shared methods for prepared statements when used with PostgreSQL databases.
|
@@ -1285,7 +1297,10 @@ module Sequel
|
|
1285
1297
|
# Insert a record returning the record inserted. Always returns nil without
|
1286
1298
|
# inserting a query if disable_insert_returning is used.
|
1287
1299
|
def insert_select(*values)
|
1288
|
-
|
1300
|
+
unless @opts[:disable_insert_returning]
|
1301
|
+
ds = opts[:returning] ? self : returning
|
1302
|
+
ds.insert(*values){|r| return r}
|
1303
|
+
end
|
1289
1304
|
end
|
1290
1305
|
|
1291
1306
|
# Locks all tables in the dataset's FROM clause (but not in JOINs) with
|
@@ -1510,6 +1525,12 @@ module Sequel
|
|
1510
1525
|
@opts[:lock] == :share ? (sql << FOR_SHARE) : super
|
1511
1526
|
end
|
1512
1527
|
|
1528
|
+
# Support VALUES clause instead of the SELECT clause to return rows.
|
1529
|
+
def select_values_sql(sql)
|
1530
|
+
sql << SELECT_VALUES
|
1531
|
+
expression_list_append(sql, opts[:values])
|
1532
|
+
end
|
1533
|
+
|
1513
1534
|
# SQL fragment for named window specifications
|
1514
1535
|
def select_window_sql(sql)
|
1515
1536
|
if ws = @opts[:window]
|
@@ -91,14 +91,20 @@ module Sequel
|
|
91
91
|
# The conversion procs to use for this database
|
92
92
|
attr_reader :conversion_procs
|
93
93
|
|
94
|
-
# Connect to the database.
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
94
|
+
# Connect to the database. Since SQLite is a file based database,
|
95
|
+
# available options are limited:
|
96
|
+
#
|
97
|
+
# :database :: database name (filename or ':memory:' or file: URI)
|
98
|
+
# :readonly :: open database in read-only mode; useful for reading
|
99
|
+
# static data that you do not want to modify
|
100
|
+
# :timeout :: how long to wait for the database to be available if it
|
101
|
+
# is locked, given in milliseconds (default is 5000)
|
98
102
|
def connect(server)
|
99
103
|
opts = server_opts(server)
|
100
104
|
opts[:database] = ':memory:' if blank_object?(opts[:database])
|
101
|
-
|
105
|
+
sqlite3_opts = {}
|
106
|
+
sqlite3_opts[:readonly] = typecast_value_boolean(opts[:readonly]) if opts.has_key?(:readonly)
|
107
|
+
db = ::SQLite3::Database.new(opts[:database].to_s, sqlite3_opts)
|
102
108
|
db.busy_timeout(opts.fetch(:timeout, 5000))
|
103
109
|
|
104
110
|
connection_pragmas.each{|s| log_yield(s){db.execute_batch(s)}}
|
@@ -157,7 +157,12 @@ module Sequel
|
|
157
157
|
|
158
158
|
cols = schema_parse_table(table_name, opts)
|
159
159
|
raise(Error, 'schema parsing returned no columns, table probably doesn\'t exist') if cols.nil? || cols.empty?
|
160
|
-
cols.each
|
160
|
+
cols.each do |_,c|
|
161
|
+
c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])
|
162
|
+
if !c[:max_length] && c[:type] == :string && (max_length = column_schema_max_length(c[:db_type]))
|
163
|
+
c[:max_length] = max_length
|
164
|
+
end
|
165
|
+
end
|
161
166
|
Sequel.synchronize{@schemas[quoted_name] = cols} if cache_schema
|
162
167
|
cols
|
163
168
|
end
|
@@ -251,6 +256,14 @@ module Sequel
|
|
251
256
|
column_schema_default_to_ruby_value(default, type) rescue nil
|
252
257
|
end
|
253
258
|
|
259
|
+
# Look at the db_type and guess the maximum length of the column.
|
260
|
+
# This assumes types such as varchar(255).
|
261
|
+
def column_schema_max_length(db_type)
|
262
|
+
if db_type =~ /\((\d+)\)/
|
263
|
+
$1.to_i
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
254
267
|
# Return a Method object for the dataset's output_identifier_method.
|
255
268
|
# Used in metadata parsing to make sure the returned information is in the
|
256
269
|
# correct format.
|
@@ -86,7 +86,8 @@ module Sequel
|
|
86
86
|
when :first
|
87
87
|
clone(:limit=>1).select_sql
|
88
88
|
when :insert_select
|
89
|
-
returning
|
89
|
+
ds = opts[:returning] ? self : returning
|
90
|
+
ds.insert_sql(*@prepared_modify_values)
|
90
91
|
when :insert
|
91
92
|
insert_sql(*@prepared_modify_values)
|
92
93
|
when :update
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -23,10 +23,9 @@ module Sequel
|
|
23
23
|
# block from the method call.
|
24
24
|
CONDITIONED_JOIN_TYPES = [:inner, :full_outer, :right_outer, :left_outer, :full, :right, :left]
|
25
25
|
|
26
|
-
# These symbols have _join methods created (e.g. natural_join)
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# if called with a block.
|
26
|
+
# These symbols have _join methods created (e.g. natural_join).
|
27
|
+
# They accept a table argument and options hash which is passed to join_table,
|
28
|
+
# and they raise an error if called with a block.
|
30
29
|
UNCONDITIONED_JOIN_TYPES = [:natural, :natural_left, :natural_right, :natural_full, :cross]
|
31
30
|
|
32
31
|
# All methods that return modified datasets with a joined table added.
|
@@ -387,37 +386,42 @@ module Sequel
|
|
387
386
|
#
|
388
387
|
# Takes the following arguments:
|
389
388
|
#
|
390
|
-
#
|
391
|
-
#
|
392
|
-
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
#
|
400
|
-
#
|
401
|
-
#
|
402
|
-
#
|
403
|
-
#
|
404
|
-
#
|
405
|
-
#
|
406
|
-
#
|
407
|
-
#
|
408
|
-
#
|
409
|
-
#
|
410
|
-
#
|
411
|
-
#
|
412
|
-
#
|
413
|
-
#
|
414
|
-
#
|
415
|
-
#
|
416
|
-
#
|
417
|
-
#
|
418
|
-
#
|
419
|
-
#
|
420
|
-
#
|
389
|
+
# type :: The type of join to do (e.g. :inner)
|
390
|
+
# table :: table to join into the current dataset. Generally one of the following types:
|
391
|
+
# String, Symbol :: identifier used as table or view name
|
392
|
+
# Dataset :: a subselect is performed with an alias of tN for some value of N
|
393
|
+
# SQL::Function :: set returning function
|
394
|
+
# SQL::AliasedExpression :: already aliased expression. Uses given alias unless
|
395
|
+
# overridden by the :table_alias option.
|
396
|
+
# expr :: conditions used when joining, depends on type:
|
397
|
+
# Hash, Array of pairs :: Assumes key (1st arg) is column of joined table (unless already
|
398
|
+
# qualified), and value (2nd arg) is column of the last joined or
|
399
|
+
# primary table (or the :implicit_qualifier option).
|
400
|
+
# To specify multiple conditions on a single joined table column,
|
401
|
+
# you must use an array. Uses a JOIN with an ON clause.
|
402
|
+
# Array :: If all members of the array are symbols, considers them as columns and
|
403
|
+
# uses a JOIN with a USING clause. Most databases will remove duplicate columns from
|
404
|
+
# the result set if this is used.
|
405
|
+
# nil :: If a block is not given, doesn't use ON or USING, so the JOIN should be a NATURAL
|
406
|
+
# or CROSS join. If a block is given, uses an ON clause based on the block, see below.
|
407
|
+
# otherwise :: Treats the argument as a filter expression, so strings are considered literal, symbols
|
408
|
+
# specify boolean columns, and Sequel expressions can be used. Uses a JOIN with an ON clause.
|
409
|
+
# options :: a hash of options, with the following keys supported:
|
410
|
+
# :table_alias :: Override the table alias used when joining. In general you shouldn't use this
|
411
|
+
# option, you should provide the appropriate SQL::AliasedExpression as the table
|
412
|
+
# argument.
|
413
|
+
# :implicit_qualifier :: The name to use for qualifying implicit conditions. By default,
|
414
|
+
# the last joined or primary table is used.
|
415
|
+
# :reset_implicit_qualifier :: Can set to false to ignore this join when future joins determine qualifier
|
416
|
+
# for implicit conditions.
|
417
|
+
# :qualify :: Can be set to false to not do any implicit qualification. Can be set
|
418
|
+
# to :deep to use the Qualifier AST Transformer, which will attempt to qualify
|
419
|
+
# subexpressions of the expression tree. Can be set to :symbol to only qualify
|
420
|
+
# symbols. Defaults to the value of default_join_table_qualification.
|
421
|
+
# block :: The block argument should only be given if a JOIN with an ON clause is used,
|
422
|
+
# in which case it yields the table alias/name for the table currently being joined,
|
423
|
+
# the table alias/name for the last joined (or first table), and an array of previous
|
424
|
+
# SQL::JoinClause. Unlike +where+, this block is not treated as a virtual row block.
|
421
425
|
#
|
422
426
|
# Examples:
|
423
427
|
#
|
@@ -505,7 +509,8 @@ module Sequel
|
|
505
509
|
SQL::JoinOnClause.new(expr, type, table_expr)
|
506
510
|
end
|
507
511
|
|
508
|
-
opts = {:join => (@opts[:join] || []) + [join]
|
512
|
+
opts = {:join => (@opts[:join] || []) + [join]}
|
513
|
+
opts[:last_joined_table] = table_name unless options[:reset_implicit_qualifier] == false
|
509
514
|
opts[:num_dataset_sources] = table_alias_num if table_alias_num
|
510
515
|
clone(opts)
|
511
516
|
end
|
@@ -514,7 +519,13 @@ module Sequel
|
|
514
519
|
class_eval("def #{jtype}_join(*args, &block); join_table(:#{jtype}, *args, &block) end", __FILE__, __LINE__)
|
515
520
|
end
|
516
521
|
UNCONDITIONED_JOIN_TYPES.each do |jtype|
|
517
|
-
class_eval(
|
522
|
+
class_eval(<<-END, __FILE__, __LINE__+1)
|
523
|
+
def #{jtype}_join(table, opts=Sequel::OPTS)
|
524
|
+
raise(Sequel::Error, '#{jtype}_join does not accept join table blocks') if block_given?
|
525
|
+
raise(Sequel::Error, '#{jtype}_join 2nd argument should be an options hash, not conditions') unless opts.is_a?(Hash)
|
526
|
+
join_table(:#{jtype}, table, nil, opts)
|
527
|
+
end
|
528
|
+
END
|
518
529
|
end
|
519
530
|
|
520
531
|
# Marks this dataset as a lateral dataset. If used in another dataset's FROM
|