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
 
| 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen-string-literal: true
         
     | 
| 
       2 
2 
     | 
    
         
             
            #
         
     | 
| 
       3 
3 
     | 
    
         
             
            # The pg_range_ops extension adds support to Sequel's DSL to make
         
     | 
| 
       4 
     | 
    
         
            -
            # it easier to call PostgreSQL range functions and operators.
         
     | 
| 
      
 4 
     | 
    
         
            +
            # it easier to call PostgreSQL range and multirange functions and operators.
         
     | 
| 
       5 
5 
     | 
    
         
             
            #
         
     | 
| 
       6 
6 
     | 
    
         
             
            # To load the extension:
         
     | 
| 
       7 
7 
     | 
    
         
             
            #
         
     | 
| 
         @@ -11,10 +11,11 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            #
         
     | 
| 
       12 
12 
     | 
    
         
             
            #   r = Sequel.pg_range_op(:range)
         
     | 
| 
       13 
13 
     | 
    
         
             
            #
         
     | 
| 
       14 
     | 
    
         
            -
            # If you have also loaded the pg_range  
     | 
| 
       15 
     | 
    
         
            -
            # Sequel.pg_range as well:
         
     | 
| 
      
 14 
     | 
    
         
            +
            # If you have also loaded the pg_range or pg_multirange extensions, you can use
         
     | 
| 
      
 15 
     | 
    
         
            +
            # Sequel.pg_range or Sequel.pg_multirange as well:
         
     | 
| 
       16 
16 
     | 
    
         
             
            #
         
     | 
| 
       17 
17 
     | 
    
         
             
            #   r = Sequel.pg_range(:range)
         
     | 
| 
      
 18 
     | 
    
         
            +
            #   r = Sequel.pg_multirange(:range)
         
     | 
| 
       18 
19 
     | 
    
         
             
            #
         
     | 
| 
       19 
20 
     | 
    
         
             
            # Also, on most Sequel expression objects, you can call the pg_range
         
     | 
| 
       20 
21 
     | 
    
         
             
            # method:
         
     | 
| 
         @@ -46,13 +47,25 @@ 
     | 
|
| 
       46 
47 
     | 
    
         
             
            #   r.upper_inc        # upper_inc(range)
         
     | 
| 
       47 
48 
     | 
    
         
             
            #   r.lower_inf        # lower_inf(range)
         
     | 
| 
       48 
49 
     | 
    
         
             
            #   r.upper_inf        # upper_inf(range)
         
     | 
| 
      
 50 
     | 
    
         
            +
            #
         
     | 
| 
      
 51 
     | 
    
         
            +
            # All of the above methods work for both ranges and multiranges, as long
         
     | 
| 
      
 52 
     | 
    
         
            +
            # as PostgreSQL supports the operation. The following methods are also
         
     | 
| 
      
 53 
     | 
    
         
            +
            # supported:
         
     | 
| 
      
 54 
     | 
    
         
            +
            #
         
     | 
| 
      
 55 
     | 
    
         
            +
            #   r.range_merge      # range_merge(range)
         
     | 
| 
      
 56 
     | 
    
         
            +
            #   r.unnest           # unnest(range)
         
     | 
| 
      
 57 
     | 
    
         
            +
            #   r.multirange       # multirange(range)
         
     | 
| 
      
 58 
     | 
    
         
            +
            #
         
     | 
| 
      
 59 
     | 
    
         
            +
            # +range_merge+ and +unnest+ expect the receiver to represent a multirange
         
     | 
| 
      
 60 
     | 
    
         
            +
            # value, while +multi_range+ expects the receiver to represent a range value.
         
     | 
| 
       49 
61 
     | 
    
         
             
            #   
         
     | 
| 
       50 
     | 
    
         
            -
            # See the PostgreSQL range function and operator documentation for more
         
     | 
| 
      
 62 
     | 
    
         
            +
            # See the PostgreSQL range and multirange function and operator documentation for more
         
     | 
| 
       51 
63 
     | 
    
         
             
            # details on what these functions and operators do.
         
     | 
| 
       52 
64 
     | 
    
         
             
            #
         
     | 
| 
       53 
     | 
    
         
            -
            # If you are also using the pg_range extension, you should 
     | 
| 
       54 
     | 
    
         
            -
            # loading this extension.  Doing so will allow you to use 
     | 
| 
       55 
     | 
    
         
            -
            #  
     | 
| 
      
 65 
     | 
    
         
            +
            # If you are also using the pg_range or pg_multirange extension, you should
         
     | 
| 
      
 66 
     | 
    
         
            +
            # load them before loading this extension.  Doing so will allow you to use
         
     | 
| 
      
 67 
     | 
    
         
            +
            # PGRange#op and PGMultiRange#op to get a RangeOp, allowing you to perform
         
     | 
| 
      
 68 
     | 
    
         
            +
            # range operations on range literals.
         
     | 
| 
       56 
69 
     | 
    
         
             
            #
         
     | 
| 
       57 
70 
     | 
    
         
             
            # Related module: Sequel::Postgres::RangeOp
         
     | 
| 
       58 
71 
     | 
    
         | 
| 
         @@ -77,9 +90,12 @@ module Sequel 
     | 
|
| 
       77 
90 
     | 
    
         
             
                    :overlaps => ["(".freeze, " && ".freeze, ")".freeze].freeze,
         
     | 
| 
       78 
91 
     | 
    
         
             
                  }.freeze
         
     | 
| 
       79 
92 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
                  %w'lower upper isempty lower_inc upper_inc lower_inf upper_inf'.each do |f|
         
     | 
| 
      
 93 
     | 
    
         
            +
                  %w'lower upper isempty lower_inc upper_inc lower_inf upper_inf unnest'.each do |f|
         
     | 
| 
       81 
94 
     | 
    
         
             
                    class_eval("def #{f}; function(:#{f}) end", __FILE__, __LINE__)
         
     | 
| 
       82 
95 
     | 
    
         
             
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  %w'range_merge multirange'.each do |f|
         
     | 
| 
      
 97 
     | 
    
         
            +
                    class_eval("def #{f}; RangeOp.new(function(:#{f})) end", __FILE__, __LINE__)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
       83 
99 
     | 
    
         
             
                  OPERATORS.each_key do |f|
         
     | 
| 
       84 
100 
     | 
    
         
             
                    class_eval("def #{f}(v); operator(:#{f}, v) end", __FILE__, __LINE__)
         
     | 
| 
       85 
101 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -127,6 +143,18 @@ module Sequel 
     | 
|
| 
       127 
143 
     | 
    
         
             
                    end
         
     | 
| 
       128 
144 
     | 
    
         
             
                  end
         
     | 
| 
       129 
145 
     | 
    
         
             
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 148 
     | 
    
         
            +
                if defined?(PGMultiRange)
         
     | 
| 
      
 149 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 150 
     | 
    
         
            +
                  class PGMultiRange
         
     | 
| 
      
 151 
     | 
    
         
            +
                    # Wrap the PGRange instance in an RangeOp, allowing you to easily use
         
     | 
| 
      
 152 
     | 
    
         
            +
                    # the PostgreSQL range functions and operators with literal ranges.
         
     | 
| 
      
 153 
     | 
    
         
            +
                    def op
         
     | 
| 
      
 154 
     | 
    
         
            +
                      RangeOp.new(self)
         
     | 
| 
      
 155 
     | 
    
         
            +
                    end
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
       130 
158 
     | 
    
         
             
              end
         
     | 
| 
       131 
159 
     | 
    
         | 
| 
       132 
160 
     | 
    
         
             
              module SQL::Builders
         
     | 
| 
         @@ -160,7 +188,7 @@ end 
     | 
|
| 
       160 
188 
     | 
    
         
             
            if defined?(Sequel::CoreRefinements)
         
     | 
| 
       161 
189 
     | 
    
         
             
              module Sequel::CoreRefinements
         
     | 
| 
       162 
190 
     | 
    
         
             
                refine Symbol do
         
     | 
| 
       163 
     | 
    
         
            -
                   
     | 
| 
      
 191 
     | 
    
         
            +
                  send INCLUDE_METH, Sequel::Postgres::RangeOpMethods
         
     | 
| 
       164 
192 
     | 
    
         
             
                end
         
     | 
| 
       165 
193 
     | 
    
         
             
              end
         
     | 
| 
       166 
194 
     | 
    
         
             
            end
         
     | 
| 
         @@ -136,6 +136,15 @@ module Sequel 
     | 
|
| 
       136 
136 
     | 
    
         
             
                        ds.quote_schema_table_append(sql, db_type)
         
     | 
| 
       137 
137 
     | 
    
         
             
                      end
         
     | 
| 
       138 
138 
     | 
    
         
             
                    end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                    # Allow automatic parameterization if all values support it.
         
     | 
| 
      
 141 
     | 
    
         
            +
                    def sequel_auto_param_type(ds)
         
     | 
| 
      
 142 
     | 
    
         
            +
                      if db_type && all?{|v| nil == v || ds.send(:auto_param_type, v)}
         
     | 
| 
      
 143 
     | 
    
         
            +
                        s = String.new << "::"
         
     | 
| 
      
 144 
     | 
    
         
            +
                        ds.quote_schema_table_append(s, db_type)
         
     | 
| 
      
 145 
     | 
    
         
            +
                        s
         
     | 
| 
      
 146 
     | 
    
         
            +
                      end
         
     | 
| 
      
 147 
     | 
    
         
            +
                    end
         
     | 
| 
       139 
148 
     | 
    
         
             
                  end
         
     | 
| 
       140 
149 
     | 
    
         | 
| 
       141 
150 
     | 
    
         
             
                  # Class for row-valued/composite types that are treated as hashes.
         
     | 
| 
         @@ -208,6 +217,15 @@ module Sequel 
     | 
|
| 
       208 
217 
     | 
    
         
             
                        ds.quote_schema_table_append(sql, db_type)
         
     | 
| 
       209 
218 
     | 
    
         
             
                      end
         
     | 
| 
       210 
219 
     | 
    
         
             
                    end
         
     | 
| 
      
 220 
     | 
    
         
            +
             
     | 
| 
      
 221 
     | 
    
         
            +
                    # Allow automatic parameterization if all values support it.
         
     | 
| 
      
 222 
     | 
    
         
            +
                    def sequel_auto_param_type(ds)
         
     | 
| 
      
 223 
     | 
    
         
            +
                      if db_type && all?{|_,v| nil == v || ds.send(:auto_param_type, v)}
         
     | 
| 
      
 224 
     | 
    
         
            +
                        s = String.new << "::"
         
     | 
| 
      
 225 
     | 
    
         
            +
                        ds.quote_schema_table_append(s, db_type)
         
     | 
| 
      
 226 
     | 
    
         
            +
                        s
         
     | 
| 
      
 227 
     | 
    
         
            +
                      end
         
     | 
| 
      
 228 
     | 
    
         
            +
                    end
         
     | 
| 
       211 
229 
     | 
    
         
             
                  end
         
     | 
| 
       212 
230 
     | 
    
         | 
| 
       213 
231 
     | 
    
         
             
                  ROW_TYPE_CLASSES = [HashRow, ArrayRow].freeze
         
     | 
| 
         @@ -519,26 +537,9 @@ module Sequel 
     | 
|
| 
       519 
537 
     | 
    
         | 
| 
       520 
538 
     | 
    
         
             
                    private
         
     | 
| 
       521 
539 
     | 
    
         | 
| 
       522 
     | 
    
         
            -
                    # Format composite types used in bound variable arrays.
         
     | 
| 
       523 
     | 
    
         
            -
                    def bound_variable_array(arg)
         
     | 
| 
       524 
     | 
    
         
            -
                      case arg
         
     | 
| 
       525 
     | 
    
         
            -
                      when ArrayRow
         
     | 
| 
       526 
     | 
    
         
            -
                        "\"(#{arg.map{|v| bound_variable_array(v) if v}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
         
     | 
| 
       527 
     | 
    
         
            -
                      when HashRow
         
     | 
| 
       528 
     | 
    
         
            -
                        arg.check_columns!
         
     | 
| 
       529 
     | 
    
         
            -
                        "\"(#{arg.values_at(*arg.columns).map{|v| bound_variable_array(v) if v}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
         
     | 
| 
       530 
     | 
    
         
            -
                      else
         
     | 
| 
       531 
     | 
    
         
            -
                        super
         
     | 
| 
       532 
     | 
    
         
            -
                      end
         
     | 
| 
       533 
     | 
    
         
            -
                    end
         
     | 
| 
       534 
     | 
    
         
            -
             
     | 
| 
       535 
540 
     | 
    
         
             
                    # Make the column type detection handle registered row types.
         
     | 
| 
       536 
     | 
    
         
            -
                    def  
     | 
| 
       537 
     | 
    
         
            -
                       
     | 
| 
       538 
     | 
    
         
            -
                        type
         
     | 
| 
       539 
     | 
    
         
            -
                      else
         
     | 
| 
       540 
     | 
    
         
            -
                        super
         
     | 
| 
       541 
     | 
    
         
            -
                      end
         
     | 
| 
      
 541 
     | 
    
         
            +
                    def schema_composite_type(db_type)
         
     | 
| 
      
 542 
     | 
    
         
            +
                      @row_schema_types[db_type] || super
         
     | 
| 
       542 
543 
     | 
    
         
             
                    end
         
     | 
| 
       543 
544 
     | 
    
         
             
                  end
         
     | 
| 
       544 
545 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,20 +1,35 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen-string-literal: true
         
     | 
| 
       2 
2 
     | 
    
         
             
            #
         
     | 
| 
       3 
3 
     | 
    
         
             
            # The pg_timestamptz extension changes the default timestamp
         
     | 
| 
       4 
     | 
    
         
            -
            # type for the database to be +timestamptz+ ( 
     | 
| 
       5 
     | 
    
         
            -
            # instead of +timestamp+ ( 
     | 
| 
      
 4 
     | 
    
         
            +
            # type for the database to be +timestamptz+ (<tt>timestamp with time zone</tt>)
         
     | 
| 
      
 5 
     | 
    
         
            +
            # instead of +timestamp+ (<tt>timestamp without time zone</tt>).  This is
         
     | 
| 
       6 
6 
     | 
    
         
             
            # recommended if you are dealing with multiple timezones in your application.
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # If you are using the auto_cast_date_and_time extension, the pg_timestamptz
         
     | 
| 
      
 9 
     | 
    
         
            +
            # extension will automatically cast Time and DateTime values to
         
     | 
| 
      
 10 
     | 
    
         
            +
            # <tt>TIMESTAMP WITH TIME ZONE</tt> instead of +TIMESTAMP+.
         
     | 
| 
       7 
11 
     | 
    
         
             
            # 
         
     | 
| 
       8 
12 
     | 
    
         
             
            # To load the extension into the database:
         
     | 
| 
       9 
13 
     | 
    
         
             
            #
         
     | 
| 
       10 
14 
     | 
    
         
             
            #   DB.extension :pg_timestamptz
         
     | 
| 
       11 
15 
     | 
    
         
             
            #
         
     | 
| 
       12 
     | 
    
         
            -
            #  
     | 
| 
      
 16 
     | 
    
         
            +
            # To load the extension into individual datasets:
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            #   ds = ds.extension(:pg_timestamptz)
         
     | 
| 
      
 19 
     | 
    
         
            +
            #
         
     | 
| 
      
 20 
     | 
    
         
            +
            # Note that the loading into individual datasets only affects the integration
         
     | 
| 
      
 21 
     | 
    
         
            +
            # with the auto_cast_date_and_time extension.
         
     | 
| 
      
 22 
     | 
    
         
            +
            #
         
     | 
| 
      
 23 
     | 
    
         
            +
            # Related modules: Sequel::Postgres::Timestamptz, Sequel::Postgres::TimestamptzDatasetMethods
         
     | 
| 
       13 
24 
     | 
    
         | 
| 
       14 
25 
     | 
    
         
             
            #
         
     | 
| 
       15 
26 
     | 
    
         
             
            module Sequel
         
     | 
| 
       16 
27 
     | 
    
         
             
              module Postgres
         
     | 
| 
       17 
28 
     | 
    
         
             
                module Timestamptz
         
     | 
| 
      
 29 
     | 
    
         
            +
                  def self.extended(db)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    db.extend_datasets(TimestamptzDatasetMethods)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       18 
33 
     | 
    
         
             
                  private
         
     | 
| 
       19 
34 
     | 
    
         | 
| 
       20 
35 
     | 
    
         
             
                  # Use timestamptz by default for generic timestamp value.
         
     | 
| 
         @@ -22,7 +37,16 @@ module Sequel 
     | 
|
| 
       22 
37 
     | 
    
         
             
                    :timestamptz
         
     | 
| 
       23 
38 
     | 
    
         
             
                  end
         
     | 
| 
       24 
39 
     | 
    
         
             
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                module TimestamptzDatasetMethods
         
     | 
| 
      
 42 
     | 
    
         
            +
                  private
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  def literal_datetime_timestamp_cast
         
     | 
| 
      
 45 
     | 
    
         
            +
                    'TIMESTAMP WITH TIME ZONE '
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
       25 
48 
     | 
    
         
             
              end
         
     | 
| 
       26 
49 
     | 
    
         | 
| 
      
 50 
     | 
    
         
            +
              Dataset.register_extension(:pg_timestamptz, Postgres::TimestamptzDatasetMethods)
         
     | 
| 
       27 
51 
     | 
    
         
             
              Database.register_extension(:pg_timestamptz, Postgres::Timestamptz)
         
     | 
| 
       28 
52 
     | 
    
         
             
            end
         
     | 
    
        data/lib/sequel/extensions/s.rb
    CHANGED
    
    
| 
         @@ -6,6 +6,17 @@ 
     | 
|
| 
       6 
6 
     | 
    
         
             
            # the current database).  The main interface is through
         
     | 
| 
       7 
7 
     | 
    
         
             
            # Sequel::Database#dump_schema_migration.
         
     | 
| 
       8 
8 
     | 
    
         
             
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            # The schema_dumper extension is quite limited in what types of
         
     | 
| 
      
 10 
     | 
    
         
            +
            # database objects it supports.  In general, it only supports
         
     | 
| 
      
 11 
     | 
    
         
            +
            # dumping tables, columns, primary key and foreign key constraints,
         
     | 
| 
      
 12 
     | 
    
         
            +
            # and some indexes.  It does not support most table options, CHECK
         
     | 
| 
      
 13 
     | 
    
         
            +
            # constraints, partial indexes, database functions, triggers,
         
     | 
| 
      
 14 
     | 
    
         
            +
            # security grants/revokes, and a wide variety of other useful
         
     | 
| 
      
 15 
     | 
    
         
            +
            # database properties.  Be aware of the limitations when using the
         
     | 
| 
      
 16 
     | 
    
         
            +
            # schema_dumper extension. If you are dumping the schema to restore
         
     | 
| 
      
 17 
     | 
    
         
            +
            # to the same database type, it is recommended to use your database's
         
     | 
| 
      
 18 
     | 
    
         
            +
            # dump and restore programs instead of the schema_dumper extension.
         
     | 
| 
      
 19 
     | 
    
         
            +
            #
         
     | 
| 
       9 
20 
     | 
    
         
             
            # To load the extension:
         
     | 
| 
       10 
21 
     | 
    
         
             
            #
         
     | 
| 
       11 
22 
     | 
    
         
             
            #   DB.extension :schema_dumper
         
     | 
| 
         @@ -77,11 +88,11 @@ module Sequel 
     | 
|
| 
       77 
88 
     | 
    
         
             
                # Note that the migration this produces does not have a down
         
     | 
| 
       78 
89 
     | 
    
         
             
                # block, so you cannot reverse it.
         
     | 
| 
       79 
90 
     | 
    
         
             
                def dump_foreign_key_migration(options=OPTS)
         
     | 
| 
       80 
     | 
    
         
            -
                  ts =  
     | 
| 
      
 91 
     | 
    
         
            +
                  ts = _dump_tables(options)
         
     | 
| 
       81 
92 
     | 
    
         
             
                  <<END_MIG
         
     | 
| 
       82 
93 
     | 
    
         
             
            Sequel.migration do
         
     | 
| 
       83 
94 
     | 
    
         
             
              change do
         
     | 
| 
       84 
     | 
    
         
            -
            #{ts. 
     | 
| 
      
 95 
     | 
    
         
            +
            #{ts.map{|t| dump_table_foreign_keys(t)}.reject{|x| x == ''}.join("\n\n").gsub(/^/, '    ')}
         
     | 
| 
       85 
96 
     | 
    
         
             
              end
         
     | 
| 
       86 
97 
     | 
    
         
             
            end
         
     | 
| 
       87 
98 
     | 
    
         
             
            END_MIG
         
     | 
| 
         @@ -95,11 +106,11 @@ END_MIG 
     | 
|
| 
       95 
106 
     | 
    
         
             
                #                 set to :namespace, prepend the table name to the index name if the
         
     | 
| 
       96 
107 
     | 
    
         
             
                #                 database does not use a global index namespace.
         
     | 
| 
       97 
108 
     | 
    
         
             
                def dump_indexes_migration(options=OPTS)
         
     | 
| 
       98 
     | 
    
         
            -
                  ts =  
     | 
| 
      
 109 
     | 
    
         
            +
                  ts = _dump_tables(options)
         
     | 
| 
       99 
110 
     | 
    
         
             
                  <<END_MIG
         
     | 
| 
       100 
111 
     | 
    
         
             
            Sequel.migration do
         
     | 
| 
       101 
112 
     | 
    
         
             
              change do
         
     | 
| 
       102 
     | 
    
         
            -
            #{ts. 
     | 
| 
      
 113 
     | 
    
         
            +
            #{ts.map{|t| dump_table_indexes(t, :add_index, options)}.reject{|x| x == ''}.join("\n\n").gsub(/^/, '    ')}
         
     | 
| 
       103 
114 
     | 
    
         
             
              end
         
     | 
| 
       104 
115 
     | 
    
         
             
            end
         
     | 
| 
       105 
116 
     | 
    
         
             
            END_MIG
         
     | 
| 
         @@ -127,7 +138,7 @@ END_MIG 
     | 
|
| 
       127 
138 
     | 
    
         
             
                    options[:foreign_keys] = false
         
     | 
| 
       128 
139 
     | 
    
         
             
                  end
         
     | 
| 
       129 
140 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                  ts = sort_dumped_tables( 
     | 
| 
      
 141 
     | 
    
         
            +
                  ts = sort_dumped_tables(_dump_tables(options), options)
         
     | 
| 
       131 
142 
     | 
    
         
             
                  skipped_fks = if sfk = options[:skipped_foreign_keys]
         
     | 
| 
       132 
143 
     | 
    
         
             
                    # Handle skipped foreign keys by adding them at the end via
         
     | 
| 
       133 
144 
     | 
    
         
             
                    # alter_table/add_foreign_key.  Note that skipped foreign keys
         
     | 
| 
         @@ -155,6 +166,21 @@ END_MIG 
     | 
|
| 
       155 
166 
     | 
    
         | 
| 
       156 
167 
     | 
    
         
             
                private
         
     | 
| 
       157 
168 
     | 
    
         | 
| 
      
 169 
     | 
    
         
            +
                # Handle schema option to dump tables in a different schema. Such
         
     | 
| 
      
 170 
     | 
    
         
            +
                # tables must be schema qualified for this to work correctly.
         
     | 
| 
      
 171 
     | 
    
         
            +
                def _dump_tables(opts)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  if opts[:schema]
         
     | 
| 
      
 173 
     | 
    
         
            +
                    _literal_table_sort(tables(opts.merge(:qualify=>true)))
         
     | 
| 
      
 174 
     | 
    
         
            +
                  else
         
     | 
| 
      
 175 
     | 
    
         
            +
                    tables(opts).sort
         
     | 
| 
      
 176 
     | 
    
         
            +
                  end
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                # Sort the given table by the literalized value.
         
     | 
| 
      
 180 
     | 
    
         
            +
                def _literal_table_sort(tables)
         
     | 
| 
      
 181 
     | 
    
         
            +
                  tables.sort_by{|s| literal(s)}
         
     | 
| 
      
 182 
     | 
    
         
            +
                end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
       158 
184 
     | 
    
         
             
                # If a database default exists and can't be converted, and we are dumping with :same_db,
         
     | 
| 
       159 
185 
     | 
    
         
             
                # return a string with the inspect method modified a literal string is created if the code is evaled.  
         
     | 
| 
       160 
186 
     | 
    
         
             
                def column_schema_to_ruby_default_fallback(default, options)
         
     | 
| 
         @@ -172,7 +198,7 @@ END_MIG 
     | 
|
| 
       172 
198 
     | 
    
         
             
                  if options[:single_pk] && schema_autoincrementing_primary_key?(schema)
         
     | 
| 
       173 
199 
     | 
    
         
             
                    type_hash = options[:same_db] ? {:type=>schema[:db_type]} : column_schema_to_ruby_type(schema)
         
     | 
| 
       174 
200 
     | 
    
         
             
                    [:table, :key, :on_delete, :on_update, :deferrable].each{|f| type_hash[f] = schema[f] if schema[f]}
         
     | 
| 
       175 
     | 
    
         
            -
                    if type_hash == {:type=>Integer} || type_hash == {:type=>"integer"}
         
     | 
| 
      
 201 
     | 
    
         
            +
                    if type_hash == {:type=>Integer} || type_hash == {:type=>"integer"} || type_hash == {:type=>"INTEGER"}
         
     | 
| 
       176 
202 
     | 
    
         
             
                      type_hash.delete(:type)
         
     | 
| 
       177 
203 
     | 
    
         
             
                    elsif options[:same_db] && type_hash == {:type=>type_literal_generic_bignum_symbol(type_hash).to_s}
         
     | 
| 
       178 
204 
     | 
    
         
             
                      type_hash[:type] = :Bignum
         
     | 
| 
         @@ -193,12 +219,20 @@ END_MIG 
     | 
|
| 
       193 
219 
     | 
    
         
             
                      if database_type == :mysql && h[:type] =~ /\Atimestamp/
         
     | 
| 
       194 
220 
     | 
    
         
             
                        h[:null] = true
         
     | 
| 
       195 
221 
     | 
    
         
             
                      end
         
     | 
| 
      
 222 
     | 
    
         
            +
                      if database_type == :mssql && schema[:max_length]
         
     | 
| 
      
 223 
     | 
    
         
            +
                        h[:size] = schema[:max_length]
         
     | 
| 
      
 224 
     | 
    
         
            +
                      end
         
     | 
| 
       196 
225 
     | 
    
         
             
                      h
         
     | 
| 
       197 
226 
     | 
    
         
             
                    else
         
     | 
| 
       198 
227 
     | 
    
         
             
                      column_schema_to_ruby_type(schema)
         
     | 
| 
       199 
228 
     | 
    
         
             
                    end
         
     | 
| 
       200 
229 
     | 
    
         
             
                    type = col_opts.delete(:type)
         
     | 
| 
       201 
     | 
    
         
            -
                    col_opts. 
     | 
| 
      
 230 
     | 
    
         
            +
                    if col_opts.key?(:size) && col_opts[:size].nil?
         
     | 
| 
      
 231 
     | 
    
         
            +
                      col_opts.delete(:size)
         
     | 
| 
      
 232 
     | 
    
         
            +
                      if max_length = schema[:max_length]
         
     | 
| 
      
 233 
     | 
    
         
            +
                        col_opts[:size] = max_length
         
     | 
| 
      
 234 
     | 
    
         
            +
                      end
         
     | 
| 
      
 235 
     | 
    
         
            +
                    end
         
     | 
| 
       202 
236 
     | 
    
         
             
                    if schema[:generated]
         
     | 
| 
       203 
237 
     | 
    
         
             
                      if options[:same_db] && database_type == :postgres
         
     | 
| 
       204 
238 
     | 
    
         
             
                        col_opts[:generated_always_as] = column_schema_to_ruby_default_fallback(schema[:default], options)
         
     | 
| 
         @@ -214,7 +248,7 @@ END_MIG 
     | 
|
| 
       214 
248 
     | 
    
         
             
                    col_opts[:null] = false if schema[:allow_null] == false
         
     | 
| 
       215 
249 
     | 
    
         
             
                    if table = schema[:table]
         
     | 
| 
       216 
250 
     | 
    
         
             
                      [:key, :on_delete, :on_update, :deferrable].each{|f| col_opts[f] = schema[f] if schema[f]}
         
     | 
| 
       217 
     | 
    
         
            -
                      col_opts[:type] = type unless type == Integer || type == 'integer'
         
     | 
| 
      
 251 
     | 
    
         
            +
                      col_opts[:type] = type unless type == Integer || type == 'integer' || type == 'INTEGER'
         
     | 
| 
       218 
252 
     | 
    
         
             
                      gen.foreign_key(name, table, col_opts)
         
     | 
| 
       219 
253 
     | 
    
         
             
                    else
         
     | 
| 
       220 
254 
     | 
    
         
             
                      gen.column(name, type, col_opts)
         
     | 
| 
         @@ -341,7 +375,7 @@ END_MIG 
     | 
|
| 
       341 
375 
     | 
    
         
             
                    options[:skipped_foreign_keys] = skipped_foreign_keys
         
     | 
| 
       342 
376 
     | 
    
         
             
                    tables
         
     | 
| 
       343 
377 
     | 
    
         
             
                  else
         
     | 
| 
       344 
     | 
    
         
            -
                    tables 
     | 
| 
      
 378 
     | 
    
         
            +
                    tables
         
     | 
| 
       345 
379 
     | 
    
         
             
                  end
         
     | 
| 
       346 
380 
     | 
    
         
             
                end
         
     | 
| 
       347 
381 
     | 
    
         | 
| 
         @@ -366,14 +400,14 @@ END_MIG 
     | 
|
| 
       366 
400 
     | 
    
         
             
                      # outstanding foreign keys and skipping those foreign keys.
         
     | 
| 
       367 
401 
     | 
    
         
             
                      # The skipped foreign keys will be added at the end of the
         
     | 
| 
       368 
402 
     | 
    
         
             
                      # migration.
         
     | 
| 
       369 
     | 
    
         
            -
                      skip_table, skip_fks = table_fks.sort_by{|table, fks| [fks.length, table]}.first
         
     | 
| 
      
 403 
     | 
    
         
            +
                      skip_table, skip_fks = table_fks.sort_by{|table, fks| [fks.length, literal(table)]}.first
         
     | 
| 
       370 
404 
     | 
    
         
             
                      skip_fks_hash = skipped_foreign_keys[skip_table] = {}
         
     | 
| 
       371 
405 
     | 
    
         
             
                      skip_fks.each{|fk| skip_fks_hash[fk[:columns]] = fk}
         
     | 
| 
       372 
406 
     | 
    
         
             
                      this_loop << skip_table
         
     | 
| 
       373 
407 
     | 
    
         
             
                    end
         
     | 
| 
       374 
408 
     | 
    
         | 
| 
       375 
409 
     | 
    
         
             
                    # Add sorted tables from this loop to the final list
         
     | 
| 
       376 
     | 
    
         
            -
                    sorted_tables.concat(this_loop 
     | 
| 
      
 410 
     | 
    
         
            +
                    sorted_tables.concat(_literal_table_sort(this_loop))
         
     | 
| 
       377 
411 
     | 
    
         | 
| 
       378 
412 
     | 
    
         
             
                    # Remove tables that were handled this loop
         
     | 
| 
       379 
413 
     | 
    
         
             
                    this_loop.each{|t| table_fks.delete(t)}
         
     | 
| 
         @@ -69,7 +69,8 @@ module Sequel 
     | 
|
| 
       69 
69 
     | 
    
         
             
                # Also defines the with_server method on the receiver for easy use.
         
     | 
| 
       70 
70 
     | 
    
         
             
                def self.extended(db)
         
     | 
| 
       71 
71 
     | 
    
         
             
                  pool = db.pool
         
     | 
| 
       72 
     | 
    
         
            -
                   
     | 
| 
      
 72 
     | 
    
         
            +
                  case pool.pool_type
         
     | 
| 
      
 73 
     | 
    
         
            +
                  when :sharded_threaded, :sharded_timed_queue
         
     | 
| 
       73 
74 
     | 
    
         
             
                    pool.extend(ThreadedServerBlock)
         
     | 
| 
       74 
75 
     | 
    
         
             
                    pool.instance_variable_set(:@default_servers, {})
         
     | 
| 
       75 
76 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -88,12 +89,10 @@ module Sequel 
     | 
|
| 
       88 
89 
     | 
    
         
             
              module UnthreadedServerBlock
         
     | 
| 
       89 
90 
     | 
    
         
             
                # Set a default server/shard to use inside the block.
         
     | 
| 
       90 
91 
     | 
    
         
             
                def with_server(default_server, read_only_server=default_server)
         
     | 
| 
       91 
     | 
    
         
            -
                   
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
                   
     | 
| 
       95 
     | 
    
         
            -
                    clear_default_server
         
     | 
| 
       96 
     | 
    
         
            -
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
                  set_default_server(default_server, read_only_server)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  yield
         
     | 
| 
      
 94 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 95 
     | 
    
         
            +
                  clear_default_server
         
     | 
| 
       97 
96 
     | 
    
         
             
                end
         
     | 
| 
       98 
97 
     | 
    
         | 
| 
       99 
98 
     | 
    
         
             
                private
         
     | 
| 
         @@ -131,12 +130,10 @@ module Sequel 
     | 
|
| 
       131 
130 
     | 
    
         
             
                # Set a default server/shard to use inside the block for the current
         
     | 
| 
       132 
131 
     | 
    
         
             
                # thread.
         
     | 
| 
       133 
132 
     | 
    
         
             
                def with_server(default_server, read_only_server=default_server)
         
     | 
| 
       134 
     | 
    
         
            -
                   
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
                   
     | 
| 
       138 
     | 
    
         
            -
                    clear_default_server
         
     | 
| 
       139 
     | 
    
         
            -
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
                  set_default_server(default_server, read_only_server)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  yield
         
     | 
| 
      
 135 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 136 
     | 
    
         
            +
                  clear_default_server
         
     | 
| 
       140 
137 
     | 
    
         
             
                end
         
     | 
| 
       141 
138 
     | 
    
         | 
| 
       142 
139 
     | 
    
         
             
                private
         
     | 
| 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen-string-literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # The set_literalizer extension allows for using Set instances in many of the
         
     | 
| 
      
 4 
     | 
    
         
            +
            # same places that you would use Array instances:
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            #   DB[:table].where(column: Set.new([1, 2, 3]))
         
     | 
| 
      
 7 
     | 
    
         
            +
            #   # SELECT FROM table WHERE (column IN (1, 2, 3))
         
     | 
| 
      
 8 
     | 
    
         
            +
            #
         
     | 
| 
      
 9 
     | 
    
         
            +
            # To load the extension into all datasets created from a given Database:
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            #   DB.extension :set_literalizer
         
     | 
| 
      
 12 
     | 
    
         
            +
            #
         
     | 
| 
      
 13 
     | 
    
         
            +
            # Related module: Sequel::Dataset::SetLiteralizer
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            require 'set'
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            module Sequel
         
     | 
| 
      
 18 
     | 
    
         
            +
              class Dataset
         
     | 
| 
      
 19 
     | 
    
         
            +
                module SetLiteralizer
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # Try to generate the same SQL for Set instances used in datasets
         
     | 
| 
      
 21 
     | 
    
         
            +
                  # that would be used for equivalent Array instances.
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def complex_expression_sql_append(sql, op, args)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    # Array instances are treated specially by
         
     | 
| 
      
 24 
     | 
    
         
            +
                    # Sequel::SQL::BooleanExpression.from_value_pairs. That cannot
         
     | 
| 
      
 25 
     | 
    
         
            +
                    # be modified by a dataset extension, so this tries to convert
         
     | 
| 
      
 26 
     | 
    
         
            +
                    # the complex expression values generated by default to what would
         
     | 
| 
      
 27 
     | 
    
         
            +
                    # be the complex expression values used for the equivalent array.
         
     | 
| 
      
 28 
     | 
    
         
            +
                    case op
         
     | 
| 
      
 29 
     | 
    
         
            +
                    when :'=', :'!='
         
     | 
| 
      
 30 
     | 
    
         
            +
                      if (set = args[1]).is_a?(Set)
         
     | 
| 
      
 31 
     | 
    
         
            +
                        op = op == :'=' ? :IN : :'NOT IN'
         
     | 
| 
      
 32 
     | 
    
         
            +
                        col = args[0]
         
     | 
| 
      
 33 
     | 
    
         
            +
                        array = set.to_a
         
     | 
| 
      
 34 
     | 
    
         
            +
                        if Sequel.condition_specifier?(array) && col.is_a?(Array)
         
     | 
| 
      
 35 
     | 
    
         
            +
                          array = Sequel.value_list(array)
         
     | 
| 
      
 36 
     | 
    
         
            +
                        end
         
     | 
| 
      
 37 
     | 
    
         
            +
                        args = [col, array]
         
     | 
| 
      
 38 
     | 
    
         
            +
                      end
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    super
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  private
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  # Literalize Set instances by converting the set to array.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  def literal_other_append(sql, v)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    if Set === v
         
     | 
| 
      
 49 
     | 
    
         
            +
                      literal_append(sql, v.to_a) 
         
     | 
| 
      
 50 
     | 
    
         
            +
                    else
         
     | 
| 
      
 51 
     | 
    
         
            +
                      super
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                register_extension(:set_literalizer, SetLiteralizer)
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -44,11 +44,51 @@ 
     | 
|
| 
       44 
44 
     | 
    
         
             
            #
         
     | 
| 
       45 
45 
     | 
    
         
             
            #   DB.extension(:sql_comments)
         
     | 
| 
       46 
46 
     | 
    
         
             
            #
         
     | 
| 
      
 47 
     | 
    
         
            +
            # Loading the sql_comments extension into the database also adds 
         
     | 
| 
      
 48 
     | 
    
         
            +
            # support for block-level comment support via Database#with_comments.
         
     | 
| 
      
 49 
     | 
    
         
            +
            # You call #with_comments with a hash.  Queries inside the hash will
         
     | 
| 
      
 50 
     | 
    
         
            +
            # include a comment based on the hash (assuming they are inside the
         
     | 
| 
      
 51 
     | 
    
         
            +
            # same thread):
         
     | 
| 
      
 52 
     | 
    
         
            +
            #
         
     | 
| 
      
 53 
     | 
    
         
            +
            #   DB.with_comments(model: Album, action: :all) do
         
     | 
| 
      
 54 
     | 
    
         
            +
            #     DB[:albums].all
         
     | 
| 
      
 55 
     | 
    
         
            +
            #     # SELECT * FROM albums -- model:Album,action:all
         
     | 
| 
      
 56 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 57 
     | 
    
         
            +
            #
         
     | 
| 
      
 58 
     | 
    
         
            +
            # You can nest calls to #with_comments, which will combine the
         
     | 
| 
      
 59 
     | 
    
         
            +
            # entries from both calls:
         
     | 
| 
      
 60 
     | 
    
         
            +
            #
         
     | 
| 
      
 61 
     | 
    
         
            +
            #   DB.with_comments(application: App, path: :scrubbed_path) do
         
     | 
| 
      
 62 
     | 
    
         
            +
            #     DB.with_comments(model: Album, action: :all) do
         
     | 
| 
      
 63 
     | 
    
         
            +
            #       ds = DB[:albums].all
         
     | 
| 
      
 64 
     | 
    
         
            +
            #       # SELECT * FROM albums
         
     | 
| 
      
 65 
     | 
    
         
            +
            #       # -- application:App,path:scrubbed_path,model:Album,action:all
         
     | 
| 
      
 66 
     | 
    
         
            +
            #     end
         
     | 
| 
      
 67 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 68 
     | 
    
         
            +
            #
         
     | 
| 
      
 69 
     | 
    
         
            +
            # You can override comment entries specified in earlier blocks, or
         
     | 
| 
      
 70 
     | 
    
         
            +
            # remove entries specified earlier using a nil value:
         
     | 
| 
      
 71 
     | 
    
         
            +
            #
         
     | 
| 
      
 72 
     | 
    
         
            +
            #   DB.with_comments(application: App, path: :scrubbed_path) do
         
     | 
| 
      
 73 
     | 
    
         
            +
            #     DB.with_comments(application: Foo, path: nil) do
         
     | 
| 
      
 74 
     | 
    
         
            +
            #       ds = DB[:albums].all
         
     | 
| 
      
 75 
     | 
    
         
            +
            #       # SELECT * FROM albums # -- application:Foo
         
     | 
| 
      
 76 
     | 
    
         
            +
            #     end
         
     | 
| 
      
 77 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 78 
     | 
    
         
            +
            #
         
     | 
| 
      
 79 
     | 
    
         
            +
            # You can combine block-level comments with dataset-specific
         
     | 
| 
      
 80 
     | 
    
         
            +
            # comments:
         
     | 
| 
      
 81 
     | 
    
         
            +
            #
         
     | 
| 
      
 82 
     | 
    
         
            +
            #   DB.with_comments(model: Album, action: :all) do
         
     | 
| 
      
 83 
     | 
    
         
            +
            #     DB[:table].comment("Some Comment").all
         
     | 
| 
      
 84 
     | 
    
         
            +
            #     # SELECT * FROM albums -- model:Album,action:all -- Some Comment
         
     | 
| 
      
 85 
     | 
    
         
            +
            #   end
         
     | 
| 
      
 86 
     | 
    
         
            +
            #
         
     | 
| 
       47 
87 
     | 
    
         
             
            # Note that Microsoft Access does not support inline comments,
         
     | 
| 
       48 
88 
     | 
    
         
             
            # and attempting to use comments on it will result in SQL syntax
         
     | 
| 
       49 
89 
     | 
    
         
             
            # errors.
         
     | 
| 
       50 
90 
     | 
    
         
             
            #
         
     | 
| 
       51 
     | 
    
         
            -
            # Related  
     | 
| 
      
 91 
     | 
    
         
            +
            # Related modules: Sequel::SQLComments, Sequel::Database::SQLComments
         
     | 
| 
       52 
92 
     | 
    
         | 
| 
       53 
93 
     | 
    
         
             
            #
         
     | 
| 
       54 
94 
     | 
    
         
             
            module Sequel
         
     | 
| 
         @@ -62,7 +102,7 @@ module Sequel 
     | 
|
| 
       62 
102 
     | 
    
         
             
                %w'select insert update delete'.each do |type|
         
     | 
| 
       63 
103 
     | 
    
         
             
                  define_method(:"#{type}_sql") do |*a|
         
     | 
| 
       64 
104 
     | 
    
         
             
                    sql = super(*a)
         
     | 
| 
       65 
     | 
    
         
            -
                    if comment =  
     | 
| 
      
 105 
     | 
    
         
            +
                    if comment = _sql_comment
         
     | 
| 
       66 
106 
     | 
    
         
             
                      # This assumes that the comment stored in the dataset has
         
     | 
| 
       67 
107 
     | 
    
         
             
                      # already been formatted. If not, this could result in SQL
         
     | 
| 
       68 
108 
     | 
    
         
             
                      # injection.
         
     | 
| 
         @@ -74,8 +114,10 @@ module Sequel 
     | 
|
| 
       74 
114 
     | 
    
         
             
                      if sql.frozen?
         
     | 
| 
       75 
115 
     | 
    
         
             
                        sql += comment
         
     | 
| 
       76 
116 
     | 
    
         
             
                        sql.freeze
         
     | 
| 
       77 
     | 
    
         
            -
                       
     | 
| 
      
 117 
     | 
    
         
            +
                      elsif @opts[:append_sql] || @opts[:placeholder_literalizer]
         
     | 
| 
       78 
118 
     | 
    
         
             
                        sql << comment
         
     | 
| 
      
 119 
     | 
    
         
            +
                      else
         
     | 
| 
      
 120 
     | 
    
         
            +
                        sql += comment
         
     | 
| 
       79 
121 
     | 
    
         
             
                      end
         
     | 
| 
       80 
122 
     | 
    
         
             
                    end
         
     | 
| 
       81 
123 
     | 
    
         
             
                    sql
         
     | 
| 
         @@ -84,6 +126,11 @@ module Sequel 
     | 
|
| 
       84 
126 
     | 
    
         | 
| 
       85 
127 
     | 
    
         
             
                private
         
     | 
| 
       86 
128 
     | 
    
         | 
| 
      
 129 
     | 
    
         
            +
                # The comment to include in the SQL query, if any.
         
     | 
| 
      
 130 
     | 
    
         
            +
                def _sql_comment
         
     | 
| 
      
 131 
     | 
    
         
            +
                  @opts[:comment]
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
       87 
134 
     | 
    
         
             
                # Format the comment.  For maximum compatibility, this uses a
         
     | 
| 
       88 
135 
     | 
    
         
             
                # single line SQL comment, and converts all consecutive whitespace
         
     | 
| 
       89 
136 
     | 
    
         
             
                # in the comment to a single space.
         
     | 
| 
         @@ -92,5 +139,65 @@ module Sequel 
     | 
|
| 
       92 
139 
     | 
    
         
             
                end
         
     | 
| 
       93 
140 
     | 
    
         
             
              end
         
     | 
| 
       94 
141 
     | 
    
         | 
| 
      
 142 
     | 
    
         
            +
              module Database::SQLComments
         
     | 
| 
      
 143 
     | 
    
         
            +
                def self.extended(db)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  db.instance_variable_set(:@comment_hashes, {})
         
     | 
| 
      
 145 
     | 
    
         
            +
                  db.extend_datasets DatasetSQLComments
         
     | 
| 
      
 146 
     | 
    
         
            +
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                # A map of threads to comment hashes, used for correctly setting
         
     | 
| 
      
 149 
     | 
    
         
            +
                # comments for all queries inside #with_comments blocks.
         
     | 
| 
      
 150 
     | 
    
         
            +
                attr_reader :comment_hashes
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                # Store the comment hash and use it to create comments inside the block
         
     | 
| 
      
 153 
     | 
    
         
            +
                def with_comments(comment_hash)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  hashes = @comment_hashes
         
     | 
| 
      
 155 
     | 
    
         
            +
                  t = Sequel.current
         
     | 
| 
      
 156 
     | 
    
         
            +
                  new_hash = if hash = Sequel.synchronize{hashes[t]}
         
     | 
| 
      
 157 
     | 
    
         
            +
                    hash.merge(comment_hash)
         
     | 
| 
      
 158 
     | 
    
         
            +
                  else
         
     | 
| 
      
 159 
     | 
    
         
            +
                    comment_hash.dup
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
                  yield Sequel.synchronize{hashes[t] = new_hash}
         
     | 
| 
      
 162 
     | 
    
         
            +
                ensure
         
     | 
| 
      
 163 
     | 
    
         
            +
                  if hash
         
     | 
| 
      
 164 
     | 
    
         
            +
                    Sequel.synchronize{hashes[t] = hash}
         
     | 
| 
      
 165 
     | 
    
         
            +
                  else
         
     | 
| 
      
 166 
     | 
    
         
            +
                    t && Sequel.synchronize{hashes.delete(t)}
         
     | 
| 
      
 167 
     | 
    
         
            +
                  end
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                module DatasetSQLComments
         
     | 
| 
      
 171 
     | 
    
         
            +
                  include Sequel::SQLComments
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                  private
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                  # Include comments added via Database#with_comments in the output SQL.
         
     | 
| 
      
 176 
     | 
    
         
            +
                  def _sql_comment
         
     | 
| 
      
 177 
     | 
    
         
            +
                    specific_comment = super
         
     | 
| 
      
 178 
     | 
    
         
            +
                    return specific_comment if @opts[:append_sql]
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                    t = Sequel.current
         
     | 
| 
      
 181 
     | 
    
         
            +
                    hashes = db.comment_hashes
         
     | 
| 
      
 182 
     | 
    
         
            +
                    block_comment = if comment_hash = Sequel.synchronize{hashes[t]}
         
     | 
| 
      
 183 
     | 
    
         
            +
                      comment_array = comment_hash.map{|k,v| "#{k}:#{v}" unless v.nil?}
         
     | 
| 
      
 184 
     | 
    
         
            +
                      comment_array.compact!
         
     | 
| 
      
 185 
     | 
    
         
            +
                      comment_array.join(",")
         
     | 
| 
      
 186 
     | 
    
         
            +
                    end
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                    if block_comment
         
     | 
| 
      
 189 
     | 
    
         
            +
                      if specific_comment
         
     | 
| 
      
 190 
     | 
    
         
            +
                        format_sql_comment(block_comment + specific_comment)
         
     | 
| 
      
 191 
     | 
    
         
            +
                      else
         
     | 
| 
      
 192 
     | 
    
         
            +
                        format_sql_comment(block_comment)
         
     | 
| 
      
 193 
     | 
    
         
            +
                      end
         
     | 
| 
      
 194 
     | 
    
         
            +
                    else
         
     | 
| 
      
 195 
     | 
    
         
            +
                      specific_comment
         
     | 
| 
      
 196 
     | 
    
         
            +
                    end
         
     | 
| 
      
 197 
     | 
    
         
            +
                  end
         
     | 
| 
      
 198 
     | 
    
         
            +
                end
         
     | 
| 
      
 199 
     | 
    
         
            +
              end
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
       95 
201 
     | 
    
         
             
              Dataset.register_extension(:sql_comments, SQLComments)
         
     | 
| 
      
 202 
     | 
    
         
            +
              Database.register_extension(:sql_comments, Database::SQLComments)
         
     | 
| 
       96 
203 
     | 
    
         
             
            end
         
     |