sequel 4.28.0 → 4.29.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4342ce776d6f7e929b8ef1e9621f79f4544357b4
4
- data.tar.gz: 64ed417591b155d46f3ca0abdbe38f515ea9e15f
3
+ metadata.gz: f1baf17a3ed5aedeadf0002e4e68ac8e2e27bdc2
4
+ data.tar.gz: 9ceec8f5898df4025b6cf5239f461dee5595ebeb
5
5
  SHA512:
6
- metadata.gz: 2e672203108c7301da9abcaf7596368a1aa09b8302175bb6f49d9bc189993a84e7089343e16fcdb69b9409d3677746694b36e7cbb25d1c179779ab605cd63343
7
- data.tar.gz: 198aa8d381bd263e27bb03b646f0fa50d45225b5370084236d6da55eb1f6032396c6548f114c8ccf0d187091ab2a195c5d298e62e5a185bf992ce4fb06615d15
6
+ metadata.gz: a2c9116e35e8ff8a536530cff484f2d82fac1916db18d8d4b4666359c6ce1f6a67aeb855feb173128f874a179bc75ef10a22bd326ecf48ad6c3cfbe6f3f3b8d3
7
+ data.tar.gz: 07d8ee3fb38aeae9caa9344756826a7e43fa19bd5786948525b427e9d64c3714ee06d452299b310bb7d30666e16ee0af64f663de7bb9a3dbd3b2fd0f2c5255dd
data/CHANGELOG CHANGED
@@ -1,3 +1,23 @@
1
+ === 4.29.0 (2015-12-01)
2
+
3
+ * Add Model#json_serializer_opts method to json_serializer plugin, allowing for setting to_json defaults on per-instance basis (jeremyevans)
4
+
5
+ * Add uuid plugin for automatically setting UUID column when creating a model object (pdrakeweb, jeremyevans) (#1106)
6
+
7
+ * Allow the sqlanywhere adapter to work with sharding (jeremyevans)
8
+
9
+ * Support blobs as bound variables in the oracle adapter (jeremyevans) (#1104)
10
+
11
+ * Order by best results first when using the Database#full_text_search :rank option on PostgreSQL (chanks) (#1101)
12
+
13
+ * Run Database#table_exists? inside a savepoint if currently in a transaction and the database supports savepoints (jeremyevans) (#1100)
14
+
15
+ * Allow Database#transaction :retry_on option to work when using savepoints (jeremyevans)
16
+
17
+ * Allow for external adapters to implement Dataset#date_add_sql_append to integrate with the date_arithmetic extension (jeremyevans)
18
+
19
+ * Add Dataset#insert_empty_columns_values private method for easy overriding for databases that don't support INSERT with DEFAULT VALUES (jeremyevans)
20
+
1
21
  === 4.28.0 (2015-11-02)
2
22
 
3
23
  * Add boolean_subsets plugin, which adds a subset for each boolean column (jeremyevans)
@@ -44,7 +44,7 @@ If you have any comments or suggestions please post to the Google group.
44
44
 
45
45
  require 'sequel'
46
46
 
47
- DB = Sequel.sqlite # memory database
47
+ DB = Sequel.sqlite # memory database, requires sqlite3
48
48
 
49
49
  DB.create_table :items do
50
50
  primary_key :id
@@ -109,11 +109,11 @@ Or getting results as a hash via +to_hash+, with one column as key and another a
109
109
  To connect to a database you simply provide <tt>Sequel.connect</tt> with a URL:
110
110
 
111
111
  require 'sequel'
112
- DB = Sequel.connect('sqlite://blog.db')
112
+ DB = Sequel.connect('sqlite://blog.db') # requires sqlite3
113
113
 
114
114
  The connection URL can also include such stuff as the user name, password, and port:
115
115
 
116
- DB = Sequel.connect('postgres://user:password@host:port/database_name')
116
+ DB = Sequel.connect('postgres://user:password@host:port/database_name') # requires pg
117
117
 
118
118
  You can also specify optional parameters, such as the connection pool size, or loggers for logging SQL queries:
119
119
 
@@ -267,7 +267,7 @@ issues that you should be aware of when using Sequel.
267
267
 
268
268
  Counting records is easy using +count+:
269
269
 
270
- posts.where(:category.like('%ruby%')).count
270
+ posts.where(Sequel.like(:category, '%ruby%')).count
271
271
  # SELECT COUNT(*) FROM posts WHERE category LIKE '%ruby%'
272
272
 
273
273
  And you can also query maximum/minimum values via +max+ and +min+:
@@ -269,12 +269,8 @@ The following additional options are supported:
269
269
  === mysql2
270
270
 
271
271
  This is a newer MySQL adapter that does typecasting in C, so it is often faster than the
272
- mysql adapter. Supports the same additional options as the mysql adapter, except for :compress, and uses
273
- :timeout instead of :read_timeout and :connect_timeout.
274
-
275
- The following additional options are supported:
276
-
277
- :flags :: Override the flags to use for the connection (e.g. ::Mysql2::Client::MULTI_STATEMENTS)
272
+ mysql adapter. The options given are passed to Mysql2::Client.new, see the mysql2 documentation
273
+ for details on what options are supported.
278
274
 
279
275
  === odbc
280
276
 
@@ -0,0 +1,41 @@
1
+ = New Features
2
+
3
+ * A uuid plugin has now been added. This plugin will automatically
4
+ create a uuid for newly created model objects.
5
+
6
+ Model.plugin :uuid
7
+ Model.create.uuid => # some UUID
8
+
9
+ * Model#json_serializer_opts has been added to the json_serializer
10
+ plugin, allowing you to override the JSON serialization options
11
+ on a per instance basis without passing the options directly
12
+ to Model#to_json. This is useful if you are including the model
13
+ instance inside another datastructure that will be serialized
14
+ to JSON.
15
+
16
+ obj.json_serializer_opts(:root => true)
17
+ [obj].to_json
18
+ # => '[{"obj":{"id":1,"name":"Foo"}}]'
19
+
20
+ = Other Improvements
21
+
22
+ * The Database#transaction :retry_on option now works when using
23
+ savepoints.
24
+
25
+ * Calling Database#table_exists? inside a transaction will now use
26
+ a savepoint if the database supports it, so that if the table
27
+ doesn't exist, it will not affect the state of the transaction.
28
+
29
+ * Blobs can now be used as bound variables in the oracle adapter.
30
+
31
+ * The sqlanywhere adapter now works with database sharding.
32
+
33
+ * The Dataset#full_text_search :rank option has been fixed to order
34
+ by rank descending instead of ascending.
35
+
36
+ * External adapters that do not support INSERT with DEFAULT VALUES
37
+ can now override Dataset#insert_empty_columns_values to set
38
+ the columns and values to use for an empty INSERT.
39
+
40
+ * External adapters can now implement Dataset#date_add_sql_append
41
+ to integrate with the date_arithmetic extension.
@@ -122,7 +122,7 @@ module Sequel
122
122
  when BigDecimal
123
123
  arg = arg.to_f
124
124
  when ::Sequel::SQL::Blob
125
- raise Error, "Sequel's oracle adapter does not currently support using a blob in a bound variable"
125
+ arg = ::OCI8::BLOB.new(conn, arg)
126
126
  end
127
127
  if t = PS_TYPES[type]
128
128
  cursor.bind_param(i, arg, t)
@@ -1331,7 +1331,7 @@ module Sequel
1331
1331
  end
1332
1332
 
1333
1333
  if opts[:rank]
1334
- ds = ds.order{ts_rank_cd(cols, terms)}
1334
+ ds = ds.reverse{ts_rank_cd(cols, terms)}
1335
1335
  end
1336
1336
 
1337
1337
  ds
@@ -79,19 +79,19 @@ module Sequel
79
79
 
80
80
  # Returns number of rows affected
81
81
  def execute_dui(sql, opts=OPTS)
82
- synchronize do |conn|
82
+ synchronize(opts[:server]) do |conn|
83
83
  _execute(conn, :rows, sql, opts)
84
84
  end
85
85
  end
86
86
 
87
87
  def execute(sql, opts=OPTS, &block)
88
- synchronize do |conn|
88
+ synchronize(opts[:server]) do |conn|
89
89
  _execute(conn, :select, sql, opts, &block)
90
90
  end
91
91
  end
92
92
 
93
93
  def execute_insert(sql, opts=OPTS)
94
- synchronize do |conn|
94
+ synchronize(opts[:server]) do |conn|
95
95
  _execute(conn, :insert, sql, opts)
96
96
  end
97
97
  end
@@ -191,7 +191,12 @@ module Sequel
191
191
  def table_exists?(name)
192
192
  sch, table_name = schema_and_table(name)
193
193
  name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
194
- _table_exists?(from(name))
194
+ ds = from(name)
195
+ if in_transaction? && supports_savepoints?
196
+ transaction(:savepoint=>true){_table_exists?(ds)}
197
+ else
198
+ _table_exists?(ds)
199
+ end
195
200
  true
196
201
  rescue DatabaseError
197
202
  false
@@ -96,12 +96,12 @@ module Sequel
96
96
  else
97
97
  synchronize(opts[:server]) do |conn|
98
98
  if already_in_transaction?(conn, opts)
99
- if opts[:retrying]
100
- raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
101
- end
102
99
  if opts[:savepoint] != false && (stack = _trans(conn)[:savepoints]) && stack.last
103
100
  _transaction(conn, Hash[opts].merge!(:savepoint=>true), &block)
104
101
  else
102
+ if opts[:retrying]
103
+ raise Sequel::Error, "cannot set :retry_on options if you are already inside a transaction"
104
+ end
105
105
  return yield(conn)
106
106
  end
107
107
  else
@@ -46,12 +46,11 @@ module Sequel
46
46
  end
47
47
 
48
48
  if values.is_a?(Array) && values.empty? && !insert_supports_empty_values?
49
- columns = [columns().last]
50
- values = [DEFAULT]
49
+ columns, values = insert_empty_columns_values
51
50
  end
52
51
  clone(:columns=>columns, :values=>values).send(:_insert_sql)
53
52
  end
54
-
53
+
55
54
  # Append a literal representation of a value to the given SQL string.
56
55
  #
57
56
  # If an unsupported object is given, an +Error+ is raised.
@@ -1116,6 +1115,12 @@ module Sequel
1116
1115
  end
1117
1116
  end
1118
1117
 
1118
+ # The columns and values to use for an empty insert if the database doesn't support
1119
+ # INSERT with DEFAULT VALUES.
1120
+ def insert_empty_columns_values
1121
+ [[columns.last], [DEFAULT]]
1122
+ end
1123
+
1119
1124
  def insert_insert_sql(sql)
1120
1125
  sql << INSERT
1121
1126
  end
@@ -66,6 +66,9 @@ module Sequel
66
66
 
67
67
  # Append the SQL fragment for the DateAdd expression to the SQL query.
68
68
  def date_add_sql_append(sql, da)
69
+ if defined?(super)
70
+ return super
71
+ end
69
72
  h = da.interval
70
73
  expr = da.expr
71
74
  cast = case db_type = db.database_type
@@ -36,6 +36,12 @@ module Sequel
36
36
  # album.to_json(:root => true)
37
37
  # # => '{"album":{"id":1,"name":"RF","artist_id":2}}'
38
38
  #
39
+ # You can specify JSON serialization options to use later:
40
+ #
41
+ # album.json_serializer_opts(:root => true)
42
+ # [album].to_json
43
+ # # => '[{"album":{"id":1,"name":"RF","artist_id":2}}]'
44
+ #
39
45
  # Additionally, +to_json+ also exists as a class and dataset method, both
40
46
  # of which return all objects in the dataset:
41
47
  #
@@ -239,6 +245,20 @@ module Sequel
239
245
  self
240
246
  end
241
247
 
248
+ # Set the json serialization options that will be used by default
249
+ # in future calls to +to_json+. This is designed for cases where
250
+ # the model object will be used inside another data structure
251
+ # which to_json is called on, and as such will not allow passing
252
+ # of arguments to +to_json+.
253
+ #
254
+ # Example:
255
+ #
256
+ # obj.json_serializer_opts(:only=>:name)
257
+ # [obj].to_json # => '[{"name":"..."}]'
258
+ def json_serializer_opts(opts=OPTS)
259
+ @json_serializer_opts = Hash[@json_serializer_opts||OPTS].merge!(opts)
260
+ end
261
+
242
262
  # Return a string in JSON format. Accepts the following
243
263
  # options:
244
264
  #
@@ -257,12 +277,13 @@ module Sequel
257
277
  # string is given, use the string as the key, otherwise
258
278
  # use an underscored version of the model's name.
259
279
  def to_json(*a)
260
- if opts = a.first.is_a?(Hash)
261
- opts = model.json_serializer_opts.merge(a.first)
280
+ opts = model.json_serializer_opts
281
+ opts = Hash[opts].merge!(@json_serializer_opts) if @json_serializer_opts
282
+ if (arg_opts = a.first).is_a?(Hash)
283
+ opts = Hash[opts].merge!(arg_opts)
262
284
  a = []
263
- else
264
- opts = model.json_serializer_opts
265
285
  end
286
+
266
287
  vals = values
267
288
  cols = if only = opts[:only]
268
289
  Array(only)
@@ -0,0 +1,72 @@
1
+ require 'securerandom'
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The uuid plugin creates hooks that automatically create a uuid for every
6
+ # instance. Note that this uses SecureRandom.uuid to create UUIDs, and
7
+ # that method is not defined on ruby 1.8.7. If you would like to use this
8
+ # on ruby 1.8.7, you need to override the Model#create_uuid private method
9
+ # to return a valid uuid.
10
+ #
11
+ # Usage:
12
+ #
13
+ # # Uuid all model instances using +uuid+
14
+ # # (called before loading subclasses)
15
+ # Sequel::Model.plugin :uuid
16
+ #
17
+ # # Uuid Album instances, with custom column name
18
+ # Album.plugin :uuid, :field=>my_uuid
19
+ module Uuid
20
+ # Configure the plugin by setting the available options. Note that
21
+ # if this method is run more than once, previous settings are ignored,
22
+ # and it will just use the settings given or the default settings. Options:
23
+ # :field :: The field to hold the uuid (default: :uuid)
24
+ # :force :: Whether to overwrite an existing uuid (default: false)
25
+ def self.configure(model, opts=OPTS)
26
+ model.instance_eval do
27
+ @uuid_field = opts[:field]||:uuid
28
+ @uuid_overwrite = opts[:force]||false
29
+ end
30
+ end
31
+
32
+ module ClassMethods
33
+ # The field to store the uuid
34
+ attr_reader :uuid_field
35
+
36
+ # Whether to overwrite the create uuid if it already exists
37
+ def uuid_overwrite?
38
+ @uuid_overwrite
39
+ end
40
+
41
+ Plugins.inherited_instance_variables(self, :@uuid_field=>nil, :@uuid_overwrite=>nil)
42
+ end
43
+
44
+ module InstanceMethods
45
+ private
46
+
47
+ # Set the uuid when creating
48
+ def _before_validation
49
+ set_uuid if new?
50
+ super
51
+ end
52
+
53
+ # Create a new UUID. This method can be overridden to use a separate
54
+ # method for creating UUIDs. Note that this method does not work on
55
+ # ruby 1.8.7, you will have to override it if you are using ruby 1.8.7.
56
+ def create_uuid
57
+ SecureRandom.uuid
58
+ end
59
+
60
+ # If the object has accessor methods for the uuid field, and the uuid
61
+ # value is nil or overwriting it is allowed, set the uuid.
62
+ def set_uuid(uuid=create_uuid)
63
+ field = model.uuid_field
64
+ meth = :"#{field}="
65
+ if respond_to?(field) && respond_to?(meth) && (model.uuid_overwrite? || get_column_value(field).nil?)
66
+ set_column_value(meth, uuid)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -3,7 +3,7 @@ module Sequel
3
3
  MAJOR = 4
4
4
  # The minor version of Sequel. Bumped for every non-patch level
5
5
  # release, generally around once a month.
6
- MINOR = 28
6
+ MINOR = 29
7
7
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
8
8
  # releases that fix regressions from previous versions.
9
9
  TINY = 0
@@ -987,7 +987,7 @@ describe "A PostgreSQL database" do
987
987
  t2 = "ruby sequel " * 1000
988
988
  @db[:posts].insert(:title=>t1)
989
989
  @db[:posts].insert(:title=>t2)
990
- @db[:posts].full_text_search(:title, 'ruby & sequel', :rank=>true).select_map(:title).must_equal [t1, t2]
990
+ @db[:posts].full_text_search(:title, 'ruby & sequel', :rank=>true).select_map(:title).must_equal [t2, t1]
991
991
  end
992
992
 
993
993
  it "should support spatial indexes" do
@@ -614,6 +614,17 @@ describe "Database#table_exists?" do
614
614
  db.table_exists?(:b).must_equal true
615
615
  db.table_exists?(:c).must_equal true
616
616
  end
617
+
618
+ it "should use a savepoint if inside a transaction" do
619
+ db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
620
+ def db.supports_savepoints?; true end
621
+ db.transaction do
622
+ db.table_exists?(:a).must_equal false
623
+ end
624
+ db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "SELECT NULL AS nil FROM a LIMIT 1", "ROLLBACK TO SAVEPOINT autopoint_1", "COMMIT"]
625
+ db.table_exists?(:b).must_equal true
626
+ db.table_exists?(:c).must_equal true
627
+ end
617
628
  end
618
629
 
619
630
  DatabaseTransactionSpecs = shared_description do
@@ -964,6 +975,30 @@ describe "Database#transaction with savepoint support" do
964
975
 
965
976
  include DatabaseTransactionSpecs
966
977
 
978
+ it "should support :retry_on option for automatically retrying transactions when using :savepoint option" do
979
+ a = []
980
+ @db.transaction do
981
+ @db.transaction(:retry_on=>Sequel::SerializationFailure, :savepoint=>true) do
982
+ a << 1
983
+ raise Sequel::SerializationFailure if a.length == 1
984
+ end
985
+ end
986
+ @db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
987
+ a.must_equal [1, 1]
988
+ end
989
+
990
+ it "should support :retry_on option for automatically retrying transactions inside an :auto_savepoint transaction" do
991
+ a = []
992
+ @db.transaction(:auto_savepoint=>true) do
993
+ @db.transaction(:retry_on=>Sequel::SerializationFailure) do
994
+ a << 1
995
+ raise Sequel::SerializationFailure if a.length == 1
996
+ end
997
+ end
998
+ @db.sqls.must_equal ["BEGIN", "SAVEPOINT autopoint_1", "ROLLBACK TO SAVEPOINT autopoint_1", "SAVEPOINT autopoint_1", "RELEASE SAVEPOINT autopoint_1", "COMMIT"]
999
+ a.must_equal [1, 1]
1000
+ end
1001
+
967
1002
  it "should support after_commit inside savepoints" do
968
1003
  @db.transaction do
969
1004
  @db.after_commit{@db.execute('foo')}
@@ -65,6 +65,23 @@ describe "date_arithmetic extension" do
65
65
  end
66
66
  end
67
67
 
68
+ it "should use existing method" do
69
+ db = Sequel.mock
70
+ db.extend_datasets do
71
+ def date_add_sql_append(sql, da)
72
+ interval = ''
73
+ each_valid_interval_unit(da.interval, Sequel::SQL::DateAdd::DatasetMethods::DEF_DURATION_UNITS) do |value, sql_unit|
74
+ interval << "#{value} #{sql_unit} "
75
+ end
76
+ literal_append(sql, Sequel.function(:da, da.expr, interval))
77
+ end
78
+ end
79
+ db.extension :date_arithmetic
80
+ db.literal(Sequel.date_add(:a, @h0)).must_equal "da(a, '')"
81
+ db.literal(Sequel.date_add(:a, @h1)).must_equal "da(a, '1 days ')"
82
+ db.literal(Sequel.date_add(:a, @h2)).must_equal "da(a, '1 years 1 months 1 days 1 hours 1 minutes 1 seconds ')"
83
+ end
84
+
68
85
  it "should correctly literalize on Postgres" do
69
86
  db = dbf.call(:postgres)
70
87
  db.literal(Sequel.date_add(:a, @h0)).must_equal "CAST(a AS timestamp)"
@@ -43,6 +43,13 @@ describe "Sequel::Plugins::JsonSerializer" do
43
43
  Artist.from_json(Artist.load(:name=>Date.today).to_json).must_equal Artist.load(:name=>Date.today)
44
44
  end
45
45
 
46
+ it "should support setting json_serializer_opts on models" do
47
+ @artist.json_serializer_opts(:only=>:name)
48
+ Sequel.parse_json([@artist].to_json).must_equal [{'name'=>@artist.name}]
49
+ @artist.json_serializer_opts(:include=>{:albums=>{:only=>:name}})
50
+ Sequel.parse_json([@artist].to_json).must_equal [{'name'=>@artist.name, 'albums'=>[{'name'=>@album.name}]}]
51
+ end
52
+
46
53
  it "should handle the :only option" do
47
54
  Artist.from_json(@artist.to_json(:only=>:name)).must_equal Artist.load(:name=>@artist.name)
48
55
  Album.from_json(@album.to_json(:only=>[:id, :name])).must_equal Album.load(:id=>@album.id, :name=>@album.name)
@@ -0,0 +1,106 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "Sequel::Plugins::Uuid" do
4
+ before do
5
+ uuid = @uuid = '57308544-4e83-47b8-b87f-6f68b987f4f9'
6
+ @alt_uuid = 'd5d1ec46-5e8e-4a7b-adc9-50e76b819e19'
7
+ dc = Object.new
8
+ @c = Class.new(Sequel::Model(:t))
9
+ @c.class_eval do
10
+ columns :id, :uuid
11
+ plugin :uuid
12
+ def _save_refresh(*) end
13
+ define_method(:create_uuid) do
14
+ uuid
15
+ end
16
+ db.reset
17
+ end
18
+ @c.dataset.autoid = nil
19
+ end
20
+
21
+ it "should handle validations on the uuid field for new objects" do
22
+ @c.plugin :uuid, :force=>true
23
+ o = @c.new
24
+ def o.validate
25
+ errors.add(model.uuid_field, 'not present') unless send(model.uuid_field)
26
+ end
27
+ o.valid?.must_equal true
28
+ end
29
+
30
+ it "should set uuid field when skipping validations" do
31
+ @c.plugin :uuid
32
+ @c.new.save(:validate=>false)
33
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
34
+ end
35
+
36
+ it "should set the uuid field on creation" do
37
+ o = @c.create
38
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
39
+ o.uuid.must_equal @uuid
40
+ end
41
+
42
+ if RUBY_VERSION >= '1.9'
43
+ it "should allow specifying the uuid field via the :field option" do
44
+ c = Class.new(Sequel::Model(:t))
45
+ c.class_eval do
46
+ columns :id, :u
47
+ plugin :uuid, :field=>:u
48
+ def _save_refresh(*) end
49
+ end
50
+ o = c.create
51
+ c.db.sqls.first.must_match(/INSERT INTO t \(u\) VALUES \('[-0-9a-f]+'\)/)
52
+ o.u.must_match /[-0-9a-f]+/
53
+ end
54
+ end
55
+
56
+ it "should not raise an error if the model doesn't have the uuid column" do
57
+ @c.columns :id, :x
58
+ @c.send(:undef_method, :uuid)
59
+ @c.create(:x=>2)
60
+ @c.load(:id=>1, :x=>2).save
61
+ @c.db.sqls.must_equal ["INSERT INTO t (x) VALUES (2)", "UPDATE t SET x = 2 WHERE (id = 1)"]
62
+ end
63
+
64
+ it "should not overwrite an existing uuid value" do
65
+ o = @c.create(:uuid=>@alt_uuid)
66
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@alt_uuid}')"]
67
+ o.uuid.must_equal @alt_uuid
68
+ end
69
+
70
+ it "should overwrite an existing uuid if the :force option is used" do
71
+ @c.plugin :uuid, :force=>true
72
+ o = @c.create(:uuid=>@alt_uuid)
73
+ @c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
74
+ o.uuid.must_equal @uuid
75
+ end
76
+
77
+ it "should have uuid_field give the uuid field" do
78
+ @c.uuid_field.must_equal :uuid
79
+ @c.plugin :uuid, :field=>:u
80
+ @c.uuid_field.must_equal :u
81
+ end
82
+
83
+ it "should have uuid_overwrite? give the whether to overwrite an existing uuid" do
84
+ @c.uuid_overwrite?.must_equal false
85
+ @c.plugin :uuid, :force=>true
86
+ @c.uuid_overwrite?.must_equal true
87
+ end
88
+
89
+ it "should work with subclasses" do
90
+ c = Class.new(@c)
91
+ o = c.create
92
+ o.uuid.must_equal @uuid
93
+ c.db.sqls.must_equal ["INSERT INTO t (uuid) VALUES ('#{@uuid}')"]
94
+ c.create(:uuid=>@alt_uuid).uuid.must_equal @alt_uuid
95
+
96
+ c.class_eval do
97
+ columns :id, :u
98
+ plugin :uuid, :field=>:u, :force=>true
99
+ end
100
+ c2 = Class.new(c)
101
+ c2.db.reset
102
+ o = c2.create
103
+ o.u.must_equal @uuid
104
+ c2.db.sqls.first.must_match(/INSERT INTO t \([u]\) VALUES \('#{@uuid}'\)/)
105
+ end
106
+ end
@@ -355,13 +355,13 @@ describe "Bound Argument Types" do
355
355
  @ds.literal(@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>fract_time)[:t]).must_equal @ds.literal(fract_time)
356
356
  end
357
357
 
358
- cspecify "should handle blob type", [:odbc], [:oracle] do
358
+ cspecify "should handle blob type", [:odbc] do
359
359
  @ds.delete
360
360
  @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>@vs[:file])
361
361
  @ds.get(:file).must_equal @vs[:file]
362
362
  end
363
363
 
364
- cspecify "should handle blob type with special characters", [:odbc], [:oracle] do
364
+ cspecify "should handle blob type with special characters", [:odbc] do
365
365
  @ds.delete
366
366
  blob = Sequel.blob("\"'[]`a0 ")
367
367
  @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>blob)
@@ -374,7 +374,7 @@ describe "Bound Argument Types" do
374
374
  @ds.get(:file).must_equal nil
375
375
  end
376
376
 
377
- cspecify "should handle blob type with embedded zeros", [:odbc], [:oracle] do
377
+ cspecify "should handle blob type with embedded zeros", [:odbc] do
378
378
  zero_blob = Sequel::SQL::Blob.new("a\0"*100)
379
379
  @ds.delete
380
380
  @ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>zero_blob)
@@ -582,7 +582,7 @@ describe "Database schema modifiers" do
582
582
  @db.schema(:items, :reload=>true).map{|x| x.first}.must_equal [:id]
583
583
  @ds.columns!.must_equal [:id]
584
584
  @ds.insert(:id=>'20')
585
- @ds.all.must_equal [{:id=>"10"}, {:id=>"20"}]
585
+ @ds.order(:id).all.must_equal [{:id=>"10"}, {:id=>"20"}]
586
586
  end
587
587
 
588
588
  cspecify "should set column types without modifying NULL/NOT NULL", [:jdbc, :db2], [:db2], :oracle, :derby do
@@ -84,6 +84,28 @@ describe "Database transactions" do
84
84
  end
85
85
 
86
86
  if DB.supports_savepoints?
87
+ it "should handle table_exists? failures inside transactions" do
88
+ @db.transaction do
89
+ @d << {:name => '1'}
90
+ @db.table_exists?(:asadf098asd9asd98sa).must_equal false
91
+ @d << {:name => '2'}
92
+ end
93
+ @d.select_order_map(:name).must_equal %w'1 2'
94
+ end
95
+
96
+ it "should handle table_exists? failures inside savepoints" do
97
+ @db.transaction do
98
+ @d << {:name => '1'}
99
+ @db.transaction(:savepoint=>true) do
100
+ @d << {:name => '2'}
101
+ @db.table_exists?(:asadf098asd9asd98sa).must_equal false
102
+ @d << {:name => '3'}
103
+ end
104
+ @d << {:name => '4'}
105
+ end
106
+ @d.select_order_map(:name).must_equal %w'1 2 3 4'
107
+ end
108
+
87
109
  it "should support nested transactions through savepoints using the savepoint option" do
88
110
  @db.transaction do
89
111
  @d << {:name => '1'}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.28.0
4
+ version: 4.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-02 00:00:00.000000000 Z
11
+ date: 2015-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -229,6 +229,7 @@ extra_rdoc_files:
229
229
  - doc/release_notes/4.26.0.txt
230
230
  - doc/release_notes/4.27.0.txt
231
231
  - doc/release_notes/4.28.0.txt
232
+ - doc/release_notes/4.29.0.txt
232
233
  files:
233
234
  - CHANGELOG
234
235
  - MIT-LICENSE
@@ -345,6 +346,7 @@ files:
345
346
  - doc/release_notes/4.26.0.txt
346
347
  - doc/release_notes/4.27.0.txt
347
348
  - doc/release_notes/4.28.0.txt
349
+ - doc/release_notes/4.29.0.txt
348
350
  - doc/release_notes/4.3.0.txt
349
351
  - doc/release_notes/4.4.0.txt
350
352
  - doc/release_notes/4.5.0.txt
@@ -598,6 +600,7 @@ files:
598
600
  - lib/sequel/plugins/update_or_create.rb
599
601
  - lib/sequel/plugins/update_primary_key.rb
600
602
  - lib/sequel/plugins/update_refresh.rb
603
+ - lib/sequel/plugins/uuid.rb
601
604
  - lib/sequel/plugins/validate_associated.rb
602
605
  - lib/sequel/plugins/validation_class_methods.rb
603
606
  - lib/sequel/plugins/validation_helpers.rb
@@ -755,6 +758,7 @@ files:
755
758
  - spec/extensions/update_or_create_spec.rb
756
759
  - spec/extensions/update_primary_key_spec.rb
757
760
  - spec/extensions/update_refresh_spec.rb
761
+ - spec/extensions/uuid_spec.rb
758
762
  - spec/extensions/validate_associated_spec.rb
759
763
  - spec/extensions/validation_class_methods_spec.rb
760
764
  - spec/extensions/validation_helpers_spec.rb