sequel 3.37.0 → 3.38.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/CHANGELOG +56 -0
  2. data/README.rdoc +82 -58
  3. data/Rakefile +6 -5
  4. data/bin/sequel +1 -1
  5. data/doc/active_record.rdoc +67 -52
  6. data/doc/advanced_associations.rdoc +33 -48
  7. data/doc/association_basics.rdoc +41 -51
  8. data/doc/cheat_sheet.rdoc +21 -21
  9. data/doc/core_extensions.rdoc +374 -0
  10. data/doc/dataset_basics.rdoc +5 -5
  11. data/doc/dataset_filtering.rdoc +47 -43
  12. data/doc/mass_assignment.rdoc +1 -1
  13. data/doc/migration.rdoc +4 -5
  14. data/doc/model_hooks.rdoc +3 -3
  15. data/doc/object_model.rdoc +31 -25
  16. data/doc/opening_databases.rdoc +19 -5
  17. data/doc/prepared_statements.rdoc +2 -2
  18. data/doc/querying.rdoc +109 -52
  19. data/doc/reflection.rdoc +6 -6
  20. data/doc/release_notes/3.38.0.txt +234 -0
  21. data/doc/schema_modification.rdoc +22 -13
  22. data/doc/sharding.rdoc +8 -9
  23. data/doc/sql.rdoc +154 -112
  24. data/doc/testing.rdoc +47 -7
  25. data/doc/thread_safety.rdoc +1 -1
  26. data/doc/transactions.rdoc +1 -1
  27. data/doc/validations.rdoc +1 -1
  28. data/doc/virtual_rows.rdoc +29 -43
  29. data/lib/sequel/adapters/do/postgres.rb +1 -4
  30. data/lib/sequel/adapters/jdbc.rb +14 -3
  31. data/lib/sequel/adapters/jdbc/db2.rb +9 -0
  32. data/lib/sequel/adapters/jdbc/derby.rb +41 -4
  33. data/lib/sequel/adapters/jdbc/jtds.rb +11 -0
  34. data/lib/sequel/adapters/jdbc/postgresql.rb +3 -6
  35. data/lib/sequel/adapters/mock.rb +10 -4
  36. data/lib/sequel/adapters/postgres.rb +1 -28
  37. data/lib/sequel/adapters/shared/mssql.rb +23 -13
  38. data/lib/sequel/adapters/shared/postgres.rb +46 -0
  39. data/lib/sequel/adapters/swift.rb +21 -13
  40. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  41. data/lib/sequel/adapters/swift/postgres.rb +4 -5
  42. data/lib/sequel/adapters/swift/sqlite.rb +2 -1
  43. data/lib/sequel/adapters/tinytds.rb +14 -2
  44. data/lib/sequel/adapters/utils/pg_types.rb +5 -0
  45. data/lib/sequel/core.rb +29 -17
  46. data/lib/sequel/database/query.rb +1 -1
  47. data/lib/sequel/database/schema_generator.rb +3 -0
  48. data/lib/sequel/dataset/actions.rb +5 -6
  49. data/lib/sequel/dataset/query.rb +7 -7
  50. data/lib/sequel/dataset/sql.rb +5 -18
  51. data/lib/sequel/extensions/core_extensions.rb +8 -12
  52. data/lib/sequel/extensions/pg_array.rb +59 -33
  53. data/lib/sequel/extensions/pg_array_ops.rb +32 -4
  54. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -1
  55. data/lib/sequel/extensions/pg_hstore.rb +32 -17
  56. data/lib/sequel/extensions/pg_hstore_ops.rb +32 -3
  57. data/lib/sequel/extensions/pg_inet.rb +1 -2
  58. data/lib/sequel/extensions/pg_interval.rb +0 -1
  59. data/lib/sequel/extensions/pg_json.rb +41 -23
  60. data/lib/sequel/extensions/pg_range.rb +36 -11
  61. data/lib/sequel/extensions/pg_range_ops.rb +32 -4
  62. data/lib/sequel/extensions/pg_row.rb +572 -0
  63. data/lib/sequel/extensions/pg_row_ops.rb +164 -0
  64. data/lib/sequel/extensions/query.rb +3 -3
  65. data/lib/sequel/extensions/schema_dumper.rb +7 -8
  66. data/lib/sequel/extensions/select_remove.rb +1 -1
  67. data/lib/sequel/model/base.rb +1 -0
  68. data/lib/sequel/no_core_ext.rb +1 -1
  69. data/lib/sequel/plugins/pg_row.rb +121 -0
  70. data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
  71. data/lib/sequel/plugins/validation_helpers.rb +31 -0
  72. data/lib/sequel/sql.rb +64 -44
  73. data/lib/sequel/version.rb +1 -1
  74. data/spec/adapters/mssql_spec.rb +37 -12
  75. data/spec/adapters/mysql_spec.rb +39 -75
  76. data/spec/adapters/oracle_spec.rb +11 -11
  77. data/spec/adapters/postgres_spec.rb +414 -237
  78. data/spec/adapters/spec_helper.rb +1 -1
  79. data/spec/adapters/sqlite_spec.rb +14 -14
  80. data/spec/core/database_spec.rb +6 -6
  81. data/spec/core/dataset_spec.rb +169 -205
  82. data/spec/core/expression_filters_spec.rb +182 -295
  83. data/spec/core/object_graph_spec.rb +6 -6
  84. data/spec/core/schema_spec.rb +14 -14
  85. data/spec/core/spec_helper.rb +1 -0
  86. data/spec/{extensions/core_extensions_spec.rb → core_extensions_spec.rb} +208 -14
  87. data/spec/extensions/columns_introspection_spec.rb +5 -5
  88. data/spec/extensions/hook_class_methods_spec.rb +28 -36
  89. data/spec/extensions/many_through_many_spec.rb +4 -4
  90. data/spec/extensions/pg_array_ops_spec.rb +15 -7
  91. data/spec/extensions/pg_array_spec.rb +81 -48
  92. data/spec/extensions/pg_auto_parameterize_spec.rb +2 -2
  93. data/spec/extensions/pg_hstore_ops_spec.rb +13 -9
  94. data/spec/extensions/pg_hstore_spec.rb +66 -65
  95. data/spec/extensions/pg_inet_spec.rb +2 -4
  96. data/spec/extensions/pg_interval_spec.rb +2 -3
  97. data/spec/extensions/pg_json_spec.rb +20 -18
  98. data/spec/extensions/pg_range_ops_spec.rb +11 -4
  99. data/spec/extensions/pg_range_spec.rb +30 -7
  100. data/spec/extensions/pg_row_ops_spec.rb +48 -0
  101. data/spec/extensions/pg_row_plugin_spec.rb +45 -0
  102. data/spec/extensions/pg_row_spec.rb +323 -0
  103. data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
  104. data/spec/extensions/query_literals_spec.rb +11 -11
  105. data/spec/extensions/query_spec.rb +3 -3
  106. data/spec/extensions/schema_dumper_spec.rb +20 -4
  107. data/spec/extensions/schema_spec.rb +18 -41
  108. data/spec/extensions/select_remove_spec.rb +4 -4
  109. data/spec/extensions/spec_helper.rb +4 -8
  110. data/spec/extensions/to_dot_spec.rb +5 -5
  111. data/spec/extensions/validation_class_methods_spec.rb +28 -16
  112. data/spec/integration/associations_test.rb +20 -20
  113. data/spec/integration/dataset_test.rb +98 -98
  114. data/spec/integration/eager_loader_test.rb +13 -27
  115. data/spec/integration/plugin_test.rb +5 -5
  116. data/spec/integration/prepared_statement_test.rb +22 -13
  117. data/spec/integration/schema_test.rb +28 -18
  118. data/spec/integration/spec_helper.rb +1 -1
  119. data/spec/integration/timezone_test.rb +2 -2
  120. data/spec/integration/type_test.rb +15 -6
  121. data/spec/model/association_reflection_spec.rb +1 -1
  122. data/spec/model/associations_spec.rb +4 -4
  123. data/spec/model/base_spec.rb +5 -5
  124. data/spec/model/eager_loading_spec.rb +15 -15
  125. data/spec/model/model_spec.rb +32 -32
  126. data/spec/model/record_spec.rb +16 -0
  127. data/spec/model/spec_helper.rb +2 -6
  128. data/spec/model/validations_spec.rb +1 -1
  129. metadata +16 -4
data/doc/testing.rdoc CHANGED
@@ -12,16 +12,16 @@ Make sure you are using Sequel 3.29.0 or above when using these examples, as old
12
12
 
13
13
  class Spec::Example::ExampleGroup
14
14
  def execute(*args, &block)
15
- x = nil
16
- Sequel::Model.db.transaction(:rollback=>:always){x = super(*args, &block)}
17
- x
15
+ result = nil
16
+ Sequel::Model.db.transaction(:rollback=>:always){result = super(*args, &block)}
17
+ result
18
18
  end
19
19
  end
20
20
 
21
- === RSpec 2
21
+ === RSpec 2, <2.8
22
22
 
23
23
  class RSpec::Core::ExampleGroup
24
- # Setting an around filter globally doesn't appear to work in 2.7 (and maybe other versions),
24
+ # Setting an around filter globally doesn't appear to work in <2.8,
25
25
  # so set one up for each subclass.
26
26
  def self.inherited(subclass)
27
27
  super
@@ -31,21 +31,61 @@ Make sure you are using Sequel 3.29.0 or above when using these examples, as old
31
31
  end
32
32
  end
33
33
 
34
+ === RSpec 2, >=2.8
35
+
36
+ # Global around filters should work
37
+ RSpec.configure do |c|
38
+ c.around(:each) do |example|
39
+ DB.transaction(:rollback=>:always){example.run}
40
+ end
41
+ end
42
+
34
43
  === Test::Unit
35
44
 
36
45
  # Must use this class as the base class for your tests
37
46
  class SequelTestCase < Test::Unit::TestCase
38
47
  def run(*args, &block)
39
- Sequel::Model.db.transaction(:rollback=>:always){super}
48
+ result = nil
49
+ Sequel::Model.db.transaction(:rollback=>:always){result = super}
50
+ result
51
+ end
52
+ end
53
+
54
+ # Or you could override the base implementation like this
55
+ class Test::Unit::TestCase
56
+ alias_method :_original_run, :run
57
+
58
+ def run(*args, &block)
59
+ result = nil
60
+ Sequel::Model.db.transaction(:rollback => :always) do
61
+ result = _original_run(*args, &block)
62
+ end
63
+ result
40
64
  end
41
65
  end
42
66
 
43
67
  === MiniTest::Unit
44
68
 
69
+ # Add a subclass
45
70
  # Must use this class as the base class for your tests
46
71
  class SequelTestCase < MiniTest::Unit::TestCase
47
72
  def run(*args, &block)
48
- Sequel::Model.db.transaction(:rollback=>:always){super}
73
+ result = nil
74
+ Sequel::Model.db.transaction(:rollback=>:always){result = super}
75
+ result
76
+ end
77
+ end
78
+
79
+ # Or you could override the base implementation like this
80
+ class MiniTest::Unit::TestCase
81
+ alias_method :_original_run, :run
82
+
83
+ def run(*args, &block)
84
+ result = nil
85
+ Sequel::Model.db.transaction(:rollback => :always) do
86
+ result = _original_run(*args, &block)
87
+ end
88
+ result
49
89
  end
50
90
  end
51
91
 
@@ -4,7 +4,7 @@ Most Sequel usage (and all common Sequel usage) is thread safe by default. Spec
4
4
 
5
5
  == Connection Pool
6
6
 
7
- In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool is empty, the thread will block (actually busy-wait) until a connection is available or the the connection pool timeout has elapsed (in which case a PoolTimeout error will be raised).
7
+ In order to allow multiple threads to operate on the same database at the same time, Sequel uses a connection pool. The connection pool is designed so that a thread uses a connection for the minimum amount of time, returning the connection to the pool as soon as it is done using the connection. If a thread requests a connection and the pool does not have an available connection, a new connection will be created. If the maximum number of connections in the pool has already been reached, the thread will block (actually busy-wait) until a connection is available or the the connection pool timeout has elapsed (in which case a PoolTimeout error will be raised).
8
8
 
9
9
  == Exceptions
10
10
 
@@ -5,7 +5,7 @@ Sequel uses autocommit mode by default for all of its database adapters, so in g
5
5
  * Dataset#import to insert many records at once
6
6
  * Model#save
7
7
  * Model#destroy
8
- * Migrations
8
+ * Migrations if the database supports transactional schema
9
9
  * A few model plugins
10
10
 
11
11
  Everywhere else, it is up to use to use a database transaction if you want to.
data/doc/validations.rdoc CHANGED
@@ -284,7 +284,7 @@ You can mix and match the two approaches. For example, if all albums should hav
284
284
 
285
285
  +validates_unique+ also accepts a block to scope the uniqueness constraint. For example, if you want to ensure that all active albums have a unique name, but inactive albums can duplicate the name:
286
286
 
287
- validates_unique(:name){|ds| ds.filter(:active)}
287
+ validates_unique(:name){|ds| ds.where(:active)}
288
288
 
289
289
  If you provide a block, it is called with the dataset to use for the uniqueness check, which you can then filter to scope the uniqueness validation to a subset of the model's dataset.
290
290
 
@@ -1,6 +1,6 @@
1
1
  = Virtual Row Blocks
2
2
 
3
- Dataset methods filter, order, and select all take blocks that are referred to as
3
+ Dataset methods where, order, and select all take blocks that are referred to as
4
4
  virtual row blocks. Many other dataset methods pass the blocks
5
5
  they are given into one of those three methods, so there are actually
6
6
  many Sequel::Dataset methods that take virtual row blocks.
@@ -11,7 +11,7 @@ Virtual Rows were created to work around the issue that some parts of
11
11
  Sequel's standard DSL could not be used on ruby 1.9. For example, the
12
12
  following Sequel code works on ruby 1.8, but not ruby 1.9:
13
13
 
14
- dataset.filter(:a > :b[:c])
14
+ dataset.where(:a > :b[:c])
15
15
  # WHERE a > b(c)
16
16
 
17
17
  This code does not work on ruby 1.9 for two reasons. First, Symbol#>
@@ -20,30 +20,15 @@ does not override it to return an SQL inequality expression. Second, Symbol#[]
20
20
  is already defined on ruby 1.9, so Sequel does not override it to return an
21
21
  SQL function expression.
22
22
 
23
- Prior to the introduction of virtual rows, the way to handle this was
24
- to use the methods that work on both ruby 1.8 and ruby 1.9:
23
+ It's possible to use Sequel's DSL to represent such expressions, but it is a
24
+ little verbose:
25
25
 
26
- dataset.filter(:a.identifier > :b.sql_function(:c))
26
+ dataset.where(Sequel.expr(:a) > Sequel.function(:b, :c))
27
27
  # WHERE a > b(c)
28
28
 
29
- However, that code is a little verbose. The virtual row DSL makes such code
30
- more concise:
29
+ The virtual row DSL makes such code more concise:
31
30
 
32
- dataset.filter{a > b(c)}
33
-
34
- Another use of virtual rows is when you turn off Sequel's core extensions off
35
- using the SEQUEL_NO_CORE_EXTENSIONS constant or environment variable. With
36
- the core extensions turned off, much of the standard Sequel DSL is not
37
- available. For example, you are no longer able to do:
38
-
39
- dataset.filter(:a & (:b | ~:c))
40
- # WHERE a AND (b OR NOT c)
41
-
42
- Because Symbol#&, Symbol#| and Symbol#~ are not defined when the core
43
- extensions are turned off. However, virtual rows allow almost the same
44
- syntax even without the core extensions:
45
-
46
- dataset.filter{a & (b | ~c)}
31
+ dataset.where{a > b(c)}
47
32
 
48
33
  == Regular Procs vs Instance Evaled Procs
49
34
 
@@ -54,11 +39,11 @@ evaluated in the context of an instance of Sequel::SQL::VirtualRow.
54
39
 
55
40
  ds = DB[:items]
56
41
  # Regular proc
57
- ds.filter{|o| o.column > 1}
42
+ ds.where{|o| o.column > 1}
58
43
  # WHERE column > 1
59
44
 
60
45
  # Instance-evaled proc
61
- ds.filter{column > 1}
46
+ ds.where{column > 1}
62
47
  # WHERE column > 1
63
48
 
64
49
  If you aren't familiar with the difference between regular blocks and instance
@@ -75,21 +60,21 @@ inside the proc. If that doesn't make sense, maybe this example will help:
75
60
  b = 32
76
61
 
77
62
  # Regular proc
78
- ds.filter{|o| o.c > a - b}
63
+ ds.where{|o| o.c > a - b}
79
64
  # WHERE c > 10
80
65
 
81
66
  # Instance-evaled proc
82
- ds.filter{c > a - b}
67
+ ds.where{c > a - b}
83
68
  # WHERE c > (a - 32)
84
69
 
85
- There are two related differences here. First is the usage of "o.c" vs "c",
86
- and second is the difference between the the use of "a". In the regular proc,
87
- you couldn't call c without an explicit receiver in the proc, unless the self of the
88
- surrounding scope responded to it. For a, note how ruby calls the method on
70
+ There are two related differences here. First is the usage of <tt>o.c</tt> vs +c+,
71
+ and second is the difference between the the use of +a+. In the regular proc,
72
+ you couldn't call +c+ without an explicit receiver in the proc, unless the self of the
73
+ surrounding scope responded to it. For +a+, note how ruby calls the method on
89
74
  the receiver of the surrounding scope in the regular proc, which returns an integer,
90
- and does the substitution before Sequel gets access to it. In the instance evaled
91
- proc, calling a without a receiver calls the a method on the VirtualRow instance.
92
- For b, note that it operates the same in both cases, as it is a local variable.
75
+ and does the subtraction before Sequel gets access to it. In the instance evaled
76
+ proc, calling +a+ without a receiver calls the a method on the VirtualRow instance.
77
+ For +b+, note that it operates the same in both cases, as it is a local variable.
93
78
 
94
79
  Basically, the choice for whether to use a regular proc or an instance evaled proc is
95
80
  completely up to you. The same things can be accomplished with both.
@@ -105,7 +90,7 @@ variable, you can call it with () to differentiate the method call from the
105
90
  local variable access. This is mostly useful in instance_evaled procs:
106
91
 
107
92
  b = 32
108
- ds.filter{b() > b}
93
+ ds.where{b() > b}
109
94
  # WHERE b > 32
110
95
 
111
96
  == VirtualRow Methods
@@ -120,8 +105,8 @@ not qualified by any table. You get an SQL::Identifier if the method is called
120
105
  without a block or arguments, and doesn't have a double underscore in the method
121
106
  name:
122
107
 
123
- ds.filter{|o| o.column > 1}
124
- ds.filter{column > 1}
108
+ ds.where{|o| o.column > 1}
109
+ ds.where{column > 1}
125
110
  # WHERE column > 1
126
111
 
127
112
  == SQL::QualifiedIdentifiers - Qualified columns
@@ -131,8 +116,8 @@ are qualified to a specific table. You get an SQL::QualifiedIdentifier if
131
116
  the method is called without a block or arguments, and has a double underscore
132
117
  in the method name:
133
118
 
134
- ds.filter{|o| o.table__column > 1}
135
- ds.filter{table__column > 1}
119
+ ds.where{|o| o.table__column > 1}
120
+ ds.where{table__column > 1}
136
121
  # WHERE table.column > 1
137
122
 
138
123
  Using the double underscore for SQL::QualifiedIdentifiers was done to make
@@ -144,15 +129,15 @@ into a qualified column.
144
129
  SQL::Functions can be thought of as function calls in SQL. You get a simple
145
130
  function call if you call a method with arguments and without a block:
146
131
 
147
- ds.filter{|o| o.function(1) > 1}
148
- ds.filter{function(1) > 1}
132
+ ds.where{|o| o.function(1) > 1}
133
+ ds.where{function(1) > 1}
149
134
  # WHERE function(1) > 1
150
135
 
151
136
  To call a SQL function with multiple arguments, just use those arguments in
152
137
  your function call:
153
138
 
154
- ds.filter{|o| o.function(1, o.a) > 1}
155
- ds.filter{function(1, a) > 1}
139
+ ds.where{|o| o.function(1, o.a) > 1}
140
+ ds.where{function(1, a) > 1}
156
141
  # WHERE function(1, a) > 1
157
142
 
158
143
  If the SQL function does not accept any arguments, you need to provide an empty
@@ -191,7 +176,8 @@ the method call:
191
176
  SQL::WindowFunctions can be thought of as calls to SQL window functions. Not
192
177
  all databases support them, but they are very helpful for certain types of
193
178
  queries. To use them, you need to make :over the first argument of the method
194
- call, with an optional hash as the second argument: Here are some examples of use:
179
+ call, with an optional hash as the second argument, and provide an empty block
180
+ to the method. Here are some examples of use:
195
181
 
196
182
  ds.select{|o| o.rank(:over){}}
197
183
  ds.select{rank(:over){}}
@@ -15,10 +15,7 @@ module Sequel
15
15
  # Add the primary_keys and primary_key_sequences instance variables,
16
16
  # so we can get the correct return values for inserted rows.
17
17
  def self.extended(db)
18
- db.instance_eval do
19
- @primary_keys = {}
20
- @primary_key_sequences = {}
21
- end
18
+ db.send(:initialize_postgres_adapter)
22
19
  end
23
20
 
24
21
  private
@@ -66,7 +66,7 @@ module Sequel
66
66
  end,
67
67
  :jtds=>proc do |db|
68
68
  Sequel.ts_require 'adapters/jdbc/jtds'
69
- db.extend(Sequel::JDBC::MSSQL::DatabaseMethods)
69
+ db.extend(Sequel::JDBC::JTDS::DatabaseMethods)
70
70
  db.dataset_class = Sequel::JDBC::JTDS::Dataset
71
71
  db.send(:set_mssql_unicode_strings)
72
72
  JDBC.load_gem('jtds')
@@ -431,7 +431,8 @@ module Sequel
431
431
  # Support fractional seconds for Time objects used in bound variables
432
432
  def java_sql_timestamp(time)
433
433
  ts = java.sql.Timestamp.new(time.to_i * 1000)
434
- ts.setNanos(RUBY_VERSION >= '1.9.0' ? time.nsec : time.usec * 1000)
434
+ # Work around jruby 1.6 ruby 1.9 mode bug
435
+ ts.setNanos((RUBY_VERSION >= '1.9.0' && time.nsec != 0) ? time.nsec : time.usec * 1000)
435
436
  ts
436
437
  end
437
438
 
@@ -477,7 +478,7 @@ module Sequel
477
478
  when TrueClass, FalseClass
478
479
  cps.setBoolean(i, arg)
479
480
  when NilClass
480
- cps.setString(i, nil)
481
+ set_ps_arg_nil(cps, i)
481
482
  when DateTime
482
483
  cps.setTimestamp(i, java_sql_datetime(arg))
483
484
  when Date
@@ -492,6 +493,11 @@ module Sequel
492
493
  cps.setObject(i, arg)
493
494
  end
494
495
  end
496
+
497
+ # Use setString with a nil value by default, but this doesn't work on all subadapters.
498
+ def set_ps_arg_nil(cps, i)
499
+ cps.setString(i, nil)
500
+ end
495
501
 
496
502
  # Return the connection. Used to do configuration on the
497
503
  # connection object before adding it to the connection pool.
@@ -636,6 +642,7 @@ module Sequel
636
642
  JAVA_BUFFERED_READER = Java::JavaIo::BufferedReader
637
643
  JAVA_BIG_DECIMAL = Java::JavaMath::BigDecimal
638
644
  JAVA_BYTE_ARRAY = Java::byte[]
645
+ JAVA_UUID = Java::JavaUtil::UUID
639
646
 
640
647
  # Handle type conversions for common Java types.
641
648
  class TYPE_TRANSLATOR
@@ -656,6 +663,7 @@ module Sequel
656
663
  end
657
664
  lines
658
665
  end
666
+ def uuid(v) v.to_string end
659
667
  end
660
668
  TYPE_TRANSLATOR_INSTANCE = tt = TYPE_TRANSLATOR.new
661
669
 
@@ -668,6 +676,7 @@ module Sequel
668
676
  BYTE_ARRAY_METHOD = tt.method(:byte_array)
669
677
  BLOB_METHOD = tt.method(:blob)
670
678
  CLOB_METHOD = tt.method(:clob)
679
+ UUID_METHOD = tt.method(:uuid)
671
680
 
672
681
  # Convert the given Java timestamp to an instance of Sequel.datetime_class.
673
682
  def convert_type_timestamp(v)
@@ -695,6 +704,8 @@ module Sequel
695
704
  BLOB_METHOD
696
705
  when JAVA_SQL_CLOB
697
706
  CLOB_METHOD
707
+ when JAVA_UUID
708
+ UUID_METHOD
698
709
  else
699
710
  false
700
711
  end
@@ -27,6 +27,15 @@ module Sequel
27
27
  end
28
28
 
29
29
  private
30
+
31
+ def set_ps_arg(cps, arg, i)
32
+ case arg
33
+ when Sequel::SQL::Blob
34
+ cps.setString(i, arg)
35
+ else
36
+ super
37
+ end
38
+ end
30
39
 
31
40
  def last_insert_id(conn, opts={})
32
41
  statement(conn) do |stmt|
@@ -114,6 +114,11 @@ module Sequel
114
114
  end
115
115
  end
116
116
 
117
+ # Handle nil values by using setNull with the correct parameter type.
118
+ def set_ps_arg_nil(cps, i)
119
+ cps.setNull(i, cps.getParameterMetaData.getParameterType(i))
120
+ end
121
+
117
122
  # Derby uses RENAME TABLE syntax to rename tables.
118
123
  def rename_table_sql(name, new_name)
119
124
  "RENAME TABLE #{quote_schema_table(name)} TO #{quote_schema_table(new_name)}"
@@ -124,6 +129,11 @@ module Sequel
124
129
  PRIMARY_KEY_INDEX_RE
125
130
  end
126
131
 
132
+ # Treat clob as string instead of blob
133
+ def schema_column_type(db_type)
134
+ db_type.downcase == 'clob' ? :string : super
135
+ end
136
+
127
137
  # If an :identity option is present in the column, add the necessary IDENTITY SQL.
128
138
  def type_literal(column)
129
139
  if column[:identity]
@@ -156,8 +166,10 @@ module Sequel
156
166
  ROWS = " ROWS".freeze
157
167
  FETCH_FIRST = " FETCH FIRST ".freeze
158
168
  ROWS_ONLY = " ROWS ONLY".freeze
159
- BOOL_TRUE = '(1 = 1)'.freeze
160
- BOOL_FALSE = '(1 = 0)'.freeze
169
+ BOOL_TRUE_OLD = '(1 = 1)'.freeze
170
+ BOOL_FALSE_OLD = '(1 = 0)'.freeze
171
+ BOOL_TRUE = 'TRUE'.freeze
172
+ BOOL_FALSE = 'FALSE'.freeze
161
173
  SELECT_CLAUSE_METHODS = clause_methods(:select, %w'select distinct columns from join where group having compounds order limit lock')
162
174
 
163
175
  # Derby doesn't support an expression between CASE and WHEN,
@@ -226,6 +238,23 @@ module Sequel
226
238
 
227
239
  private
228
240
 
241
+ JAVA_SQL_CLOB = Java::JavaSQL::Clob
242
+
243
+ class ::Sequel::JDBC::Dataset::TYPE_TRANSLATOR
244
+ def derby_clob(v) v.getSubString(1, v.length) end
245
+ end
246
+
247
+ DERBY_CLOB_METHOD = TYPE_TRANSLATOR_INSTANCE.method(:derby_clob)
248
+
249
+ # Handle clobs on Derby as strings.
250
+ def convert_type_proc(v)
251
+ if v.is_a?(JAVA_SQL_CLOB)
252
+ DERBY_CLOB_METHOD
253
+ else
254
+ super
255
+ end
256
+ end
257
+
229
258
  # Derby needs a hex string casted to BLOB for blobs.
230
259
  def literal_blob_append(sql, v)
231
260
  sql << BLOB_OPEN << v.unpack(HSTAR).first << BLOB_CLOSE
@@ -240,7 +269,11 @@ module Sequel
240
269
  # Derby uses an expression yielding false for false values.
241
270
  # Newer versions can use the FALSE literal, but the latest gem version cannot.
242
271
  def literal_false
243
- BOOL_FALSE
272
+ if db.svn_version >= 1040133
273
+ BOOL_FALSE
274
+ else
275
+ BOOL_FALSE_OLD
276
+ end
244
277
  end
245
278
 
246
279
  # Derby handles fractional seconds in timestamps, but not in times
@@ -251,7 +284,11 @@ module Sequel
251
284
  # Derby uses an expression yielding true for true values.
252
285
  # Newer versions can use the TRUE literal, but the latest gem version cannot.
253
286
  def literal_true
254
- BOOL_TRUE
287
+ if db.svn_version >= 1040133
288
+ BOOL_TRUE
289
+ else
290
+ BOOL_TRUE_OLD
291
+ end
255
292
  end
256
293
 
257
294
  # Derby doesn't support common table expressions.