sequel 3.30.0 → 3.31.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.
- data/CHANGELOG +40 -0
 - data/Rakefile +12 -2
 - data/doc/association_basics.rdoc +28 -0
 - data/doc/dataset_filtering.rdoc +8 -0
 - data/doc/opening_databases.rdoc +1 -0
 - data/doc/release_notes/3.31.0.txt +146 -0
 - data/lib/sequel/adapters/jdbc.rb +7 -6
 - data/lib/sequel/adapters/jdbc/derby.rb +5 -0
 - data/lib/sequel/adapters/jdbc/h2.rb +6 -1
 - data/lib/sequel/adapters/mock.rb +21 -2
 - data/lib/sequel/adapters/shared/db2.rb +10 -0
 - data/lib/sequel/adapters/shared/mssql.rb +40 -5
 - data/lib/sequel/adapters/shared/mysql.rb +19 -2
 - data/lib/sequel/adapters/shared/oracle.rb +13 -1
 - data/lib/sequel/adapters/shared/postgres.rb +52 -8
 - data/lib/sequel/adapters/shared/sqlite.rb +4 -3
 - data/lib/sequel/adapters/utils/stored_procedures.rb +1 -11
 - data/lib/sequel/database/schema_generator.rb +9 -2
 - data/lib/sequel/dataset/actions.rb +37 -19
 - data/lib/sequel/dataset/features.rb +10 -0
 - data/lib/sequel/dataset/prepared_statements.rb +0 -10
 - data/lib/sequel/dataset/query.rb +13 -1
 - data/lib/sequel/dataset/sql.rb +6 -1
 - data/lib/sequel/model/associations.rb +14 -4
 - data/lib/sequel/model/base.rb +10 -0
 - data/lib/sequel/plugins/serialization.rb +82 -43
 - data/lib/sequel/version.rb +1 -1
 - data/spec/adapters/mssql_spec.rb +46 -0
 - data/spec/adapters/mysql_spec.rb +3 -0
 - data/spec/adapters/postgres_spec.rb +61 -24
 - data/spec/core/database_spec.rb +31 -18
 - data/spec/core/dataset_spec.rb +90 -13
 - data/spec/core/mock_adapter_spec.rb +37 -0
 - data/spec/extensions/instance_filters_spec.rb +1 -0
 - data/spec/extensions/nested_attributes_spec.rb +1 -1
 - data/spec/extensions/serialization_spec.rb +49 -5
 - data/spec/extensions/sharding_spec.rb +1 -1
 - data/spec/integration/associations_test.rb +15 -0
 - data/spec/integration/dataset_test.rb +71 -0
 - data/spec/integration/prepared_statement_test.rb +8 -0
 - data/spec/model/association_reflection_spec.rb +27 -0
 - data/spec/model/associations_spec.rb +18 -3
 - data/spec/model/base_spec.rb +20 -0
 - data/spec/model/eager_loading_spec.rb +21 -0
 - metadata +4 -2
 
    
        data/lib/sequel/dataset/sql.rb
    CHANGED
    
    | 
         @@ -20,7 +20,7 @@ module Sequel 
     | 
|
| 
       20 
20 
     | 
    
         
             
                #   DB.select(1).where(DB[:items].exists)
         
     | 
| 
       21 
21 
     | 
    
         
             
                #   # SELECT 1 WHERE (EXISTS (SELECT * FROM items))
         
     | 
| 
       22 
22 
     | 
    
         
             
                def exists
         
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
      
 23 
     | 
    
         
            +
                  SQL::PlaceholderLiteralString.new("EXISTS ?", [self], true)
         
     | 
| 
       24 
24 
     | 
    
         
             
                end
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                # Returns an INSERT SQL query string.  See +insert+.
         
     | 
| 
         @@ -1196,7 +1196,12 @@ module Sequel 
     | 
|
| 
       1196 
1196 
     | 
    
         
             
                def select_group_sql(sql)
         
     | 
| 
       1197 
1197 
     | 
    
         
             
                  if group = @opts[:group]
         
     | 
| 
       1198 
1198 
     | 
    
         
             
                    sql << GROUP_BY
         
     | 
| 
      
 1199 
     | 
    
         
            +
                    if go = @opts[:group_options]
         
     | 
| 
      
 1200 
     | 
    
         
            +
                      sql << go.to_s.upcase
         
     | 
| 
      
 1201 
     | 
    
         
            +
                      sql << PAREN_OPEN
         
     | 
| 
      
 1202 
     | 
    
         
            +
                    end
         
     | 
| 
       1199 
1203 
     | 
    
         
             
                    expression_list_append(sql, group)
         
     | 
| 
      
 1204 
     | 
    
         
            +
                    sql << PAREN_CLOSE if go
         
     | 
| 
       1200 
1205 
     | 
    
         
             
                  end
         
     | 
| 
       1201 
1206 
     | 
    
         
             
                end
         
     | 
| 
       1202 
1207 
     | 
    
         | 
| 
         @@ -761,6 +761,10 @@ module Sequel 
     | 
|
| 
       761 
761 
     | 
    
         
             
                    # :key :: foreign key in current model's table that references
         
     | 
| 
       762 
762 
     | 
    
         
             
                    #         associated model's primary key, as a symbol.  Defaults to :"#{name}_id".  Can use an
         
     | 
| 
       763 
763 
     | 
    
         
             
                    #         array of symbols for a composite key association.
         
     | 
| 
      
 764 
     | 
    
         
            +
                    # :key_column :: Similar to, and usually identical to, :key, but :key refers to the model method
         
     | 
| 
      
 765 
     | 
    
         
            +
                    #                to call, where :key_column refers to the underlying column.  Should only be
         
     | 
| 
      
 766 
     | 
    
         
            +
                    #                used if the association has the same name as the foreign key column, in conjunction
         
     | 
| 
      
 767 
     | 
    
         
            +
                    #                with defining a model alias method for the key column.
         
     | 
| 
       764 
768 
     | 
    
         
             
                    # :primary_key :: column in the associated table that :key option references, as a symbol.
         
     | 
| 
       765 
769 
     | 
    
         
             
                    #                 Defaults to the primary key of the associated table. Can use an
         
     | 
| 
       766 
770 
     | 
    
         
             
                    #                 array of symbols for a composite key association.
         
     | 
| 
         @@ -1121,8 +1125,13 @@ module Sequel 
     | 
|
| 
       1121 
1125 
     | 
    
         
             
                      name = opts[:name]
         
     | 
| 
       1122 
1126 
     | 
    
         
             
                      model = self
         
     | 
| 
       1123 
1127 
     | 
    
         
             
                      opts[:key] = opts.default_key unless opts.include?(:key)
         
     | 
| 
       1124 
     | 
    
         
            -
                      key = opts[:key]
         
     | 
| 
       1125 
     | 
    
         
            -
                      cks = opts[:keys] = Array( 
     | 
| 
      
 1128 
     | 
    
         
            +
                      key_column = key = opts[:key]
         
     | 
| 
      
 1129 
     | 
    
         
            +
                      cks = opts[:graph_keys] = opts[:keys] = Array(key)
         
     | 
| 
      
 1130 
     | 
    
         
            +
                      if opts[:key_column]
         
     | 
| 
      
 1131 
     | 
    
         
            +
                        key_column = opts[:key_column]
         
     | 
| 
      
 1132 
     | 
    
         
            +
                        opts[:eager_loader_key] ||= key_column
         
     | 
| 
      
 1133 
     | 
    
         
            +
                        opts[:graph_keys] = Array(key_column)
         
     | 
| 
      
 1134 
     | 
    
         
            +
                      end
         
     | 
| 
       1126 
1135 
     | 
    
         
             
                      opts[:qualified_key] = opts.qualify_cur(key)
         
     | 
| 
       1127 
1136 
     | 
    
         
             
                      if opts[:primary_key]
         
     | 
| 
       1128 
1137 
     | 
    
         
             
                        cpks = Array(opts[:primary_key])
         
     | 
| 
         @@ -1136,7 +1145,7 @@ module Sequel 
     | 
|
| 
       1136 
1145 
     | 
    
         
             
                        klass.filter(Array(opts.qualified_primary_key).zip(cks.map{|k| send(k)}))
         
     | 
| 
       1137 
1146 
     | 
    
         
             
                      end
         
     | 
| 
       1138 
1147 
     | 
    
         
             
                      opts[:eager_loader] ||= proc do |eo|
         
     | 
| 
       1139 
     | 
    
         
            -
                        h = eo[:key_hash][ 
     | 
| 
      
 1148 
     | 
    
         
            +
                        h = eo[:key_hash][key_column]
         
     | 
| 
       1140 
1149 
     | 
    
         
             
                        keys = h.keys
         
     | 
| 
       1141 
1150 
     | 
    
         
             
                        # Default the cached association to nil, so any object that doesn't have it
         
     | 
| 
       1142 
1151 
     | 
    
         
             
                        # populated will have cached the negative lookup.
         
     | 
| 
         @@ -1158,9 +1167,10 @@ module Sequel 
     | 
|
| 
       1158 
1167 
     | 
    
         
             
                      only_conditions = opts[:graph_only_conditions]
         
     | 
| 
       1159 
1168 
     | 
    
         
             
                      conditions = opts[:graph_conditions]
         
     | 
| 
       1160 
1169 
     | 
    
         
             
                      graph_block = opts[:graph_block]
         
     | 
| 
      
 1170 
     | 
    
         
            +
                      graph_cks = opts[:graph_keys]
         
     | 
| 
       1161 
1171 
     | 
    
         
             
                      opts[:eager_grapher] ||= proc do |eo|
         
     | 
| 
       1162 
1172 
     | 
    
         
             
                        ds = eo[:self]
         
     | 
| 
       1163 
     | 
    
         
            -
                        ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : opts.primary_keys.zip( 
     | 
| 
      
 1173 
     | 
    
         
            +
                        ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : opts.primary_keys.zip(graph_cks) + conditions, eo.merge(:select=>select, :join_type=>join_type, :from_self_alias=>ds.opts[:eager_graph][:master]), &graph_block)
         
     | 
| 
       1164 
1174 
     | 
    
         
             
                      end
         
     | 
| 
       1165 
1175 
     | 
    
         | 
| 
       1166 
1176 
     | 
    
         
             
                      def_association_dataset_methods(opts)
         
     | 
    
        data/lib/sequel/model/base.rb
    CHANGED
    
    | 
         @@ -234,6 +234,16 @@ module Sequel 
     | 
|
| 
       234 
234 
     | 
    
         
             
                    @db_schema ||= get_db_schema
         
     | 
| 
       235 
235 
     | 
    
         
             
                  end
         
     | 
| 
       236 
236 
     | 
    
         | 
| 
      
 237 
     | 
    
         
            +
                  # Create a column alias, where the column methods have one name, but the underlying storage uses a
         
     | 
| 
      
 238 
     | 
    
         
            +
                  # different name.
         
     | 
| 
      
 239 
     | 
    
         
            +
                  def def_column_alias(meth, column)
         
     | 
| 
      
 240 
     | 
    
         
            +
                    clear_setter_methods_cache
         
     | 
| 
      
 241 
     | 
    
         
            +
                    overridable_methods_module.module_eval do
         
     | 
| 
      
 242 
     | 
    
         
            +
                      define_method(meth){self[column]}
         
     | 
| 
      
 243 
     | 
    
         
            +
                      define_method("#{meth}="){|v| self[column] = v}
         
     | 
| 
      
 244 
     | 
    
         
            +
                    end
         
     | 
| 
      
 245 
     | 
    
         
            +
                  end
         
     | 
| 
      
 246 
     | 
    
         
            +
              
         
     | 
| 
       237 
247 
     | 
    
         
             
                  # If a block is given, define a method on the dataset (if the model currently has an dataset)  with the given argument name using
         
     | 
| 
       238 
248 
     | 
    
         
             
                  # the given block.  Also define a class method on the model that calls the
         
     | 
| 
       239 
249 
     | 
    
         
             
                  # dataset method.  Stores the method name and block so that it can be reapplied if the model's
         
     | 
| 
         @@ -11,8 +11,17 @@ module Sequel 
     | 
|
| 
       11 
11 
     | 
    
         
             
                # set the @deserialized_values entry.  This plugin adds a before_save hook
         
     | 
| 
       12 
12 
     | 
    
         
             
                # that serializes all @deserialized_values to @values.
         
     | 
| 
       13 
13 
     | 
    
         
             
                #
         
     | 
| 
       14 
     | 
    
         
            -
                # You can  
     | 
| 
       15 
     | 
    
         
            -
                #  
     | 
| 
      
 14 
     | 
    
         
            +
                # You can specify the serialization format as a pair of serializer/deserializer
         
     | 
| 
      
 15 
     | 
    
         
            +
                # callable objects.  You can also specify the serialization format as a single
         
     | 
| 
      
 16 
     | 
    
         
            +
                # symbol, if such a symbol has a registered serializer/deserializer pair in the
         
     | 
| 
      
 17 
     | 
    
         
            +
                # plugin.  By default, the plugin registers the :marshal, :yaml, and :json
         
     | 
| 
      
 18 
     | 
    
         
            +
                # serialization formats.  To register your own serialization formats, use
         
     | 
| 
      
 19 
     | 
    
         
            +
                # Sequel::Plugins::Serialization.register_format.
         
     | 
| 
      
 20 
     | 
    
         
            +
                # If you use yaml or json format, you need to require the libraries, Sequel
         
     | 
| 
      
 21 
     | 
    
         
            +
                # does not do the requiring for you.
         
     | 
| 
      
 22 
     | 
    
         
            +
                #
         
     | 
| 
      
 23 
     | 
    
         
            +
                # You can specify the columns to serialize when loading the plugin, or later
         
     | 
| 
      
 24 
     | 
    
         
            +
                # using the serialize_attributes class method.
         
     | 
| 
       16 
25 
     | 
    
         
             
                #
         
     | 
| 
       17 
26 
     | 
    
         
             
                # Because of how this plugin works, it must be used inside each model class
         
     | 
| 
       18 
27 
     | 
    
         
             
                # that needs serialization, after any set_dataset method calls in that class.
         
     | 
| 
         @@ -22,56 +31,96 @@ module Sequel 
     | 
|
| 
       22 
31 
     | 
    
         
             
                # == Example
         
     | 
| 
       23 
32 
     | 
    
         
             
                #
         
     | 
| 
       24 
33 
     | 
    
         
             
                #   require 'sequel'
         
     | 
| 
      
 34 
     | 
    
         
            +
                #   # Require json, as the plugin doesn't require it for you.
         
     | 
| 
       25 
35 
     | 
    
         
             
                #   require 'json'
         
     | 
| 
      
 36 
     | 
    
         
            +
                #
         
     | 
| 
      
 37 
     | 
    
         
            +
                #   # Register custom serializer/deserializer pair
         
     | 
| 
      
 38 
     | 
    
         
            +
                #   Sequel::Plugins::Serialization.register_format(:reverse,
         
     | 
| 
      
 39 
     | 
    
         
            +
                #     lambda{|v| v.reverse},
         
     | 
| 
      
 40 
     | 
    
         
            +
                #     lambda{|v| v.reverse})
         
     | 
| 
      
 41 
     | 
    
         
            +
                #
         
     | 
| 
       26 
42 
     | 
    
         
             
                #   class User < Sequel::Model
         
     | 
| 
      
 43 
     | 
    
         
            +
                #     # Built-in format support when loading the plugin
         
     | 
| 
       27 
44 
     | 
    
         
             
                #     plugin :serialization, :json, :permissions
         
     | 
| 
       28 
     | 
    
         
            -
                # 
     | 
| 
      
 45 
     | 
    
         
            +
                #
         
     | 
| 
      
 46 
     | 
    
         
            +
                #     # Built-in format support after loading the plugin using serialize_attributes
         
     | 
| 
       29 
47 
     | 
    
         
             
                #     plugin :serialization
         
     | 
| 
       30 
     | 
    
         
            -
                #     serialize_attributes :marshal, :permissions 
     | 
| 
      
 48 
     | 
    
         
            +
                #     serialize_attributes :marshal, :permissions
         
     | 
| 
      
 49 
     | 
    
         
            +
                #
         
     | 
| 
      
 50 
     | 
    
         
            +
                #     # Use custom registered serialization format just like built-in format
         
     | 
| 
      
 51 
     | 
    
         
            +
                #     serialize_attributes :reverse, :password
         
     | 
| 
      
 52 
     | 
    
         
            +
                #
         
     | 
| 
      
 53 
     | 
    
         
            +
                #     # Use a custom serializer/deserializer pair without registering
         
     | 
| 
      
 54 
     | 
    
         
            +
                #     serialize_attributes [lambda{|v| v.reverse}, lambda{|v| v.reverse}], :password
         
     | 
| 
       31 
55 
     | 
    
         
             
                #   end
         
     | 
| 
       32 
56 
     | 
    
         
             
                #   user = User.create
         
     | 
| 
       33 
57 
     | 
    
         
             
                #   user.permissions = { :global => 'read-only' }
         
     | 
| 
       34 
58 
     | 
    
         
             
                #   user.save
         
     | 
| 
       35 
59 
     | 
    
         
             
                module Serialization
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # The default serializers supported by the serialization module.
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # Use register_format to add serializers to this hash.
         
     | 
| 
      
 62 
     | 
    
         
            +
                  REGISTERED_FORMATS = {}
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       36 
64 
     | 
    
         
             
                  # Set up the column readers to do deserialization and the column writers
         
     | 
| 
       37 
65 
     | 
    
         
             
                  # to save the value in deserialized_values.
         
     | 
| 
       38 
66 
     | 
    
         
             
                  def self.apply(model, *args)
         
     | 
| 
       39 
     | 
    
         
            -
                    model.instance_eval 
     | 
| 
      
 67 
     | 
    
         
            +
                    model.instance_eval do
         
     | 
| 
      
 68 
     | 
    
         
            +
                      @deserialization_map = {}
         
     | 
| 
      
 69 
     | 
    
         
            +
                      @serialization_map = {}
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
       40 
71 
     | 
    
         
             
                  end
         
     | 
| 
       41 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
                  # Automatically call serialize_attributes with the format and columns unless
         
     | 
| 
      
 74 
     | 
    
         
            +
                  # no columns were provided.
         
     | 
| 
       42 
75 
     | 
    
         
             
                  def self.configure(model, format=nil, *columns)
         
     | 
| 
       43 
76 
     | 
    
         
             
                    model.serialize_attributes(format, *columns) unless columns.empty?
         
     | 
| 
       44 
77 
     | 
    
         
             
                  end
         
     | 
| 
       45 
78 
     | 
    
         | 
| 
      
 79 
     | 
    
         
            +
                  # Register a serializer/deserializer pair with a format symbol, to allow
         
     | 
| 
      
 80 
     | 
    
         
            +
                  # models to pick this format by name.  Both serializer and deserializer
         
     | 
| 
      
 81 
     | 
    
         
            +
                  # should be callable objects.
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def self.register_format(format, serializer, deserializer)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    REGISTERED_FORMATS[format] = [serializer, deserializer]
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  register_format(:marshal, lambda{|v| [Marshal.dump(v)].pack('m')}, lambda{|v| Marshal.load(v.unpack('m')[0]) rescue Marshal.load(v)})
         
     | 
| 
      
 86 
     | 
    
         
            +
                  register_format(:yaml, lambda{|v| v.to_yaml}, lambda{|v| YAML.load(v)})
         
     | 
| 
      
 87 
     | 
    
         
            +
                  register_format(:json, lambda{|v| v.to_json}, lambda{|v| JSON.parse(v)})
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       46 
89 
     | 
    
         
             
                  module ClassMethods
         
     | 
| 
       47 
     | 
    
         
            -
                    # A  
     | 
| 
       48 
     | 
    
         
            -
                    #  
     | 
| 
      
 90 
     | 
    
         
            +
                    # A hash with column name symbols and callable values, with the value
         
     | 
| 
      
 91 
     | 
    
         
            +
                    # called to deserialize the column.
         
     | 
| 
      
 92 
     | 
    
         
            +
                    attr_reader :deserialization_map
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                    # A hash with column name symbols and callable values, with the value
         
     | 
| 
      
 95 
     | 
    
         
            +
                    # called to serialize the column.
         
     | 
| 
       49 
96 
     | 
    
         
             
                    attr_reader :serialization_map
         
     | 
| 
       50 
97 
     | 
    
         | 
| 
       51 
98 
     | 
    
         
             
                    # Module to store the serialized column accessor methods, so they can
         
     | 
| 
       52 
99 
     | 
    
         
             
                    # call be overridden and call super to get the serialization behavior
         
     | 
| 
       53 
100 
     | 
    
         
             
                    attr_accessor :serialization_module
         
     | 
| 
       54 
101 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
                    # Copy the  
     | 
| 
      
 102 
     | 
    
         
            +
                    # Copy the serialization_map and deserialization map into the subclass.
         
     | 
| 
       56 
103 
     | 
    
         
             
                    def inherited(subclass)
         
     | 
| 
       57 
104 
     | 
    
         
             
                      super
         
     | 
| 
       58 
105 
     | 
    
         
             
                      sm = serialization_map.dup
         
     | 
| 
       59 
     | 
    
         
            -
                       
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                    def serialization_format
         
     | 
| 
       65 
     | 
    
         
            -
                      serialization_map.values.first
         
     | 
| 
      
 106 
     | 
    
         
            +
                      dsm = deserialization_map.dup
         
     | 
| 
      
 107 
     | 
    
         
            +
                      subclass.instance_eval do
         
     | 
| 
      
 108 
     | 
    
         
            +
                        @deserialization_map = dsm
         
     | 
| 
      
 109 
     | 
    
         
            +
                        @serialization_map = sm
         
     | 
| 
      
 110 
     | 
    
         
            +
                      end
         
     | 
| 
       66 
111 
     | 
    
         
             
                    end
         
     | 
| 
       67 
112 
     | 
    
         | 
| 
       68 
113 
     | 
    
         
             
                    # Create instance level reader that deserializes column values on request,
         
     | 
| 
       69 
     | 
    
         
            -
                    # and instance level writer that stores new deserialized  
     | 
| 
       70 
     | 
    
         
            -
                    # columns
         
     | 
| 
      
 114 
     | 
    
         
            +
                    # and instance level writer that stores new deserialized values.
         
     | 
| 
       71 
115 
     | 
    
         
             
                    def serialize_attributes(format, *columns)
         
     | 
| 
       72 
     | 
    
         
            -
                       
     | 
| 
      
 116 
     | 
    
         
            +
                      if format.is_a?(Symbol)
         
     | 
| 
      
 117 
     | 
    
         
            +
                        unless format = REGISTERED_FORMATS[format]
         
     | 
| 
      
 118 
     | 
    
         
            +
                          raise(Error, "Unsupported serialization format: #{format} (valid formats: #{REGISTERED_FORMATS.keys.map{|k| k.inspect}.join})")
         
     | 
| 
      
 119 
     | 
    
         
            +
                        end
         
     | 
| 
      
 120 
     | 
    
         
            +
                      end
         
     | 
| 
      
 121 
     | 
    
         
            +
                      serializer, deserializer = format
         
     | 
| 
       73 
122 
     | 
    
         
             
                      raise(Error, "No columns given.  The serialization plugin requires you specify which columns to serialize") if columns.empty?
         
     | 
| 
       74 
     | 
    
         
            -
                      define_serialized_attribute_accessor( 
     | 
| 
      
 123 
     | 
    
         
            +
                      define_serialized_attribute_accessor(serializer, deserializer, *columns)
         
     | 
| 
       75 
124 
     | 
    
         
             
                    end
         
     | 
| 
       76 
125 
     | 
    
         | 
| 
       77 
126 
     | 
    
         
             
                    # The columns that will be serialized.  This is only for
         
     | 
| 
         @@ -83,12 +132,13 @@ module Sequel 
     | 
|
| 
       83 
132 
     | 
    
         
             
                    private
         
     | 
| 
       84 
133 
     | 
    
         | 
| 
       85 
134 
     | 
    
         
             
                    # Add serializated attribute acessor methods to the serialization_module
         
     | 
| 
       86 
     | 
    
         
            -
                    def define_serialized_attribute_accessor( 
     | 
| 
      
 135 
     | 
    
         
            +
                    def define_serialized_attribute_accessor(serializer, deserializer, *columns)
         
     | 
| 
       87 
136 
     | 
    
         
             
                      m = self
         
     | 
| 
       88 
137 
     | 
    
         
             
                      include(self.serialization_module ||= Module.new) unless serialization_module
         
     | 
| 
       89 
138 
     | 
    
         
             
                      serialization_module.class_eval do
         
     | 
| 
       90 
139 
     | 
    
         
             
                        columns.each do |column|
         
     | 
| 
       91 
     | 
    
         
            -
                          m.serialization_map[column] =  
     | 
| 
      
 140 
     | 
    
         
            +
                          m.serialization_map[column] = serializer
         
     | 
| 
      
 141 
     | 
    
         
            +
                          m.deserialization_map[column] = deserializer
         
     | 
| 
       92 
142 
     | 
    
         
             
                          define_method(column) do 
         
     | 
| 
       93 
143 
     | 
    
         
             
                            if deserialized_values.has_key?(column)
         
     | 
| 
       94 
144 
     | 
    
         
             
                              deserialized_values[column]
         
     | 
| 
         @@ -127,6 +177,7 @@ module Sequel 
     | 
|
| 
       127 
177 
     | 
    
         
             
                      super
         
     | 
| 
       128 
178 
     | 
    
         
             
                    end
         
     | 
| 
       129 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
                    # Initialization the deserialized values for objects retrieved from the database.
         
     | 
| 
       130 
181 
     | 
    
         
             
                    def set_values(*)
         
     | 
| 
       131 
182 
     | 
    
         
             
                      @deserialized_values ||= {}
         
     | 
| 
       132 
183 
     | 
    
         
             
                      super
         
     | 
| 
         @@ -134,33 +185,21 @@ module Sequel 
     | 
|
| 
       134 
185 
     | 
    
         | 
| 
       135 
186 
     | 
    
         
             
                    private
         
     | 
| 
       136 
187 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
                    # Deserialize the column  
     | 
| 
      
 188 
     | 
    
         
            +
                    # Deserialize the column value.  Called when the model column accessor is called to
         
     | 
| 
      
 189 
     | 
    
         
            +
                    # return a deserialized value.
         
     | 
| 
       138 
190 
     | 
    
         
             
                    def deserialize_value(column, v)
         
     | 
| 
       139 
     | 
    
         
            -
                       
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                        Marshal.load(v.unpack('m')[0]) rescue Marshal.load(v)
         
     | 
| 
       143 
     | 
    
         
            -
                      when :yaml
         
     | 
| 
       144 
     | 
    
         
            -
                        YAML.load v if v
         
     | 
| 
       145 
     | 
    
         
            -
                      when :json
         
     | 
| 
       146 
     | 
    
         
            -
                        JSON.parse v if v
         
     | 
| 
       147 
     | 
    
         
            -
                      else
         
     | 
| 
       148 
     | 
    
         
            -
                        raise Error, "Bad serialization format (#{model.serialization_map[column].inspect}) for column #{column.inspect}"
         
     | 
| 
      
 191 
     | 
    
         
            +
                      unless v.nil?
         
     | 
| 
      
 192 
     | 
    
         
            +
                        raise Sequel::Error, "no entry in deserialization_map for #{column.inspect}" unless callable = model.deserialization_map[column]
         
     | 
| 
      
 193 
     | 
    
         
            +
                        callable.call(v)
         
     | 
| 
       149 
194 
     | 
    
         
             
                      end
         
     | 
| 
       150 
195 
     | 
    
         
             
                    end
         
     | 
| 
       151 
196 
     | 
    
         | 
| 
       152 
     | 
    
         
            -
                    # Serialize the column to  
     | 
| 
      
 197 
     | 
    
         
            +
                    # Serialize the column value.  Called before saving to ensure the serialized value
         
     | 
| 
      
 198 
     | 
    
         
            +
                    # is saved in the database.
         
     | 
| 
       153 
199 
     | 
    
         
             
                    def serialize_value(column, v)
         
     | 
| 
       154 
     | 
    
         
            -
                       
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
       157 
     | 
    
         
            -
                        [Marshal.dump(v)].pack('m')
         
     | 
| 
       158 
     | 
    
         
            -
                      when :yaml
         
     | 
| 
       159 
     | 
    
         
            -
                        v.to_yaml
         
     | 
| 
       160 
     | 
    
         
            -
                      when :json
         
     | 
| 
       161 
     | 
    
         
            -
                        v.to_json
         
     | 
| 
       162 
     | 
    
         
            -
                      else
         
     | 
| 
       163 
     | 
    
         
            -
                        raise Error, "Bad serialization format (#{model.serialization_map[column].inspect}) for column #{column.inspect}"
         
     | 
| 
      
 200 
     | 
    
         
            +
                      unless v.nil?
         
     | 
| 
      
 201 
     | 
    
         
            +
                        raise Sequel::Error, "no entry in serialization_map for #{column.inspect}" unless callable = model.serialization_map[column]
         
     | 
| 
      
 202 
     | 
    
         
            +
                        callable.call(v)
         
     | 
| 
       164 
203 
     | 
    
         
             
                      end
         
     | 
| 
       165 
204 
     | 
    
         
             
                    end
         
     | 
| 
       166 
205 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/sequel/version.rb
    CHANGED
    
    | 
         @@ -3,7 +3,7 @@ module Sequel 
     | 
|
| 
       3 
3 
     | 
    
         
             
              MAJOR = 3
         
     | 
| 
       4 
4 
     | 
    
         
             
              # The minor version of Sequel.  Bumped for every non-patch level
         
     | 
| 
       5 
5 
     | 
    
         
             
              # release, generally around once a month.
         
     | 
| 
       6 
     | 
    
         
            -
              MINOR =  
     | 
| 
      
 6 
     | 
    
         
            +
              MINOR = 31
         
     | 
| 
       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
         
     | 
    
        data/spec/adapters/mssql_spec.rb
    CHANGED
    
    | 
         @@ -60,6 +60,35 @@ describe "A MSSQL database" do 
     | 
|
| 
       60 
60 
     | 
    
         
             
              end
         
     | 
| 
       61 
61 
     | 
    
         
             
            end
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
            # This spec is currently disabled as the SQL Server 2008 R2 Express doesn't support
         
     | 
| 
      
 64 
     | 
    
         
            +
            # full text searching.  Even if full text searching is supported,
         
     | 
| 
      
 65 
     | 
    
         
            +
            # you may need to create a full text catalog on the database first via:
         
     | 
| 
      
 66 
     | 
    
         
            +
            #   CREATE FULLTEXT CATALOG ftscd AS DEFAULT
         
     | 
| 
      
 67 
     | 
    
         
            +
            describe "MSSQL full_text_search" do
         
     | 
| 
      
 68 
     | 
    
         
            +
              before do
         
     | 
| 
      
 69 
     | 
    
         
            +
                @db = MSSQL_DB
         
     | 
| 
      
 70 
     | 
    
         
            +
                @db.drop_table(:posts) rescue nil
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
              after do
         
     | 
| 
      
 73 
     | 
    
         
            +
                @db.drop_table(:posts) rescue nil
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
              
         
     | 
| 
      
 76 
     | 
    
         
            +
              specify "should support fulltext indexes and full_text_search" do
         
     | 
| 
      
 77 
     | 
    
         
            +
                log do
         
     | 
| 
      
 78 
     | 
    
         
            +
                @db.create_table(:posts){Integer :id, :null=>false; String :title; String :body; index :id, :name=>:fts_id_idx, :unique=>true; full_text_index :title, :key_index=>:fts_id_idx; full_text_index [:title, :body], :key_index=>:fts_id_idx}
         
     | 
| 
      
 79 
     | 
    
         
            +
                @db[:posts].insert(:title=>'ruby rails', :body=>'y')
         
     | 
| 
      
 80 
     | 
    
         
            +
                @db[:posts].insert(:title=>'sequel', :body=>'ruby')
         
     | 
| 
      
 81 
     | 
    
         
            +
                @db[:posts].insert(:title=>'ruby scooby', :body=>'x')
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, 'rails').all.should == [{:title=>'ruby rails', :body=>'y'}]
         
     | 
| 
      
 84 
     | 
    
         
            +
                @db[:posts].full_text_search([:title, :body], ['sequel', 'ruby']).all.should == [{:title=>'sequel', :body=>'ruby'}]
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
         
     | 
| 
      
 87 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end if false
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
       63 
92 
     | 
    
         
             
            describe "MSSQL Dataset#join_table" do
         
     | 
| 
       64 
93 
     | 
    
         
             
              specify "should emulate the USING clause with ON" do
         
     | 
| 
       65 
94 
     | 
    
         
             
                MSSQL_DB[:items].join(:categories, [:id]).sql.should ==
         
     | 
| 
         @@ -219,6 +248,23 @@ describe "MSSQL dataset" do 
     | 
|
| 
       219 
248 
     | 
    
         
             
              end
         
     | 
| 
       220 
249 
     | 
    
         
             
            end
         
     | 
| 
       221 
250 
     | 
    
         | 
| 
      
 251 
     | 
    
         
            +
            describe "MSSQL::Dataset#import" do
         
     | 
| 
      
 252 
     | 
    
         
            +
              before do
         
     | 
| 
      
 253 
     | 
    
         
            +
                @db = MSSQL_DB
         
     | 
| 
      
 254 
     | 
    
         
            +
                @db.create_table!(:test){primary_key :x; Integer :y}
         
     | 
| 
      
 255 
     | 
    
         
            +
                @db.sqls.clear
         
     | 
| 
      
 256 
     | 
    
         
            +
                @ds = @db[:test]
         
     | 
| 
      
 257 
     | 
    
         
            +
              end
         
     | 
| 
      
 258 
     | 
    
         
            +
              after do
         
     | 
| 
      
 259 
     | 
    
         
            +
                @db.drop_table(:test) rescue nil
         
     | 
| 
      
 260 
     | 
    
         
            +
              end
         
     | 
| 
      
 261 
     | 
    
         
            +
              
         
     | 
| 
      
 262 
     | 
    
         
            +
              specify "#import should work correctly with an arbitrary output value" do
         
     | 
| 
      
 263 
     | 
    
         
            +
                @ds.output(nil, [:inserted__y, :inserted__x]).import([:y], [[3], [4]]).should == [{:y=>3, :x=>1}, {:y=>4, :x=>2}]
         
     | 
| 
      
 264 
     | 
    
         
            +
                @ds.all.should == [{:x=>1, :y=>3}, {:x=>2, :y=>4}]
         
     | 
| 
      
 265 
     | 
    
         
            +
              end
         
     | 
| 
      
 266 
     | 
    
         
            +
            end
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
       222 
268 
     | 
    
         
             
            describe "MSSQL joined datasets" do
         
     | 
| 
       223 
269 
     | 
    
         
             
              before do
         
     | 
| 
       224 
270 
     | 
    
         
             
                @db = MSSQL_DB
         
     | 
    
        data/spec/adapters/mysql_spec.rb
    CHANGED
    
    | 
         @@ -645,6 +645,9 @@ describe "A MySQL database" do 
     | 
|
| 
       645 
645 
     | 
    
         
             
                  "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('rails'))",
         
     | 
| 
       646 
646 
     | 
    
         
             
                  "SELECT * FROM `posts` WHERE (MATCH (`title`, `body`) AGAINST ('sequel ruby'))",
         
     | 
| 
       647 
647 
     | 
    
         
             
                  "SELECT * FROM `posts` WHERE (MATCH (`title`) AGAINST ('+ruby -rails' IN BOOLEAN MODE))"]
         
     | 
| 
      
 648 
     | 
    
         
            +
             
     | 
| 
      
 649 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
         
     | 
| 
      
 650 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'y'}]
         
     | 
| 
       648 
651 
     | 
    
         
             
              end
         
     | 
| 
       649 
652 
     | 
    
         | 
| 
       650 
653 
     | 
    
         
             
              specify "should support spatial indexes" do
         
     | 
| 
         @@ -380,6 +380,9 @@ describe "A PostgreSQL database" do 
     | 
|
| 
       380 
380 
     | 
    
         
             
                  %{SELECT * FROM "posts" WHERE (to_tsvector('simple', (COALESCE("title", ''))) @@ to_tsquery('simple', 'rails'))},
         
     | 
| 
       381 
381 
     | 
    
         
             
                  %{SELECT * FROM "posts" WHERE (to_tsvector('simple', (COALESCE("title", '') || ' ' || COALESCE("body", ''))) @@ to_tsquery('simple', 'yowsa | rails'))},
         
     | 
| 
       382 
382 
     | 
    
         
             
                  %{SELECT * FROM "posts" WHERE (to_tsvector('french', (COALESCE("title", ''))) @@ to_tsquery('french', 'scooby'))}]
         
     | 
| 
      
 383 
     | 
    
         
            +
             
     | 
| 
      
 384 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, :$n).call(:select, :n=>'rails').should == [{:title=>'ruby rails', :body=>'yowsa'}]
         
     | 
| 
      
 385 
     | 
    
         
            +
                @db[:posts].full_text_search(:title, :$n).prepare(:select, :fts_select).call(:n=>'rails').should == [{:title=>'ruby rails', :body=>'yowsa'}]
         
     | 
| 
       383 
386 
     | 
    
         
             
              end
         
     | 
| 
       384 
387 
     | 
    
         | 
| 
       385 
388 
     | 
    
         
             
              specify "should support spatial indexes" do
         
     | 
| 
         @@ -431,7 +434,7 @@ end 
     | 
|
| 
       431 
434 
     | 
    
         
             
            describe "Postgres::Dataset#import" do
         
     | 
| 
       432 
435 
     | 
    
         
             
              before do
         
     | 
| 
       433 
436 
     | 
    
         
             
                @db = POSTGRES_DB
         
     | 
| 
       434 
     | 
    
         
            -
                @db.create_table!(:test){ 
     | 
| 
      
 437 
     | 
    
         
            +
                @db.create_table!(:test){primary_key :x; Integer :y}
         
     | 
| 
       435 
438 
     | 
    
         
             
                @db.sqls.clear
         
     | 
| 
       436 
439 
     | 
    
         
             
                @ds = @db[:test]
         
     | 
| 
       437 
440 
     | 
    
         
             
              end
         
     | 
| 
         @@ -441,28 +444,45 @@ describe "Postgres::Dataset#import" do 
     | 
|
| 
       441 
444 
     | 
    
         | 
| 
       442 
445 
     | 
    
         
             
              specify "#import should return separate insert statements if server_version < 80200" do
         
     | 
| 
       443 
446 
     | 
    
         
             
                @ds.meta_def(:server_version){80199}
         
     | 
| 
       444 
     | 
    
         
            -
                
         
     | 
| 
       445 
447 
     | 
    
         
             
                @ds.import([:x, :y], [[1, 2], [3, 4]])
         
     | 
| 
       446 
     | 
    
         
            -
                
         
     | 
| 
       447 
     | 
    
         
            -
                @db.sqls.should == [
         
     | 
| 
       448 
     | 
    
         
            -
                  'BEGIN',
         
     | 
| 
       449 
     | 
    
         
            -
                  'INSERT INTO "test" ("x", "y") VALUES (1, 2)',
         
     | 
| 
       450 
     | 
    
         
            -
                  'INSERT INTO "test" ("x", "y") VALUES (3, 4)',
         
     | 
| 
       451 
     | 
    
         
            -
                  'COMMIT'
         
     | 
| 
       452 
     | 
    
         
            -
                ]
         
     | 
| 
      
 448 
     | 
    
         
            +
                @db.sqls.should == ['BEGIN', 'INSERT INTO "test" ("x", "y") VALUES (1, 2)', 'INSERT INTO "test" ("x", "y") VALUES (3, 4)', 'COMMIT']
         
     | 
| 
       453 
449 
     | 
    
         
             
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
       454 
450 
     | 
    
         
             
              end
         
     | 
| 
       455 
451 
     | 
    
         | 
| 
       456 
452 
     | 
    
         
             
              specify "#import should a single insert statement if server_version >= 80200" do
         
     | 
| 
       457 
453 
     | 
    
         
             
                @ds.meta_def(:server_version){80200}
         
     | 
| 
       458 
     | 
    
         
            -
                
         
     | 
| 
       459 
454 
     | 
    
         
             
                @ds.import([:x, :y], [[1, 2], [3, 4]])
         
     | 
| 
       460 
     | 
    
         
            -
                
         
     | 
| 
       461 
     | 
    
         
            -
                @ 
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
             
     | 
| 
       464 
     | 
    
         
            -
             
     | 
| 
       465 
     | 
    
         
            -
                 
     | 
| 
      
 455 
     | 
    
         
            +
                @db.sqls.should == ['BEGIN', 'INSERT INTO "test" ("x", "y") VALUES (1, 2), (3, 4)', 'COMMIT']
         
     | 
| 
      
 456 
     | 
    
         
            +
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
      
 457 
     | 
    
         
            +
              end
         
     | 
| 
      
 458 
     | 
    
         
            +
              
         
     | 
| 
      
 459 
     | 
    
         
            +
              specify "#import should work correctly when returning primary keys for server_version < 80200" do
         
     | 
| 
      
 460 
     | 
    
         
            +
                @ds.meta_def(:server_version){80199}
         
     | 
| 
      
 461 
     | 
    
         
            +
                @ds.import([:x, :y], [[1, 2], [3, 4]], :return=>:primary_key).should == [1, 3]
         
     | 
| 
      
 462 
     | 
    
         
            +
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
      
 463 
     | 
    
         
            +
              end
         
     | 
| 
      
 464 
     | 
    
         
            +
              
         
     | 
| 
      
 465 
     | 
    
         
            +
              specify "#import should work correctly when returning primary keys for server_version >= 80200" do
         
     | 
| 
      
 466 
     | 
    
         
            +
                @ds.meta_def(:server_version){80200}
         
     | 
| 
      
 467 
     | 
    
         
            +
                @ds.import([:x, :y], [[1, 2], [3, 4]], :return=>:primary_key).should == [1, 3]
         
     | 
| 
      
 468 
     | 
    
         
            +
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
      
 469 
     | 
    
         
            +
              end
         
     | 
| 
      
 470 
     | 
    
         
            +
              
         
     | 
| 
      
 471 
     | 
    
         
            +
              specify "#import should work correctly when returning primary keys with :slice option for server_version < 80200" do
         
     | 
| 
      
 472 
     | 
    
         
            +
                @ds.meta_def(:server_version){80199}
         
     | 
| 
      
 473 
     | 
    
         
            +
                @ds.import([:x, :y], [[1, 2], [3, 4]], :return=>:primary_key, :slice=>1).should == [1, 3]
         
     | 
| 
      
 474 
     | 
    
         
            +
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
      
 475 
     | 
    
         
            +
              end
         
     | 
| 
      
 476 
     | 
    
         
            +
              
         
     | 
| 
      
 477 
     | 
    
         
            +
              specify "#import should work correctly when returning primary keys with :slice option for server_version >= 80200" do
         
     | 
| 
      
 478 
     | 
    
         
            +
                @ds.meta_def(:server_version){80200}
         
     | 
| 
      
 479 
     | 
    
         
            +
                @ds.import([:x, :y], [[1, 2], [3, 4]], :return=>:primary_key, :slice=>1).should == [1, 3]
         
     | 
| 
      
 480 
     | 
    
         
            +
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
      
 481 
     | 
    
         
            +
              end
         
     | 
| 
      
 482 
     | 
    
         
            +
              
         
     | 
| 
      
 483 
     | 
    
         
            +
              specify "#import should work correctly with an arbitrary returning value" do
         
     | 
| 
      
 484 
     | 
    
         
            +
                @ds.meta_def(:server_version){80200}
         
     | 
| 
      
 485 
     | 
    
         
            +
                @ds.returning(:y, :x).import([:x, :y], [[1, 2], [3, 4]]).should == [{:y=>2, :x=>1}, {:y=>4, :x=>3}]
         
     | 
| 
       466 
486 
     | 
    
         
             
                @ds.all.should == [{:x=>1, :y=>2}, {:x=>3, :y=>4}]
         
     | 
| 
       467 
487 
     | 
    
         
             
              end
         
     | 
| 
       468 
488 
     | 
    
         
             
            end
         
     | 
| 
         @@ -500,21 +520,26 @@ describe "Postgres::Dataset#insert" do 
     | 
|
| 
       500 
520 
     | 
    
         
             
                @ds.all.should == [{:xid=>1, :value=>10}, {:xid=>2, :value=>20}, {:xid=>3, :value=>13}]
         
     | 
| 
       501 
521 
     | 
    
         
             
              end
         
     | 
| 
       502 
522 
     | 
    
         | 
| 
       503 
     | 
    
         
            -
              specify "should  
     | 
| 
      
 523 
     | 
    
         
            +
              specify "should insert correctly if server_version < 80200" do
         
     | 
| 
       504 
524 
     | 
    
         
             
                @ds.meta_def(:server_version){80100}
         
     | 
| 
       505 
     | 
    
         
            -
                @ds. 
     | 
| 
       506 
     | 
    
         
            -
                @ds. 
     | 
| 
      
 525 
     | 
    
         
            +
                @ds.insert(:value=>10).should == 1
         
     | 
| 
      
 526 
     | 
    
         
            +
                @ds.all.should == [{:xid=>1, :value=>10}]
         
     | 
| 
       507 
527 
     | 
    
         
             
              end
         
     | 
| 
       508 
528 
     | 
    
         | 
| 
       509 
     | 
    
         
            -
              specify "should  
     | 
| 
       510 
     | 
    
         
            -
                @ds.disable_insert_returning 
     | 
| 
       511 
     | 
    
         
            -
                @ds. 
     | 
| 
       512 
     | 
    
         
            -
             
     | 
| 
      
 529 
     | 
    
         
            +
              specify "should insert correctly if disabling insert returning" do
         
     | 
| 
      
 530 
     | 
    
         
            +
                @ds.disable_insert_returning.insert(:value=>10).should == 1
         
     | 
| 
      
 531 
     | 
    
         
            +
                @ds.all.should == [{:xid=>1, :value=>10}]
         
     | 
| 
      
 532 
     | 
    
         
            +
              end
         
     | 
| 
      
 533 
     | 
    
         
            +
             
     | 
| 
      
 534 
     | 
    
         
            +
              specify "should insert correctly if using a column array and a value array and server_version < 80200" do
         
     | 
| 
      
 535 
     | 
    
         
            +
                @ds.meta_def(:server_version){80100}
         
     | 
| 
      
 536 
     | 
    
         
            +
                @ds.insert([:value], [10]).should == 1
         
     | 
| 
      
 537 
     | 
    
         
            +
                @ds.all.should == [{:xid=>1, :value=>10}]
         
     | 
| 
       513 
538 
     | 
    
         
             
              end
         
     | 
| 
       514 
539 
     | 
    
         | 
| 
       515 
540 
     | 
    
         
             
              specify "should use INSERT RETURNING if server_version >= 80200" do
         
     | 
| 
       516 
541 
     | 
    
         
             
                @ds.meta_def(:server_version){80201}
         
     | 
| 
       517 
     | 
    
         
            -
                @ds.insert(:value=>10)
         
     | 
| 
      
 542 
     | 
    
         
            +
                @ds.insert(:value=>10).should == 1
         
     | 
| 
       518 
543 
     | 
    
         
             
                @db.sqls.last.should == 'INSERT INTO "test5" ("value") VALUES (10) RETURNING "xid"'
         
     | 
| 
       519 
544 
     | 
    
         
             
              end
         
     | 
| 
       520 
545 
     | 
    
         | 
| 
         @@ -605,6 +630,18 @@ describe "Postgres::Database schema qualified tables" do 
     | 
|
| 
       605 
630 
     | 
    
         
             
                POSTGRES_DB.drop_table(:domains)
         
     | 
| 
       606 
631 
     | 
    
         
             
              end
         
     | 
| 
       607 
632 
     | 
    
         | 
| 
      
 633 
     | 
    
         
            +
              specify "#schema should raise an exception if columns from tables in two separate schema are returned" do
         
     | 
| 
      
 634 
     | 
    
         
            +
                POSTGRES_DB.create_table!(:public__domains){integer :d}
         
     | 
| 
      
 635 
     | 
    
         
            +
                POSTGRES_DB.create_table(:schema_test__domains){integer :i}
         
     | 
| 
      
 636 
     | 
    
         
            +
                begin
         
     | 
| 
      
 637 
     | 
    
         
            +
                  proc{POSTGRES_DB.schema(:domains)}.should raise_error(Sequel::Error)
         
     | 
| 
      
 638 
     | 
    
         
            +
                  POSTGRES_DB.schema(:public__domains).map{|x| x.first}.should == [:d]
         
     | 
| 
      
 639 
     | 
    
         
            +
                  POSTGRES_DB.schema(:schema_test__domains).map{|x| x.first}.should == [:i]
         
     | 
| 
      
 640 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 641 
     | 
    
         
            +
                  POSTGRES_DB.drop_table(:public__domains)
         
     | 
| 
      
 642 
     | 
    
         
            +
                end
         
     | 
| 
      
 643 
     | 
    
         
            +
              end
         
     | 
| 
      
 644 
     | 
    
         
            +
              
         
     | 
| 
       608 
645 
     | 
    
         
             
              specify "#table_exists? should see if the table is in a given schema" do
         
     | 
| 
       609 
646 
     | 
    
         
             
                POSTGRES_DB.create_table(:schema_test__schema_test){integer :i}
         
     | 
| 
       610 
647 
     | 
    
         
             
                POSTGRES_DB.table_exists?(:schema_test__schema_test).should == true
         
     |