sequel 5.45.0 → 5.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG +434 -0
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +59 -27
 - data/bin/sequel +11 -3
 - data/doc/advanced_associations.rdoc +16 -14
 - data/doc/association_basics.rdoc +119 -24
 - data/doc/cheat_sheet.rdoc +11 -3
 - data/doc/mass_assignment.rdoc +1 -1
 - data/doc/migration.rdoc +27 -6
 - data/doc/model_hooks.rdoc +1 -1
 - data/doc/object_model.rdoc +8 -8
 - data/doc/opening_databases.rdoc +28 -12
 - data/doc/postgresql.rdoc +16 -8
 - data/doc/querying.rdoc +5 -3
 - data/doc/release_notes/5.46.0.txt +87 -0
 - data/doc/release_notes/5.47.0.txt +59 -0
 - data/doc/release_notes/5.48.0.txt +14 -0
 - data/doc/release_notes/5.49.0.txt +59 -0
 - data/doc/release_notes/5.50.0.txt +78 -0
 - data/doc/release_notes/5.51.0.txt +47 -0
 - data/doc/release_notes/5.52.0.txt +87 -0
 - data/doc/release_notes/5.53.0.txt +23 -0
 - data/doc/release_notes/5.54.0.txt +27 -0
 - data/doc/release_notes/5.55.0.txt +21 -0
 - data/doc/release_notes/5.56.0.txt +51 -0
 - data/doc/release_notes/5.57.0.txt +23 -0
 - data/doc/release_notes/5.58.0.txt +31 -0
 - data/doc/release_notes/5.59.0.txt +73 -0
 - data/doc/release_notes/5.60.0.txt +22 -0
 - data/doc/release_notes/5.61.0.txt +43 -0
 - data/doc/release_notes/5.62.0.txt +132 -0
 - data/doc/release_notes/5.63.0.txt +33 -0
 - data/doc/release_notes/5.64.0.txt +50 -0
 - data/doc/release_notes/5.65.0.txt +21 -0
 - data/doc/release_notes/5.66.0.txt +24 -0
 - data/doc/release_notes/5.67.0.txt +32 -0
 - data/doc/release_notes/5.68.0.txt +61 -0
 - data/doc/release_notes/5.69.0.txt +26 -0
 - data/doc/release_notes/5.70.0.txt +35 -0
 - data/doc/release_notes/5.71.0.txt +21 -0
 - data/doc/release_notes/5.72.0.txt +33 -0
 - data/doc/release_notes/5.73.0.txt +66 -0
 - data/doc/release_notes/5.74.0.txt +45 -0
 - data/doc/release_notes/5.75.0.txt +35 -0
 - data/doc/release_notes/5.76.0.txt +86 -0
 - data/doc/release_notes/5.77.0.txt +63 -0
 - data/doc/schema_modification.rdoc +1 -1
 - data/doc/security.rdoc +9 -9
 - data/doc/sharding.rdoc +3 -1
 - data/doc/sql.rdoc +27 -15
 - data/doc/testing.rdoc +23 -13
 - data/doc/transactions.rdoc +6 -6
 - data/doc/virtual_rows.rdoc +1 -1
 - data/lib/sequel/adapters/ado/access.rb +1 -1
 - data/lib/sequel/adapters/ado.rb +1 -1
 - data/lib/sequel/adapters/amalgalite.rb +3 -5
 - data/lib/sequel/adapters/ibmdb.rb +3 -3
 - data/lib/sequel/adapters/jdbc/derby.rb +8 -0
 - data/lib/sequel/adapters/jdbc/h2.rb +63 -10
 - data/lib/sequel/adapters/jdbc/hsqldb.rb +8 -0
 - data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
 - data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
 - data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
 - data/lib/sequel/adapters/jdbc.rb +24 -22
 - data/lib/sequel/adapters/mysql.rb +92 -67
 - data/lib/sequel/adapters/mysql2.rb +56 -51
 - data/lib/sequel/adapters/odbc/mssql.rb +1 -1
 - data/lib/sequel/adapters/odbc.rb +1 -1
 - data/lib/sequel/adapters/oracle.rb +4 -3
 - data/lib/sequel/adapters/postgres.rb +89 -45
 - data/lib/sequel/adapters/shared/access.rb +11 -1
 - data/lib/sequel/adapters/shared/db2.rb +42 -0
 - data/lib/sequel/adapters/shared/mssql.rb +91 -10
 - data/lib/sequel/adapters/shared/mysql.rb +78 -3
 - data/lib/sequel/adapters/shared/oracle.rb +86 -7
 - data/lib/sequel/adapters/shared/postgres.rb +576 -171
 - data/lib/sequel/adapters/shared/sqlanywhere.rb +21 -5
 - data/lib/sequel/adapters/shared/sqlite.rb +92 -8
 - data/lib/sequel/adapters/sqlanywhere.rb +1 -1
 - data/lib/sequel/adapters/sqlite.rb +99 -18
 - data/lib/sequel/adapters/tinytds.rb +1 -1
 - data/lib/sequel/adapters/trilogy.rb +117 -0
 - data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
 - data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
 - data/lib/sequel/ast_transformer.rb +6 -0
 - data/lib/sequel/connection_pool/sharded_single.rb +5 -7
 - data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
 - data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
 - data/lib/sequel/connection_pool/single.rb +6 -8
 - data/lib/sequel/connection_pool/threaded.rb +14 -8
 - data/lib/sequel/connection_pool/timed_queue.rb +270 -0
 - data/lib/sequel/connection_pool.rb +57 -31
 - data/lib/sequel/core.rb +17 -18
 - data/lib/sequel/database/connecting.rb +27 -3
 - data/lib/sequel/database/dataset.rb +16 -6
 - data/lib/sequel/database/misc.rb +70 -14
 - data/lib/sequel/database/query.rb +73 -2
 - data/lib/sequel/database/schema_generator.rb +11 -6
 - data/lib/sequel/database/schema_methods.rb +23 -4
 - data/lib/sequel/database/transactions.rb +6 -0
 - data/lib/sequel/dataset/actions.rb +111 -15
 - data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
 - data/lib/sequel/dataset/features.rb +20 -1
 - data/lib/sequel/dataset/misc.rb +12 -2
 - data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
 - data/lib/sequel/dataset/query.rb +170 -41
 - data/lib/sequel/dataset/sql.rb +190 -71
 - data/lib/sequel/dataset.rb +4 -0
 - data/lib/sequel/extensions/_model_pg_row.rb +0 -12
 - data/lib/sequel/extensions/_pretty_table.rb +1 -1
 - data/lib/sequel/extensions/any_not_empty.rb +2 -2
 - data/lib/sequel/extensions/async_thread_pool.rb +14 -13
 - data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
 - data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
 - data/lib/sequel/extensions/connection_expiration.rb +15 -9
 - data/lib/sequel/extensions/connection_validator.rb +16 -11
 - data/lib/sequel/extensions/constraint_validations.rb +1 -1
 - data/lib/sequel/extensions/core_refinements.rb +36 -11
 - data/lib/sequel/extensions/date_arithmetic.rb +36 -8
 - data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
 - data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
 - data/lib/sequel/extensions/duplicate_columns_handler.rb +11 -10
 - data/lib/sequel/extensions/index_caching.rb +5 -1
 - data/lib/sequel/extensions/inflector.rb +1 -1
 - data/lib/sequel/extensions/is_distinct_from.rb +141 -0
 - data/lib/sequel/extensions/looser_typecasting.rb +3 -0
 - data/lib/sequel/extensions/migration.rb +57 -15
 - data/lib/sequel/extensions/named_timezones.rb +22 -6
 - data/lib/sequel/extensions/pagination.rb +1 -1
 - data/lib/sequel/extensions/pg_array.rb +33 -4
 - data/lib/sequel/extensions/pg_array_ops.rb +2 -2
 - data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
 - data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
 - data/lib/sequel/extensions/pg_enum.rb +1 -2
 - data/lib/sequel/extensions/pg_extended_date_support.rb +39 -28
 - data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
 - data/lib/sequel/extensions/pg_hstore.rb +6 -1
 - data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
 - data/lib/sequel/extensions/pg_inet.rb +10 -11
 - data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
 - data/lib/sequel/extensions/pg_interval.rb +11 -11
 - data/lib/sequel/extensions/pg_json.rb +13 -15
 - data/lib/sequel/extensions/pg_json_ops.rb +125 -2
 - data/lib/sequel/extensions/pg_multirange.rb +367 -0
 - data/lib/sequel/extensions/pg_range.rb +13 -26
 - data/lib/sequel/extensions/pg_range_ops.rb +37 -9
 - data/lib/sequel/extensions/pg_row.rb +20 -19
 - data/lib/sequel/extensions/pg_row_ops.rb +1 -1
 - data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
 - data/lib/sequel/extensions/round_timestamps.rb +1 -1
 - data/lib/sequel/extensions/s.rb +2 -1
 - data/lib/sequel/extensions/schema_caching.rb +1 -1
 - data/lib/sequel/extensions/schema_dumper.rb +45 -11
 - data/lib/sequel/extensions/server_block.rb +10 -13
 - data/lib/sequel/extensions/set_literalizer.rb +58 -0
 - data/lib/sequel/extensions/sql_comments.rb +110 -3
 - data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
 - data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
 - data/lib/sequel/extensions/string_agg.rb +1 -1
 - data/lib/sequel/extensions/string_date_time.rb +19 -23
 - data/lib/sequel/extensions/symbol_aref.rb +2 -0
 - data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
 - data/lib/sequel/model/associations.rb +286 -92
 - data/lib/sequel/model/base.rb +53 -33
 - data/lib/sequel/model/dataset_module.rb +3 -0
 - data/lib/sequel/model/errors.rb +10 -1
 - data/lib/sequel/model/exceptions.rb +15 -3
 - data/lib/sequel/model/inflections.rb +1 -1
 - data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
 - data/lib/sequel/plugins/auto_validations.rb +74 -16
 - data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
 - data/lib/sequel/plugins/column_encryption.rb +29 -8
 - data/lib/sequel/plugins/composition.rb +3 -2
 - data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
 - data/lib/sequel/plugins/constraint_validations.rb +8 -5
 - data/lib/sequel/plugins/defaults_setter.rb +16 -0
 - data/lib/sequel/plugins/dirty.rb +1 -1
 - data/lib/sequel/plugins/enum.rb +124 -0
 - data/lib/sequel/plugins/finder.rb +4 -2
 - data/lib/sequel/plugins/insert_conflict.rb +4 -0
 - data/lib/sequel/plugins/instance_specific_default.rb +1 -1
 - data/lib/sequel/plugins/json_serializer.rb +2 -2
 - data/lib/sequel/plugins/lazy_attributes.rb +3 -0
 - data/lib/sequel/plugins/list.rb +8 -3
 - data/lib/sequel/plugins/many_through_many.rb +109 -10
 - data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
 - data/lib/sequel/plugins/nested_attributes.rb +4 -4
 - data/lib/sequel/plugins/optimistic_locking.rb +9 -42
 - data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
 - data/lib/sequel/plugins/paged_operations.rb +181 -0
 - data/lib/sequel/plugins/pg_array_associations.rb +46 -34
 - data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
 - data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
 - data/lib/sequel/plugins/prepared_statements.rb +12 -2
 - data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
 - data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
 - data/lib/sequel/plugins/rcte_tree.rb +7 -4
 - data/lib/sequel/plugins/require_valid_schema.rb +67 -0
 - data/lib/sequel/plugins/serialization.rb +1 -0
 - data/lib/sequel/plugins/serialization_modification_detection.rb +1 -0
 - data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
 - data/lib/sequel/plugins/sql_comments.rb +189 -0
 - data/lib/sequel/plugins/static_cache.rb +39 -1
 - data/lib/sequel/plugins/static_cache_cache.rb +5 -1
 - data/lib/sequel/plugins/subclasses.rb +28 -11
 - data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
 - data/lib/sequel/plugins/timestamps.rb +1 -1
 - data/lib/sequel/plugins/unused_associations.rb +521 -0
 - data/lib/sequel/plugins/update_or_create.rb +1 -1
 - data/lib/sequel/plugins/validate_associated.rb +22 -12
 - data/lib/sequel/plugins/validation_helpers.rb +41 -11
 - data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
 - data/lib/sequel/plugins/xml_serializer.rb +1 -1
 - data/lib/sequel/sql.rb +1 -1
 - data/lib/sequel/timezones.rb +12 -14
 - data/lib/sequel/version.rb +1 -1
 - metadata +109 -19
 
    
        data/lib/sequel/dataset/sql.rb
    CHANGED
    
    | 
         @@ -24,29 +24,7 @@ module Sequel 
     | 
|
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
                  check_insert_allowed!
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                  columns =  
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                  case values.size
         
     | 
| 
       30 
     | 
    
         
            -
                  when 0
         
     | 
| 
       31 
     | 
    
         
            -
                    return insert_sql(OPTS)
         
     | 
| 
       32 
     | 
    
         
            -
                  when 1
         
     | 
| 
       33 
     | 
    
         
            -
                    case vals = values[0]
         
     | 
| 
       34 
     | 
    
         
            -
                    when Hash
         
     | 
| 
       35 
     | 
    
         
            -
                      values = []
         
     | 
| 
       36 
     | 
    
         
            -
                      vals.each do |k,v| 
         
     | 
| 
       37 
     | 
    
         
            -
                        columns << k
         
     | 
| 
       38 
     | 
    
         
            -
                        values << v
         
     | 
| 
       39 
     | 
    
         
            -
                      end
         
     | 
| 
       40 
     | 
    
         
            -
                    when Dataset, Array, LiteralString
         
     | 
| 
       41 
     | 
    
         
            -
                      values = vals
         
     | 
| 
       42 
     | 
    
         
            -
                    end
         
     | 
| 
       43 
     | 
    
         
            -
                  when 2
         
     | 
| 
       44 
     | 
    
         
            -
                    if (v0 = values[0]).is_a?(Array) && ((v1 = values[1]).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
         
     | 
| 
       45 
     | 
    
         
            -
                      columns, values = v0, v1
         
     | 
| 
       46 
     | 
    
         
            -
                      raise(Error, "Different number of values and columns given to insert_sql") if values.is_a?(Array) and columns.length != values.length
         
     | 
| 
       47 
     | 
    
         
            -
                    end
         
     | 
| 
       48 
     | 
    
         
            -
                  end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
                  columns, values = _parse_insert_sql_args(values)
         
     | 
| 
       50 
28 
     | 
    
         
             
                  if values.is_a?(Array) && values.empty? && !insert_supports_empty_values? 
         
     | 
| 
       51 
29 
     | 
    
         
             
                    columns, values = insert_empty_columns_values
         
     | 
| 
       52 
30 
     | 
    
         
             
                  elsif values.is_a?(Dataset) && hoist_cte?(values) && supports_cte?(:insert)
         
     | 
| 
         @@ -104,7 +82,7 @@ module Sequel 
     | 
|
| 
       104 
82 
     | 
    
         
             
                  when DateTime
         
     | 
| 
       105 
83 
     | 
    
         
             
                    literal_datetime_append(sql, v)
         
     | 
| 
       106 
84 
     | 
    
         
             
                  when Date
         
     | 
| 
       107 
     | 
    
         
            -
                    sql  
     | 
| 
      
 85 
     | 
    
         
            +
                    literal_date_append(sql, v)
         
     | 
| 
       108 
86 
     | 
    
         
             
                  when Dataset
         
     | 
| 
       109 
87 
     | 
    
         
             
                    literal_dataset_append(sql, v)
         
     | 
| 
       110 
88 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -112,6 +90,58 @@ module Sequel 
     | 
|
| 
       112 
90 
     | 
    
         
             
                  end
         
     | 
| 
       113 
91 
     | 
    
         
             
                end
         
     | 
| 
       114 
92 
     | 
    
         | 
| 
      
 93 
     | 
    
         
            +
                # The SQL to use for the MERGE statement.
         
     | 
| 
      
 94 
     | 
    
         
            +
                def merge_sql
         
     | 
| 
      
 95 
     | 
    
         
            +
                  raise Error, "This database doesn't support MERGE" unless supports_merge?
         
     | 
| 
      
 96 
     | 
    
         
            +
                  if sql = opts[:sql]
         
     | 
| 
      
 97 
     | 
    
         
            +
                    return static_sql(sql)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  if sql = cache_get(:_merge_sql)
         
     | 
| 
      
 100 
     | 
    
         
            +
                    return sql
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  source, join_condition = @opts[:merge_using]
         
     | 
| 
      
 103 
     | 
    
         
            +
                  raise Error, "No USING clause for MERGE" unless source
         
     | 
| 
      
 104 
     | 
    
         
            +
                  sql = @opts[:append_sql] || sql_string_origin
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                  select_with_sql(sql)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  sql << "MERGE INTO "
         
     | 
| 
      
 108 
     | 
    
         
            +
                  source_list_append(sql, @opts[:from])
         
     | 
| 
      
 109 
     | 
    
         
            +
                  sql << " USING "
         
     | 
| 
      
 110 
     | 
    
         
            +
                  identifier_append(sql, source)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  sql << " ON "
         
     | 
| 
      
 112 
     | 
    
         
            +
                  literal_append(sql, join_condition)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  _merge_when_sql(sql)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  cache_set(:_merge_sql, sql) if cache_sql?
         
     | 
| 
      
 115 
     | 
    
         
            +
                  sql
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                # Literalize a date or time value, as a SQL string value with no
         
     | 
| 
      
 119 
     | 
    
         
            +
                # typecasting. If +raw+ is true, remove the surrounding single
         
     | 
| 
      
 120 
     | 
    
         
            +
                # quotes.  This is designed for usage by bound argument code that
         
     | 
| 
      
 121 
     | 
    
         
            +
                # can work even if the auto_cast_date_and_time extension is
         
     | 
| 
      
 122 
     | 
    
         
            +
                # used (either manually or implicitly in the related adapter).
         
     | 
| 
      
 123 
     | 
    
         
            +
                def literal_date_or_time(dt, raw=false)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  value = case dt
         
     | 
| 
      
 125 
     | 
    
         
            +
                  when SQLTime
         
     | 
| 
      
 126 
     | 
    
         
            +
                    literal_sqltime(dt)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  when Time
         
     | 
| 
      
 128 
     | 
    
         
            +
                    literal_time(dt)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  when DateTime
         
     | 
| 
      
 130 
     | 
    
         
            +
                    literal_datetime(dt)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  when Date
         
     | 
| 
      
 132 
     | 
    
         
            +
                    literal_date(dt)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  else
         
     | 
| 
      
 134 
     | 
    
         
            +
                    raise TypeError, "unsupported type: #{dt.inspect}"
         
     | 
| 
      
 135 
     | 
    
         
            +
                  end
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
                  if raw
         
     | 
| 
      
 138 
     | 
    
         
            +
                    value.sub!(/\A'/, '')
         
     | 
| 
      
 139 
     | 
    
         
            +
                    value.sub!(/'\z/, '')
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                  value
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
       115 
145 
     | 
    
         
             
                # Returns an array of insert statements for inserting multiple records.
         
     | 
| 
       116 
146 
     | 
    
         
             
                # This method is used by +multi_insert+ to format insert statements and
         
     | 
| 
       117 
147 
     | 
    
         
             
                # expects a keys array and and an array of value arrays.
         
     | 
| 
         @@ -559,11 +589,9 @@ module Sequel 
     | 
|
| 
       559 
589 
     | 
    
         
             
                # Append literalization of JOIN USING clause to SQL string.
         
     | 
| 
       560 
590 
     | 
    
         
             
                def join_using_clause_sql_append(sql, jc)
         
     | 
| 
       561 
591 
     | 
    
         
             
                  join_clause_sql_append(sql, jc)
         
     | 
| 
       562 
     | 
    
         
            -
                  sql  
     | 
| 
       563 
     | 
    
         
            -
                  column_list_append(sql, jc.using)
         
     | 
| 
       564 
     | 
    
         
            -
                  sql << ')'
         
     | 
| 
      
 592 
     | 
    
         
            +
                  join_using_clause_using_sql_append(sql, jc.using) 
         
     | 
| 
       565 
593 
     | 
    
         
             
                end
         
     | 
| 
       566 
     | 
    
         
            -
             
     | 
| 
      
 594 
     | 
    
         
            +
             
     | 
| 
       567 
595 
     | 
    
         
             
                # Append literalization of negative boolean constant to SQL string.
         
     | 
| 
       568 
596 
     | 
    
         
             
                def negative_boolean_constant_sql_append(sql, constant)
         
     | 
| 
       569 
597 
     | 
    
         
             
                  sql << 'NOT '
         
     | 
| 
         @@ -852,6 +880,83 @@ module Sequel 
     | 
|
| 
       852 
880 
     | 
    
         | 
| 
       853 
881 
     | 
    
         
             
                private
         
     | 
| 
       854 
882 
     | 
    
         | 
| 
      
 883 
     | 
    
         
            +
                # Append the INSERT sql used in a MERGE
         
     | 
| 
      
 884 
     | 
    
         
            +
                def _merge_insert_sql(sql, data)
         
     | 
| 
      
 885 
     | 
    
         
            +
                  sql << " THEN INSERT"
         
     | 
| 
      
 886 
     | 
    
         
            +
                  columns, values = _parse_insert_sql_args(data[:values])
         
     | 
| 
      
 887 
     | 
    
         
            +
                  _insert_columns_sql(sql, columns)
         
     | 
| 
      
 888 
     | 
    
         
            +
                  _insert_values_sql(sql, values)
         
     | 
| 
      
 889 
     | 
    
         
            +
                end
         
     | 
| 
      
 890 
     | 
    
         
            +
             
     | 
| 
      
 891 
     | 
    
         
            +
                def _merge_update_sql(sql, data)
         
     | 
| 
      
 892 
     | 
    
         
            +
                  sql << " THEN UPDATE SET "
         
     | 
| 
      
 893 
     | 
    
         
            +
                  update_sql_values_hash(sql, data[:values])
         
     | 
| 
      
 894 
     | 
    
         
            +
                end
         
     | 
| 
      
 895 
     | 
    
         
            +
             
     | 
| 
      
 896 
     | 
    
         
            +
                def _merge_delete_sql(sql, data)
         
     | 
| 
      
 897 
     | 
    
         
            +
                  sql << " THEN DELETE"
         
     | 
| 
      
 898 
     | 
    
         
            +
                end
         
     | 
| 
      
 899 
     | 
    
         
            +
             
     | 
| 
      
 900 
     | 
    
         
            +
                # Mapping of merge types to related SQL
         
     | 
| 
      
 901 
     | 
    
         
            +
                MERGE_TYPE_SQL = {
         
     | 
| 
      
 902 
     | 
    
         
            +
                  :insert => ' WHEN NOT MATCHED',
         
     | 
| 
      
 903 
     | 
    
         
            +
                  :delete => ' WHEN MATCHED',
         
     | 
| 
      
 904 
     | 
    
         
            +
                  :update => ' WHEN MATCHED',
         
     | 
| 
      
 905 
     | 
    
         
            +
                  :matched => ' WHEN MATCHED',
         
     | 
| 
      
 906 
     | 
    
         
            +
                  :not_matched => ' WHEN NOT MATCHED',
         
     | 
| 
      
 907 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 908 
     | 
    
         
            +
                private_constant :MERGE_TYPE_SQL
         
     | 
| 
      
 909 
     | 
    
         
            +
             
     | 
| 
      
 910 
     | 
    
         
            +
                # Add the WHEN clauses to the MERGE SQL
         
     | 
| 
      
 911 
     | 
    
         
            +
                def _merge_when_sql(sql)
         
     | 
| 
      
 912 
     | 
    
         
            +
                  raise Error, "no WHEN [NOT] MATCHED clauses provided for MERGE" unless merge_when = @opts[:merge_when]
         
     | 
| 
      
 913 
     | 
    
         
            +
                  merge_when.each do |data|
         
     | 
| 
      
 914 
     | 
    
         
            +
                    type = data[:type]
         
     | 
| 
      
 915 
     | 
    
         
            +
                    sql << MERGE_TYPE_SQL[type]
         
     | 
| 
      
 916 
     | 
    
         
            +
                    _merge_when_conditions_sql(sql, data)
         
     | 
| 
      
 917 
     | 
    
         
            +
                    send(:"_merge_#{type}_sql", sql, data)
         
     | 
| 
      
 918 
     | 
    
         
            +
                  end
         
     | 
| 
      
 919 
     | 
    
         
            +
                end
         
     | 
| 
      
 920 
     | 
    
         
            +
             
     | 
| 
      
 921 
     | 
    
         
            +
                # Append MERGE WHEN conditions, if there are conditions provided.
         
     | 
| 
      
 922 
     | 
    
         
            +
                def _merge_when_conditions_sql(sql, data)
         
     | 
| 
      
 923 
     | 
    
         
            +
                  if data.has_key?(:conditions)
         
     | 
| 
      
 924 
     | 
    
         
            +
                    sql << " AND "
         
     | 
| 
      
 925 
     | 
    
         
            +
                    literal_append(sql, data[:conditions])
         
     | 
| 
      
 926 
     | 
    
         
            +
                  end
         
     | 
| 
      
 927 
     | 
    
         
            +
                end
         
     | 
| 
      
 928 
     | 
    
         
            +
             
     | 
| 
      
 929 
     | 
    
         
            +
                # Parse the values passed to insert_sql, returning columns and values
         
     | 
| 
      
 930 
     | 
    
         
            +
                # to use for the INSERT.  Returned columns is always an array, but can be empty
         
     | 
| 
      
 931 
     | 
    
         
            +
                # for an INSERT without explicit column references. Returned values can be an
         
     | 
| 
      
 932 
     | 
    
         
            +
                # array, dataset, or literal string.
         
     | 
| 
      
 933 
     | 
    
         
            +
                def _parse_insert_sql_args(values)
         
     | 
| 
      
 934 
     | 
    
         
            +
                  columns = []
         
     | 
| 
      
 935 
     | 
    
         
            +
             
     | 
| 
      
 936 
     | 
    
         
            +
                  case values.size
         
     | 
| 
      
 937 
     | 
    
         
            +
                  when 0
         
     | 
| 
      
 938 
     | 
    
         
            +
                    values = []
         
     | 
| 
      
 939 
     | 
    
         
            +
                  when 1
         
     | 
| 
      
 940 
     | 
    
         
            +
                    case vals = values[0]
         
     | 
| 
      
 941 
     | 
    
         
            +
                    when Hash
         
     | 
| 
      
 942 
     | 
    
         
            +
                      values = []
         
     | 
| 
      
 943 
     | 
    
         
            +
                      vals.each do |k,v| 
         
     | 
| 
      
 944 
     | 
    
         
            +
                        columns << k
         
     | 
| 
      
 945 
     | 
    
         
            +
                        values << v
         
     | 
| 
      
 946 
     | 
    
         
            +
                      end
         
     | 
| 
      
 947 
     | 
    
         
            +
                    when Dataset, Array, LiteralString
         
     | 
| 
      
 948 
     | 
    
         
            +
                      values = vals
         
     | 
| 
      
 949 
     | 
    
         
            +
                    end
         
     | 
| 
      
 950 
     | 
    
         
            +
                  when 2
         
     | 
| 
      
 951 
     | 
    
         
            +
                    if (v0 = values[0]).is_a?(Array) && ((v1 = values[1]).is_a?(Array) || v1.is_a?(Dataset) || v1.is_a?(LiteralString))
         
     | 
| 
      
 952 
     | 
    
         
            +
                      columns, values = v0, v1
         
     | 
| 
      
 953 
     | 
    
         
            +
                      raise(Error, "Different number of values and columns given to insert_sql") if values.is_a?(Array) and columns.length != values.length
         
     | 
| 
      
 954 
     | 
    
         
            +
                    end
         
     | 
| 
      
 955 
     | 
    
         
            +
                  end
         
     | 
| 
      
 956 
     | 
    
         
            +
             
     | 
| 
      
 957 
     | 
    
         
            +
                  [columns, values]
         
     | 
| 
      
 958 
     | 
    
         
            +
                end
         
     | 
| 
      
 959 
     | 
    
         
            +
             
     | 
| 
       855 
960 
     | 
    
         
             
                # Formats the truncate statement.  Assumes the table given has already been
         
     | 
| 
       856 
961 
     | 
    
         
             
                # literalized.
         
     | 
| 
       857 
962 
     | 
    
         
             
                def _truncate_sql(table)
         
     | 
| 
         @@ -896,9 +1001,15 @@ module Sequel 
     | 
|
| 
       896 
1001 
     | 
    
         
             
                # Clone of this dataset usable in aggregate operations.  Does
         
     | 
| 
       897 
1002 
     | 
    
         
             
                # a from_self if dataset contains any parameters that would
         
     | 
| 
       898 
1003 
     | 
    
         
             
                # affect normal aggregation, or just removes an existing
         
     | 
| 
       899 
     | 
    
         
            -
                # order if not.
         
     | 
| 
      
 1004 
     | 
    
         
            +
                # order if not. Also removes the row_proc, which isn't needed
         
     | 
| 
      
 1005 
     | 
    
         
            +
                # for aggregate calculations.
         
     | 
| 
       900 
1006 
     | 
    
         
             
                def aggregate_dataset
         
     | 
| 
       901 
     | 
    
         
            -
                   
     | 
| 
      
 1007 
     | 
    
         
            +
                  (aggreate_dataset_use_from_self? ? from_self : unordered).naked
         
     | 
| 
      
 1008 
     | 
    
         
            +
                end
         
     | 
| 
      
 1009 
     | 
    
         
            +
             
     | 
| 
      
 1010 
     | 
    
         
            +
                # Whether to use from_self for an aggregate dataset.
         
     | 
| 
      
 1011 
     | 
    
         
            +
                def aggreate_dataset_use_from_self?
         
     | 
| 
      
 1012 
     | 
    
         
            +
                  options_overlap(COUNT_FROM_SELF_OPTS)
         
     | 
| 
       902 
1013 
     | 
    
         
             
                end
         
     | 
| 
       903 
1014 
     | 
    
         | 
| 
       904 
1015 
     | 
    
         
             
                # Append aliasing expression to SQL string.
         
     | 
| 
         @@ -1020,9 +1131,14 @@ module Sequel 
     | 
|
| 
       1020 
1131 
     | 
    
         
             
                  :"t#{number}"
         
     | 
| 
       1021 
1132 
     | 
    
         
             
                end
         
     | 
| 
       1022 
1133 
     | 
    
         | 
| 
       1023 
     | 
    
         
            -
                # The strftime format to use when literalizing  
     | 
| 
      
 1134 
     | 
    
         
            +
                # The strftime format to use when literalizing time (Sequel::SQLTime) values.
         
     | 
| 
      
 1135 
     | 
    
         
            +
                def default_time_format
         
     | 
| 
      
 1136 
     | 
    
         
            +
                  "'%H:%M:%S.%6N'"
         
     | 
| 
      
 1137 
     | 
    
         
            +
                end
         
     | 
| 
      
 1138 
     | 
    
         
            +
             
     | 
| 
      
 1139 
     | 
    
         
            +
                # The strftime format to use when literalizing timestamp (Time/DateTime) values.
         
     | 
| 
       1024 
1140 
     | 
    
         
             
                def default_timestamp_format
         
     | 
| 
       1025 
     | 
    
         
            -
                   
     | 
| 
      
 1141 
     | 
    
         
            +
                  "'%Y-%m-%d %H:%M:%S.%6N'"
         
     | 
| 
       1026 
1142 
     | 
    
         
             
                end
         
     | 
| 
       1027 
1143 
     | 
    
         | 
| 
       1028 
1144 
     | 
    
         
             
                def delete_delete_sql(sql)
         
     | 
| 
         @@ -1085,43 +1201,23 @@ module Sequel 
     | 
|
| 
       1085 
1201 
     | 
    
         
             
                  {1 => ((op == :IN) ? 0 : 1)}
         
     | 
| 
       1086 
1202 
     | 
    
         
             
                end
         
     | 
| 
       1087 
1203 
     | 
    
         | 
| 
       1088 
     | 
    
         
            -
                # Format the timestamp based on the default_timestamp_format 
     | 
| 
       1089 
     | 
    
         
            -
                # of modifiers.  First, allow %N to be used for fractions seconds (if the
         
     | 
| 
       1090 
     | 
    
         
            -
                # database supports them), and override %z to always use a numeric offset
         
     | 
| 
       1091 
     | 
    
         
            -
                # of hours and minutes.
         
     | 
| 
      
 1204 
     | 
    
         
            +
                # Format the timestamp based on the default_timestamp_format.
         
     | 
| 
       1092 
1205 
     | 
    
         
             
                def format_timestamp(v)
         
     | 
| 
       1093 
     | 
    
         
            -
                   
     | 
| 
       1094 
     | 
    
         
            -
                  fmt = default_timestamp_format.gsub(/%[Nz]/) do |m|
         
     | 
| 
       1095 
     | 
    
         
            -
                    if m == '%N'
         
     | 
| 
       1096 
     | 
    
         
            -
                      # Ruby 1.9 supports %N in timestamp formats, but Sequel has supported %N
         
     | 
| 
       1097 
     | 
    
         
            -
                      # for longer in a different way, where the . is already appended and only 6
         
     | 
| 
       1098 
     | 
    
         
            -
                      # decimal places are used by default.
         
     | 
| 
       1099 
     | 
    
         
            -
                      format_timestamp_usec(v.is_a?(DateTime) ? v.sec_fraction*(1000000) : v.usec) if supports_timestamp_usecs?
         
     | 
| 
       1100 
     | 
    
         
            -
                    else
         
     | 
| 
       1101 
     | 
    
         
            -
                      if supports_timestamp_timezones?
         
     | 
| 
       1102 
     | 
    
         
            -
                        # Would like to just use %z format, but it doesn't appear to work on Windows
         
     | 
| 
       1103 
     | 
    
         
            -
                        # Instead, the offset fragment is constructed manually
         
     | 
| 
       1104 
     | 
    
         
            -
                        minutes = (v2.is_a?(DateTime) ? v2.offset * 1440 : v2.utc_offset/60).to_i
         
     | 
| 
       1105 
     | 
    
         
            -
                        format_timestamp_offset(*minutes.divmod(60))
         
     | 
| 
       1106 
     | 
    
         
            -
                      end
         
     | 
| 
       1107 
     | 
    
         
            -
                    end
         
     | 
| 
       1108 
     | 
    
         
            -
                  end
         
     | 
| 
       1109 
     | 
    
         
            -
                  v2.strftime(fmt)
         
     | 
| 
      
 1206 
     | 
    
         
            +
                  db.from_application_timestamp(v).strftime(default_timestamp_format)
         
     | 
| 
       1110 
1207 
     | 
    
         
             
                end
         
     | 
| 
       1111 
1208 
     | 
    
         | 
| 
       1112 
     | 
    
         
            -
                #  
     | 
| 
       1113 
     | 
    
         
            -
                def format_timestamp_offset(hour, minute)
         
     | 
| 
       1114 
     | 
    
         
            -
                  sprintf("%+03i%02i", hour, minute)
         
     | 
| 
       1115 
     | 
    
         
            -
                end
         
     | 
| 
      
 1209 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       1116 
1210 
     | 
    
         | 
| 
       1117 
1211 
     | 
    
         
             
                # Return the SQL timestamp fragment to use for the fractional time part.
         
     | 
| 
       1118 
1212 
     | 
    
         
             
                # Should start with the decimal point.  Uses 6 decimal places by default.
         
     | 
| 
       1119 
1213 
     | 
    
         
             
                def format_timestamp_usec(usec, ts=timestamp_precision)
         
     | 
| 
      
 1214 
     | 
    
         
            +
                  # SEQUEL6: Remove
         
     | 
| 
       1120 
1215 
     | 
    
         
             
                  unless ts == 6
         
     | 
| 
       1121 
1216 
     | 
    
         
             
                    usec = usec/(10 ** (6 - ts))
         
     | 
| 
       1122 
1217 
     | 
    
         
             
                  end
         
     | 
| 
       1123 
1218 
     | 
    
         
             
                  sprintf(".%0#{ts}d", usec)
         
     | 
| 
       1124 
1219 
     | 
    
         
             
                end
         
     | 
| 
      
 1220 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
       1125 
1221 
     | 
    
         | 
| 
       1126 
1222 
     | 
    
         
             
                # Append literalization of identifier to SQL string, considering regular strings
         
     | 
| 
       1127 
1223 
     | 
    
         
             
                # as SQL identifiers instead of SQL strings.
         
     | 
| 
         @@ -1166,7 +1262,10 @@ module Sequel 
     | 
|
| 
       1166 
1262 
     | 
    
         
             
                end
         
     | 
| 
       1167 
1263 
     | 
    
         | 
| 
       1168 
1264 
     | 
    
         
             
                def insert_columns_sql(sql)
         
     | 
| 
       1169 
     | 
    
         
            -
                   
     | 
| 
      
 1265 
     | 
    
         
            +
                  _insert_columns_sql(sql, opts[:columns])
         
     | 
| 
      
 1266 
     | 
    
         
            +
                end
         
     | 
| 
      
 1267 
     | 
    
         
            +
             
     | 
| 
      
 1268 
     | 
    
         
            +
                def _insert_columns_sql(sql, columns)
         
     | 
| 
       1170 
1269 
     | 
    
         
             
                  if columns && !columns.empty?
         
     | 
| 
       1171 
1270 
     | 
    
         
             
                    sql << ' ('
         
     | 
| 
       1172 
1271 
     | 
    
         
             
                    identifier_list_append(sql, columns)
         
     | 
| 
         @@ -1185,7 +1284,11 @@ module Sequel 
     | 
|
| 
       1185 
1284 
     | 
    
         
             
                end
         
     | 
| 
       1186 
1285 
     | 
    
         | 
| 
       1187 
1286 
     | 
    
         
             
                def insert_values_sql(sql)
         
     | 
| 
       1188 
     | 
    
         
            -
                   
     | 
| 
      
 1287 
     | 
    
         
            +
                  _insert_values_sql(sql, opts[:values])
         
     | 
| 
      
 1288 
     | 
    
         
            +
                end
         
     | 
| 
      
 1289 
     | 
    
         
            +
                
         
     | 
| 
      
 1290 
     | 
    
         
            +
                def _insert_values_sql(sql, values)
         
     | 
| 
      
 1291 
     | 
    
         
            +
                  case values
         
     | 
| 
       1189 
1292 
     | 
    
         
             
                  when Array
         
     | 
| 
       1190 
1293 
     | 
    
         
             
                    if values.empty?
         
     | 
| 
       1191 
1294 
     | 
    
         
             
                      sql << " DEFAULT VALUES"
         
     | 
| 
         @@ -1218,6 +1321,13 @@ module Sequel 
     | 
|
| 
       1218 
1321 
     | 
    
         
             
                  "#{join_type.to_s.gsub('_', ' ').upcase} JOIN"
         
     | 
| 
       1219 
1322 
     | 
    
         
             
                end
         
     | 
| 
       1220 
1323 
     | 
    
         | 
| 
      
 1324 
     | 
    
         
            +
                # Append USING clause for JOIN USING
         
     | 
| 
      
 1325 
     | 
    
         
            +
                def join_using_clause_using_sql_append(sql, using_columns)
         
     | 
| 
      
 1326 
     | 
    
         
            +
                  sql << ' USING ('
         
     | 
| 
      
 1327 
     | 
    
         
            +
                  column_list_append(sql, using_columns)
         
     | 
| 
      
 1328 
     | 
    
         
            +
                  sql << ')'
         
     | 
| 
      
 1329 
     | 
    
         
            +
                end
         
     | 
| 
      
 1330 
     | 
    
         
            +
                
         
     | 
| 
       1221 
1331 
     | 
    
         
             
                # Append a literalization of the array to SQL string.
         
     | 
| 
       1222 
1332 
     | 
    
         
             
                # Treats as an expression if an array of all two pairs, or as a SQL array otherwise.
         
     | 
| 
       1223 
1333 
     | 
    
         
             
                def literal_array_append(sql, v)
         
     | 
| 
         @@ -1249,11 +1359,12 @@ module Sequel 
     | 
|
| 
       1249 
1359 
     | 
    
         | 
| 
       1250 
1360 
     | 
    
         
             
                # SQL fragment for Date, using the ISO8601 format.
         
     | 
| 
       1251 
1361 
     | 
    
         
             
                def literal_date(v)
         
     | 
| 
       1252 
     | 
    
         
            -
                   
     | 
| 
       1253 
     | 
    
         
            -
             
     | 
| 
       1254 
     | 
    
         
            -
             
     | 
| 
       1255 
     | 
    
         
            -
             
     | 
| 
       1256 
     | 
    
         
            -
             
     | 
| 
      
 1362 
     | 
    
         
            +
                  v.strftime("'%Y-%m-%d'")
         
     | 
| 
      
 1363 
     | 
    
         
            +
                end
         
     | 
| 
      
 1364 
     | 
    
         
            +
             
     | 
| 
      
 1365 
     | 
    
         
            +
                # Append literalization of date to SQL string.
         
     | 
| 
      
 1366 
     | 
    
         
            +
                def literal_date_append(sql, v)
         
     | 
| 
      
 1367 
     | 
    
         
            +
                  sql << literal_date(v)
         
     | 
| 
       1257 
1368 
     | 
    
         
             
                end
         
     | 
| 
       1258 
1369 
     | 
    
         | 
| 
       1259 
1370 
     | 
    
         
             
                # SQL fragment for DateTime
         
     | 
| 
         @@ -1316,7 +1427,7 @@ module Sequel 
     | 
|
| 
       1316 
1427 
     | 
    
         | 
| 
       1317 
1428 
     | 
    
         
             
                # SQL fragment for Sequel::SQLTime, containing just the time part
         
     | 
| 
       1318 
1429 
     | 
    
         
             
                def literal_sqltime(v)
         
     | 
| 
       1319 
     | 
    
         
            -
                  v.strftime( 
     | 
| 
      
 1430 
     | 
    
         
            +
                  v.strftime(default_time_format)
         
     | 
| 
       1320 
1431 
     | 
    
         
             
                end
         
     | 
| 
       1321 
1432 
     | 
    
         | 
| 
       1322 
1433 
     | 
    
         
             
                # Append literalization of Sequel::SQLTime to SQL string.
         
     | 
| 
         @@ -1538,15 +1649,14 @@ module Sequel 
     | 
|
| 
       1538 
1649 
     | 
    
         | 
| 
       1539 
1650 
     | 
    
         
             
                def select_with_sql(sql)
         
     | 
| 
       1540 
1651 
     | 
    
         
             
                  return unless supports_cte?
         
     | 
| 
       1541 
     | 
    
         
            -
                   
     | 
| 
       1542 
     | 
    
         
            -
                  return if ! 
     | 
| 
      
 1652 
     | 
    
         
            +
                  ctes = opts[:with]
         
     | 
| 
      
 1653 
     | 
    
         
            +
                  return if !ctes || ctes.empty?
         
     | 
| 
       1543 
1654 
     | 
    
         
             
                  sql << select_with_sql_base
         
     | 
| 
       1544 
1655 
     | 
    
         
             
                  c = false
         
     | 
| 
       1545 
1656 
     | 
    
         
             
                  comma = ', '
         
     | 
| 
       1546 
     | 
    
         
            -
                   
     | 
| 
      
 1657 
     | 
    
         
            +
                  ctes.each do |cte|
         
     | 
| 
       1547 
1658 
     | 
    
         
             
                    sql << comma if c
         
     | 
| 
       1548 
     | 
    
         
            -
                     
     | 
| 
       1549 
     | 
    
         
            -
                    literal_dataset_append(sql, w[:dataset])
         
     | 
| 
      
 1659 
     | 
    
         
            +
                    select_with_sql_cte(sql, cte)
         
     | 
| 
       1550 
1660 
     | 
    
         
             
                    c ||= true
         
     | 
| 
       1551 
1661 
     | 
    
         
             
                  end
         
     | 
| 
       1552 
1662 
     | 
    
         
             
                  sql << ' '
         
     | 
| 
         @@ -1559,6 +1669,11 @@ module Sequel 
     | 
|
| 
       1559 
1669 
     | 
    
         
             
                  "WITH "
         
     | 
| 
       1560 
1670 
     | 
    
         
             
                end
         
     | 
| 
       1561 
1671 
     | 
    
         | 
| 
      
 1672 
     | 
    
         
            +
                def select_with_sql_cte(sql, cte)
         
     | 
| 
      
 1673 
     | 
    
         
            +
                  select_with_sql_prefix(sql, cte)
         
     | 
| 
      
 1674 
     | 
    
         
            +
                  literal_dataset_append(sql, cte[:dataset])
         
     | 
| 
      
 1675 
     | 
    
         
            +
                end
         
     | 
| 
      
 1676 
     | 
    
         
            +
                
         
     | 
| 
       1562 
1677 
     | 
    
         
             
                def select_with_sql_prefix(sql, w)
         
     | 
| 
       1563 
1678 
     | 
    
         
             
                  quote_identifier_append(sql, w[:name])
         
     | 
| 
       1564 
1679 
     | 
    
         
             
                  if args = w[:args]
         
     | 
| 
         @@ -1628,7 +1743,7 @@ module Sequel 
     | 
|
| 
       1628 
1743 
     | 
    
         
             
                # Append literalization of the subselect to SQL string.
         
     | 
| 
       1629 
1744 
     | 
    
         
             
                def subselect_sql_append(sql, ds)
         
     | 
| 
       1630 
1745 
     | 
    
         
             
                  sds = subselect_sql_dataset(sql, ds)
         
     | 
| 
       1631 
     | 
    
         
            -
                  sds 
     | 
| 
      
 1746 
     | 
    
         
            +
                  subselect_sql_append_sql(sql, sds)
         
     | 
| 
       1632 
1747 
     | 
    
         
             
                  unless sds.send(:cache_sql?)
         
     | 
| 
       1633 
1748 
     | 
    
         
             
                    # If subquery dataset does not allow caching SQL,
         
     | 
| 
       1634 
1749 
     | 
    
         
             
                    # then this dataset should not allow caching SQL.
         
     | 
| 
         @@ -1640,6 +1755,10 @@ module Sequel 
     | 
|
| 
       1640 
1755 
     | 
    
         
             
                  ds.clone(:append_sql=>sql)
         
     | 
| 
       1641 
1756 
     | 
    
         
             
                end
         
     | 
| 
       1642 
1757 
     | 
    
         | 
| 
      
 1758 
     | 
    
         
            +
                def subselect_sql_append_sql(sql, ds)
         
     | 
| 
      
 1759 
     | 
    
         
            +
                  ds.sql
         
     | 
| 
      
 1760 
     | 
    
         
            +
                end
         
     | 
| 
      
 1761 
     | 
    
         
            +
             
     | 
| 
       1643 
1762 
     | 
    
         
             
                # The number of decimal digits of precision to use in timestamps.
         
     | 
| 
       1644 
1763 
     | 
    
         
             
                def timestamp_precision
         
     | 
| 
       1645 
1764 
     | 
    
         
             
                  supports_timestamp_usecs? ? 6 : 0
         
     | 
    
        data/lib/sequel/dataset.rb
    CHANGED
    
    | 
         @@ -53,4 +53,8 @@ module Sequel 
     | 
|
| 
       53 
53 
     | 
    
         
             
              require_relative "dataset/sql"
         
     | 
| 
       54 
54 
     | 
    
         
             
              require_relative "dataset/placeholder_literalizer"
         
     | 
| 
       55 
55 
     | 
    
         
             
              require_relative "dataset/dataset_module"
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              # :nocov:
         
     | 
| 
      
 58 
     | 
    
         
            +
              require_relative "dataset/deprecated_singleton_class_methods" if Dataset::TRUE_FREEZE
         
     | 
| 
      
 59 
     | 
    
         
            +
              # :nocov:
         
     | 
| 
       56 
60 
     | 
    
         
             
            end
         
     | 
| 
         @@ -23,18 +23,6 @@ module Sequel 
     | 
|
| 
       23 
23 
     | 
    
         
             
                        super
         
     | 
| 
       24 
24 
     | 
    
         
             
                      end
         
     | 
| 
       25 
25 
     | 
    
         
             
                    end
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                    private
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                    # Handle Sequel::Model instances in bound variable arrays.
         
     | 
| 
       30 
     | 
    
         
            -
                    def bound_variable_array(arg)
         
     | 
| 
       31 
     | 
    
         
            -
                      case arg
         
     | 
| 
       32 
     | 
    
         
            -
                      when Sequel::Model
         
     | 
| 
       33 
     | 
    
         
            -
                        "\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
         
     | 
| 
       34 
     | 
    
         
            -
                      else
         
     | 
| 
       35 
     | 
    
         
            -
                        super
         
     | 
| 
       36 
     | 
    
         
            -
                      end
         
     | 
| 
       37 
     | 
    
         
            -
                    end
         
     | 
| 
       38 
26 
     | 
    
         
             
                  end
         
     | 
| 
       39 
27 
     | 
    
         
             
                end
         
     | 
| 
       40 
28 
     | 
    
         
             
              end
         
     | 
| 
         @@ -5,9 +5,9 @@ 
     | 
|
| 
       5 
5 
     | 
    
         
             
            # code
         
     | 
| 
       6 
6 
     | 
    
         
             
            #
         
     | 
| 
       7 
7 
     | 
    
         
             
            #   DB.extension :async_thread_pool
         
     | 
| 
       8 
     | 
    
         
            -
            #   foos = DB[:foos].async.where 
     | 
| 
      
 8 
     | 
    
         
            +
            #   foos = DB[:foos].async.where(name: 'A'..'M').all
         
     | 
| 
       9 
9 
     | 
    
         
             
            #   bar_names = DB[:bar].async.select_order_map(:name)
         
     | 
| 
       10 
     | 
    
         
            -
            #   baz_1 = DB[:bazes].async.first(: 
     | 
| 
      
 10 
     | 
    
         
            +
            #   baz_1 = DB[:bazes].async.first(id: 1)
         
     | 
| 
       11 
11 
     | 
    
         
             
            #
         
     | 
| 
       12 
12 
     | 
    
         
             
            # All 3 queries will be run in separate threads.  +foos+, +bar_names+
         
     | 
| 
       13 
13 
     | 
    
         
             
            # and +baz_1+ will be proxy objects.  Calling a method on the proxy
         
     | 
| 
         @@ -15,9 +15,9 @@ 
     | 
|
| 
       15 
15 
     | 
    
         
             
            # of calling that method on the result of the query method. For example,
         
     | 
| 
       16 
16 
     | 
    
         
             
            # if you run:
         
     | 
| 
       17 
17 
     | 
    
         
             
            #
         
     | 
| 
       18 
     | 
    
         
            -
            #   foos = DB[:foos].async.where 
     | 
| 
      
 18 
     | 
    
         
            +
            #   foos = DB[:foos].async.where(name: 'A'..'M').all
         
     | 
| 
       19 
19 
     | 
    
         
             
            #   bar_names = DB[:bars].async.select_order_map(:name)
         
     | 
| 
       20 
     | 
    
         
            -
            #   baz_1 = DB[:bazes].async.first(: 
     | 
| 
      
 20 
     | 
    
         
            +
            #   baz_1 = DB[:bazes].async.first(id: 1)
         
     | 
| 
       21 
21 
     | 
    
         
             
            #   sleep(1)
         
     | 
| 
       22 
22 
     | 
    
         
             
            #   foos.size
         
     | 
| 
       23 
23 
     | 
    
         
             
            #   bar_names.first
         
     | 
| 
         @@ -26,9 +26,9 @@ 
     | 
|
| 
       26 
26 
     | 
    
         
             
            # These three queries will generally be run concurrently in separate
         
     | 
| 
       27 
27 
     | 
    
         
             
            # threads.  If you instead run:
         
     | 
| 
       28 
28 
     | 
    
         
             
            #   
         
     | 
| 
       29 
     | 
    
         
            -
            #   DB[:foos].async.where 
     | 
| 
      
 29 
     | 
    
         
            +
            #   DB[:foos].async.where(name: 'A'..'M').all.size
         
     | 
| 
       30 
30 
     | 
    
         
             
            #   DB[:bars].async.select_order_map(:name).first
         
     | 
| 
       31 
     | 
    
         
            -
            #   DB[:bazes].async.first(: 
     | 
| 
      
 31 
     | 
    
         
            +
            #   DB[:bazes].async.first(id: 1).name
         
     | 
| 
       32 
32 
     | 
    
         
             
            #
         
     | 
| 
       33 
33 
     | 
    
         
             
            # Then will run each query sequentially, since you need the result of
         
     | 
| 
       34 
34 
     | 
    
         
             
            # one query before running the next query.  The queries will still be
         
     | 
| 
         @@ -37,11 +37,11 @@ 
     | 
|
| 
       37 
37 
     | 
    
         
             
            # What is run in the separate thread is the entire method call that
         
     | 
| 
       38 
38 
     | 
    
         
             
            # returns results.  So with the original example:
         
     | 
| 
       39 
39 
     | 
    
         
             
            #
         
     | 
| 
       40 
     | 
    
         
            -
            #   foos = DB[:foos].async.where 
     | 
| 
      
 40 
     | 
    
         
            +
            #   foos = DB[:foos].async.where(name: 'A'..'M').all
         
     | 
| 
       41 
41 
     | 
    
         
             
            #   bar_names = DB[:bars].async.select_order_map(:name)
         
     | 
| 
       42 
     | 
    
         
            -
            #   baz_1 = DB[:bazes].async.first(: 
     | 
| 
      
 42 
     | 
    
         
            +
            #   baz_1 = DB[:bazes].async.first(id: 1)
         
     | 
| 
       43 
43 
     | 
    
         
             
            #
         
     | 
| 
       44 
     | 
    
         
            -
            # The +all+, <tt>select_order_map(:name)</tt>, and <tt>first(: 
     | 
| 
      
 44 
     | 
    
         
            +
            # The +all+, <tt>select_order_map(:name)</tt>, and <tt>first(id: 1)</tt>
         
     | 
| 
       45 
45 
     | 
    
         
             
            # calls are run in separate threads.  If a block is passed to a method
         
     | 
| 
       46 
46 
     | 
    
         
             
            # such as +all+ or +each+, the block is also run in that thread.  If you
         
     | 
| 
       47 
47 
     | 
    
         
             
            # have code such as:
         
     | 
| 
         @@ -156,10 +156,10 @@ 
     | 
|
| 
       156 
156 
     | 
    
         
             
            # so that the query will run in the current thread instead of waiting
         
     | 
| 
       157 
157 
     | 
    
         
             
            # for an async thread to become available.  With the following code:
         
     | 
| 
       158 
158 
     | 
    
         
             
            #
         
     | 
| 
       159 
     | 
    
         
            -
            #   foos = DB[:foos].async.where 
     | 
| 
      
 159 
     | 
    
         
            +
            #   foos = DB[:foos].async.where(name: 'A'..'M').all
         
     | 
| 
       160 
160 
     | 
    
         
             
            #   bar_names = DB[:bar].async.select_order_map(:name)
         
     | 
| 
       161 
161 
     | 
    
         
             
            #   if foos.length > 4
         
     | 
| 
       162 
     | 
    
         
            -
            #     baz_1 = DB[:bazes].async.first(: 
     | 
| 
      
 162 
     | 
    
         
            +
            #     baz_1 = DB[:bazes].async.first(id: 1)
         
     | 
| 
       163 
163 
     | 
    
         
             
            #   end
         
     | 
| 
       164 
164 
     | 
    
         
             
            # 
         
     | 
| 
       165 
165 
     | 
    
         
             
            # Whether you need the +baz_1+ variable depends on the value of foos.
         
     | 
| 
         @@ -338,8 +338,9 @@ module Sequel 
     | 
|
| 
       338 
338 
     | 
    
         
             
                module DatabaseMethods
         
     | 
| 
       339 
339 
     | 
    
         
             
                  def self.extended(db)
         
     | 
| 
       340 
340 
     | 
    
         
             
                    db.instance_exec do
         
     | 
| 
       341 
     | 
    
         
            -
                       
     | 
| 
       342 
     | 
    
         
            -
             
     | 
| 
      
 341 
     | 
    
         
            +
                      case pool.pool_type
         
     | 
| 
      
 342 
     | 
    
         
            +
                      when :single, :sharded_single
         
     | 
| 
      
 343 
     | 
    
         
            +
                        raise Error, "cannot load async_thread_pool extension if using single or sharded_single connection pool"
         
     | 
| 
       343 
344 
     | 
    
         
             
                      end
         
     | 
| 
       344 
345 
     | 
    
         | 
| 
       345 
346 
     | 
    
         
             
                      num_async_threads = opts[:num_async_threads] ? typecast_value_integer(opts[:num_async_threads]) : (Integer(opts[:max_connections] || 4))
         
     | 
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen-string-literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # The auto_cast_date_and_time extension uses SQL standard type casting
         
     | 
| 
      
 4 
     | 
    
         
            +
            # when literalizing date, time, and timestamp values:
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            #   DB.literal(Time.now)
         
     | 
| 
      
 7 
     | 
    
         
            +
            #   # => "TIMESTAMP '...'"
         
     | 
| 
      
 8 
     | 
    
         
            +
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   DB.literal(Date.today)
         
     | 
| 
      
 10 
     | 
    
         
            +
            #   # => "DATE '...'"
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            #   DB.literal(Sequel::SQLTime.create(10, 20, 30))
         
     | 
| 
      
 13 
     | 
    
         
            +
            #   # => "TIME '10:20:30.000000'"
         
     | 
| 
      
 14 
     | 
    
         
            +
            #
         
     | 
| 
      
 15 
     | 
    
         
            +
            # The default behavior of Sequel on adapters that do not require the
         
     | 
| 
      
 16 
     | 
    
         
            +
            # SQL standard behavior is to format the date or time value without:
         
     | 
| 
      
 17 
     | 
    
         
            +
            # casting
         
     | 
| 
      
 18 
     | 
    
         
            +
            #
         
     | 
| 
      
 19 
     | 
    
         
            +
            #   DB.literal(Sequel::SQLTime.create(10, 20, 30))
         
     | 
| 
      
 20 
     | 
    
         
            +
            #   # => "'10:20:30.000000'"
         
     | 
| 
      
 21 
     | 
    
         
            +
            #
         
     | 
| 
      
 22 
     | 
    
         
            +
            # However, then the database cannot determine the type of the string,
         
     | 
| 
      
 23 
     | 
    
         
            +
            # and must perform some implicit casting.  If implicit casting cannot
         
     | 
| 
      
 24 
     | 
    
         
            +
            # be used, it will probably treat the value as a string:
         
     | 
| 
      
 25 
     | 
    
         
            +
            #
         
     | 
| 
      
 26 
     | 
    
         
            +
            #  DB.get(Time.now).class
         
     | 
| 
      
 27 
     | 
    
         
            +
            #  # Without auto_cast_date_and_time: String
         
     | 
| 
      
 28 
     | 
    
         
            +
            #  #    With auto_cast_date_and_time: Time
         
     | 
| 
      
 29 
     | 
    
         
            +
            #
         
     | 
| 
      
 30 
     | 
    
         
            +
            # Note that not all databases support this extension. PostgreSQL and
         
     | 
| 
      
 31 
     | 
    
         
            +
            # MySQL support it, but SQLite and Microsoft SQL Server do not.
         
     | 
| 
      
 32 
     | 
    
         
            +
            #
         
     | 
| 
      
 33 
     | 
    
         
            +
            # You can load this extension into specific datasets:
         
     | 
| 
      
 34 
     | 
    
         
            +
            #
         
     | 
| 
      
 35 
     | 
    
         
            +
            #   ds = DB[:table]
         
     | 
| 
      
 36 
     | 
    
         
            +
            #   ds = ds.extension(:auto_cast_date_and_time)
         
     | 
| 
      
 37 
     | 
    
         
            +
            #
         
     | 
| 
      
 38 
     | 
    
         
            +
            # Or you can load it into all of a database's datasets, which
         
     | 
| 
      
 39 
     | 
    
         
            +
            # is probably the desired behavior if you are using this extension:
         
     | 
| 
      
 40 
     | 
    
         
            +
            #
         
     | 
| 
      
 41 
     | 
    
         
            +
            #   DB.extension(:auto_cast_date_and_time)
         
     | 
| 
      
 42 
     | 
    
         
            +
            # 
         
     | 
| 
      
 43 
     | 
    
         
            +
            # Related module: Sequel::AutoCastDateAndTime
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            #
         
     | 
| 
      
 46 
     | 
    
         
            +
            module Sequel
         
     | 
| 
      
 47 
     | 
    
         
            +
              module AutoCastDateAndTime
         
     | 
| 
      
 48 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # Mark the datasets as requiring sql standard date times.  This is only needed
         
     | 
| 
      
 51 
     | 
    
         
            +
                # for backwards compatibility.  
         
     | 
| 
      
 52 
     | 
    
         
            +
                def requires_sql_standard_datetimes?
         
     | 
| 
      
 53 
     | 
    
         
            +
                  # SEQUEL6: Remove
         
     | 
| 
      
 54 
     | 
    
         
            +
                  true
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                private
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                # Explicitly cast SQLTime objects to TIME.
         
     | 
| 
      
 61 
     | 
    
         
            +
                def literal_sqltime_append(sql, v)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  sql << "TIME "
         
     | 
| 
      
 63 
     | 
    
         
            +
                  super
         
     | 
| 
      
 64 
     | 
    
         
            +
                end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                # Explicitly cast Time objects to TIMESTAMP.
         
     | 
| 
      
 67 
     | 
    
         
            +
                def literal_time_append(sql, v)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  sql << literal_datetime_timestamp_cast
         
     | 
| 
      
 69 
     | 
    
         
            +
                  super
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                # Explicitly cast DateTime objects to TIMESTAMP.
         
     | 
| 
      
 73 
     | 
    
         
            +
                def literal_datetime_append(sql, v)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  sql << literal_datetime_timestamp_cast
         
     | 
| 
      
 75 
     | 
    
         
            +
                  super
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                # Explicitly cast Date objects to DATE.
         
     | 
| 
      
 79 
     | 
    
         
            +
                def literal_date_append(sql, v)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  sql << "DATE "
         
     | 
| 
      
 81 
     | 
    
         
            +
                  super
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                # The default cast string to use for Time/DateTime objects.
         
     | 
| 
      
 85 
     | 
    
         
            +
                # Respects existing method if already defined.
         
     | 
| 
      
 86 
     | 
    
         
            +
                def literal_datetime_timestamp_cast
         
     | 
| 
      
 87 
     | 
    
         
            +
                  return super if defined?(super)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  'TIMESTAMP '
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              Dataset.register_extension(:auto_cast_date_and_time, AutoCastDateAndTime)
         
     | 
| 
      
 93 
     | 
    
         
            +
            end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
         @@ -22,7 +22,7 @@ 
     | 
|
| 
       22 
22 
     | 
    
         
             
            #
         
     | 
| 
       23 
23 
     | 
    
         
             
            # Named placeholders can also be used with a hash:
         
     | 
| 
       24 
24 
     | 
    
         
             
            #
         
     | 
| 
       25 
     | 
    
         
            -
            #   ds.where("name > :a", : 
     | 
| 
      
 25 
     | 
    
         
            +
            #   ds.where("name > :a", a: "A")
         
     | 
| 
       26 
26 
     | 
    
         
             
            #   # SELECT * FROM table WHERE (name > 'A')
         
     | 
| 
       27 
27 
     | 
    
         
             
            #
         
     | 
| 
       28 
28 
     | 
    
         
             
            # This extension also allows the use of a plain string passed to Dataset#update:
         
     | 
| 
         @@ -15,16 +15,16 @@ 
     | 
|
| 
       15 
15 
     | 
    
         
             
            #
         
     | 
| 
       16 
16 
     | 
    
         
             
            #   DB.pool.connection_expiration_timeout = 3600 # 1 hour
         
     | 
| 
       17 
17 
     | 
    
         
             
            #
         
     | 
| 
       18 
     | 
    
         
            -
            # Note that this extension  
     | 
| 
       19 
     | 
    
         
            -
            # and  
     | 
| 
       20 
     | 
    
         
            -
            #  
     | 
| 
       21 
     | 
    
         
            -
            # not affected.  As the only reason to use the single threaded
         
     | 
| 
      
 18 
     | 
    
         
            +
            # Note that this extension does not work with the single
         
     | 
| 
      
 19 
     | 
    
         
            +
            # threaded and sharded single threaded connection pools.
         
     | 
| 
      
 20 
     | 
    
         
            +
            # As the only reason to use the single threaded
         
     | 
| 
       22 
21 
     | 
    
         
             
            # pools is for speed, and this extension makes the connection
         
     | 
| 
       23 
22 
     | 
    
         
             
            # pool slower, there's not much point in modifying this
         
     | 
| 
       24 
23 
     | 
    
         
             
            # extension to work with the single threaded pools.  The
         
     | 
| 
       25 
     | 
    
         
            -
            # threaded pools work fine even in single threaded 
     | 
| 
       26 
     | 
    
         
            -
            # you are currently using a single threaded pool 
     | 
| 
       27 
     | 
    
         
            -
            # use this extension, switch to using  
     | 
| 
      
 24 
     | 
    
         
            +
            # non-single threaded pools work fine even in single threaded
         
     | 
| 
      
 25 
     | 
    
         
            +
            # code, so if you are currently using a single threaded pool
         
     | 
| 
      
 26 
     | 
    
         
            +
            # and want to use this extension, switch to using another
         
     | 
| 
      
 27 
     | 
    
         
            +
            # pool.
         
     | 
| 
       28 
28 
     | 
    
         
             
            #
         
     | 
| 
       29 
29 
     | 
    
         
             
            # Related module: Sequel::ConnectionExpiration
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
         @@ -45,6 +45,11 @@ module Sequel 
     | 
|
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                # Initialize the data structures used by this extension.
         
     | 
| 
       47 
47 
     | 
    
         
             
                def self.extended(pool)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  case pool.pool_type
         
     | 
| 
      
 49 
     | 
    
         
            +
                  when :single, :sharded_single
         
     | 
| 
      
 50 
     | 
    
         
            +
                    raise Error, "cannot load connection_expiration extension if using single or sharded_single connection pool"
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
       48 
53 
     | 
    
         
             
                  pool.instance_exec do
         
     | 
| 
       49 
54 
     | 
    
         
             
                    sync do
         
     | 
| 
       50 
55 
     | 
    
         
             
                      @connection_expiration_timestamps ||= {}
         
     | 
| 
         @@ -79,8 +84,9 @@ module Sequel 
     | 
|
| 
       79 
84 
     | 
    
         
             
                       (cet = sync{@connection_expiration_timestamps[conn]}) &&
         
     | 
| 
       80 
85 
     | 
    
         
             
                       Sequel.elapsed_seconds_since(cet[0]) > cet[1]
         
     | 
| 
       81 
86 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                       
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
      
 87 
     | 
    
         
            +
                      case pool_type
         
     | 
| 
      
 88 
     | 
    
         
            +
                      when :sharded_threaded, :sharded_timed_queue
         
     | 
| 
      
 89 
     | 
    
         
            +
                        sync{@allocated[a.last].delete(Sequel.current)}
         
     | 
| 
       84 
90 
     | 
    
         
             
                      else
         
     | 
| 
       85 
91 
     | 
    
         
             
                        sync{@allocated.delete(Sequel.current)}
         
     | 
| 
       86 
92 
     | 
    
         
             
                      end
         
     |