db_leftovers 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.html +11 -4
- data/README.md +10 -4
- data/VERSION +1 -1
- data/db_leftovers.gemspec +1 -1
- data/lib/db_leftovers/database_interface.rb +3 -2
- data/lib/db_leftovers/dsl.rb +44 -5
- data/lib/db_leftovers/table_dsl.rb +1 -1
- data/spec/db_leftovers_spec.rb +36 -0
- metadata +2 -2
    
        data/README.html
    CHANGED
    
    | @@ -31,11 +31,11 @@ index :books, [:publisher_id, :published_at] | |
| 31 31 | 
             
            index :books, :isbn, :unique => true
         | 
| 32 32 | 
             
            </code></pre>
         | 
| 33 33 |  | 
| 34 | 
            -
            <h3>foreign_key(from_table, from_column, to_table, [to_column, [opts] | 
| 34 | 
            +
            <h3>foreign_key(from_table, [from_column], to_table, [to_column], [opts])</h3>
         | 
| 35 35 |  | 
| 36 36 | 
             
            <p>This ensures that you have a foreign key relating the given tables and columns.
         | 
| 37 37 | 
             
            All parameters are strings/symbols except <code>opts</code>, which is a hash.
         | 
| 38 | 
            -
            If you  | 
| 38 | 
            +
            If you omit the column names, db_leftovers will infer them based on Rails conventions. (See examples below.)
         | 
| 39 39 | 
             
            The only option that is supported is <code>:on_delete</code>, which may have any of these values:</p>
         | 
| 40 40 |  | 
| 41 41 | 
             
            <ul>
         | 
| @@ -47,10 +47,17 @@ The only option that is supported is <code>:on_delete</code>, which may have any | |
| 47 47 | 
             
            <h4>Examples</h4>
         | 
| 48 48 |  | 
| 49 49 | 
             
            <pre><code>foreign_key :books, :author_id, :authors, :id
         | 
| 50 | 
            -
            foreign_key :books, :publisher_id, :publishers
         | 
| 51 50 | 
             
            foreign_key :pages, :book_id, :books, :id, :on_delete => :cascade
         | 
| 52 51 | 
             
            </code></pre>
         | 
| 53 52 |  | 
| 53 | 
            +
            <p>With implicit column names:</p>
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            <pre><code>foreign_key :books, :authors
         | 
| 56 | 
            +
            foreign_key :books, :authors, :on_delete => :cascade
         | 
| 57 | 
            +
            foreign_key :books, :co_author_id, :authors
         | 
| 58 | 
            +
            foreign_key :books, :co_author_id, :authors, :on_delete => :cascade
         | 
| 59 | 
            +
            </code></pre>
         | 
| 60 | 
            +
             | 
| 54 61 | 
             
            <h3>check(constraint_name, on_table, expression)</h3>
         | 
| 55 62 |  | 
| 56 63 | 
             
            <p>This ensures that you have a CHECK constraint on the given table with the given name and expression.
         | 
| @@ -63,7 +70,7 @@ All parameters are strings or symbols.</p> | |
| 63 70 |  | 
| 64 71 | 
             
            <h3>table(table_name, &block)</h3>
         | 
| 65 72 |  | 
| 66 | 
            -
            <p>The <code>table</code> call is just a convenience so you can group all a table's indexes  | 
| 73 | 
            +
            <p>The <code>table</code> call is just a convenience so you can group all a table's indexes etcetera together and not keep repeating the table name. You use it like this:</p>
         | 
| 67 74 |  | 
| 68 75 | 
             
            <pre><code>table :books do
         | 
| 69 76 | 
             
              index :author_id
         | 
    
        data/README.md
    CHANGED
    
    | @@ -32,11 +32,11 @@ This ensures that you have an index on the given table and column(s). The `colum | |
| 32 32 | 
             
                index :books, [:publisher_id, :published_at]
         | 
| 33 33 | 
             
                index :books, :isbn, :unique => true
         | 
| 34 34 |  | 
| 35 | 
            -
            ### foreign\_key(from\_table, from\_column, to\_table, [to\_column, [opts] | 
| 35 | 
            +
            ### foreign\_key(from\_table, [from\_column], to\_table, [to\_column], [opts])
         | 
| 36 36 |  | 
| 37 37 | 
             
            This ensures that you have a foreign key relating the given tables and columns.
         | 
| 38 38 | 
             
            All parameters are strings/symbols except `opts`, which is a hash.
         | 
| 39 | 
            -
            If you  | 
| 39 | 
            +
            If you omit the column names, db\_leftovers will infer them based on Rails conventions. (See examples below.)
         | 
| 40 40 | 
             
            The only option that is supported is `:on_delete`, which may have any of these values:
         | 
| 41 41 |  | 
| 42 42 | 
             
            * `nil` Indicates that attempting to delete the referenced row should fail (the default).
         | 
| @@ -46,9 +46,15 @@ The only option that is supported is `:on_delete`, which may have any of these v | |
| 46 46 | 
             
            #### Examples
         | 
| 47 47 |  | 
| 48 48 | 
             
                foreign_key :books, :author_id, :authors, :id
         | 
| 49 | 
            -
                foreign_key :books, :publisher_id, :publishers
         | 
| 50 49 | 
             
                foreign_key :pages, :book_id, :books, :id, :on_delete => :cascade
         | 
| 51 50 |  | 
| 51 | 
            +
            With implicit column names:
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                foreign_key :books, :authors
         | 
| 54 | 
            +
                foreign_key :books, :authors, :on_delete => :cascade
         | 
| 55 | 
            +
                foreign_key :books, :co_author_id, :authors
         | 
| 56 | 
            +
                foreign_key :books, :co_author_id, :authors, :on_delete => :cascade
         | 
| 57 | 
            +
             | 
| 52 58 | 
             
            ### check(constraint\_name, on\_table, expression)
         | 
| 53 59 |  | 
| 54 60 | 
             
            This ensures that you have a CHECK constraint on the given table with the given name and expression.
         | 
| @@ -60,7 +66,7 @@ All parameters are strings or symbols. | |
| 60 66 |  | 
| 61 67 | 
             
            ### table(table\_name, &block)
         | 
| 62 68 |  | 
| 63 | 
            -
            The `table` call is just a convenience so you can group all a table's indexes  | 
| 69 | 
            +
            The `table` call is just a convenience so you can group all a table's indexes etcetera together and not keep repeating the table name. You use it like this:
         | 
| 64 70 |  | 
| 65 71 | 
             
                table :books do
         | 
| 66 72 | 
             
                  index :author_id
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0. | 
| 1 | 
            +
            0.9.1
         | 
    
        data/db_leftovers.gemspec
    CHANGED
    
    
| @@ -101,7 +101,8 @@ module DBLeftovers | |
| 101 101 | 
             
                  ret = {}
         | 
| 102 102 | 
             
                  sql = <<-EOQ
         | 
| 103 103 | 
             
                      SELECT  c.conname,
         | 
| 104 | 
            -
                              t.relname
         | 
| 104 | 
            +
                              t.relname,
         | 
| 105 | 
            +
                              pg_get_expr(c.conbin, c.conrelid)
         | 
| 105 106 | 
             
                      FROM    pg_catalog.pg_constraint c,
         | 
| 106 107 | 
             
                              pg_catalog.pg_class t,
         | 
| 107 108 | 
             
                              pg_catalog.pg_namespace n
         | 
| @@ -182,7 +183,7 @@ module DBLeftovers | |
| 182 183 | 
             
                end
         | 
| 183 184 |  | 
| 184 185 | 
             
                def remove_outer_parens(str)
         | 
| 185 | 
            -
                  str.gsub(/^\((.*)\)$/, '\1')
         | 
| 186 | 
            +
                  str ? str.gsub(/^\((.*)\)$/, '\1') : nil
         | 
| 186 187 | 
             
                end
         | 
| 187 188 |  | 
| 188 189 |  | 
    
        data/lib/db_leftovers/dsl.rb
    CHANGED
    
    | @@ -38,7 +38,30 @@ module DBLeftovers | |
| 38 38 | 
             
                  add_index(Index.new(table_name, column_names, opts))
         | 
| 39 39 | 
             
                end
         | 
| 40 40 |  | 
| 41 | 
            -
                 | 
| 41 | 
            +
                # foreign_key(from_table, [from_column], to_table, [to_column], [opts]):
         | 
| 42 | 
            +
                #   foreign_key(:books, :publishers)                   -> foreign_key(:books, nil, :publishers, nil)
         | 
| 43 | 
            +
                #   foreign_key(:books, :co_author_id, :authors)       -> foreign_key(:books, :co_author_id, :authors, nil)
         | 
| 44 | 
            +
                #   foreign_key(:books, :publishers, opts)             -> foreign_key(:books, nil, :publishers, nil, opts)
         | 
| 45 | 
            +
                #   foreign_key(:books, :co_author_id, :authors, opts) -> foreign_key(:books, :co_author_id, :authors, nil, opts)
         | 
| 46 | 
            +
                def foreign_key(from_table, from_column=nil, to_table=nil, to_column=nil, opts={})
         | 
| 47 | 
            +
                  # First get the options hash into the right place:
         | 
| 48 | 
            +
                  if to_column.class == Hash
         | 
| 49 | 
            +
                    opts = to_column
         | 
| 50 | 
            +
                    to_column = nil
         | 
| 51 | 
            +
                  elsif to_table.class == Hash
         | 
| 52 | 
            +
                    opts = to_table
         | 
| 53 | 
            +
                    to_table = to_column = nil
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  # Sort out implicit arguments:
         | 
| 57 | 
            +
                  if from_column and not to_table and not to_column
         | 
| 58 | 
            +
                    to_table = from_column
         | 
| 59 | 
            +
                    from_column = "#{to_table.to_s.singularize}_id"
         | 
| 60 | 
            +
                    to_column = :id
         | 
| 61 | 
            +
                  elsif from_column and to_table and not to_column
         | 
| 62 | 
            +
                    to_column = :id
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
             | 
| 42 65 | 
             
                  add_foreign_key(ForeignKey.new(name_constraint(from_table, from_column), from_table, from_column, to_table, to_column, opts))
         | 
| 43 66 | 
             
                end
         | 
| 44 67 |  | 
| @@ -57,10 +80,22 @@ module DBLeftovers | |
| 57 80 | 
             
                      when STATUS_CHANGED
         | 
| 58 81 | 
             
                        @db.execute_drop_index(idx.table_name, idx.index_name)
         | 
| 59 82 | 
             
                        @db.execute_add_index(idx)
         | 
| 60 | 
            -
                         | 
| 83 | 
            +
                        if idx.where_clause
         | 
| 84 | 
            +
                          # NB: This is O(n*m) where n is your indexes and m is your indexes with WHERE clauses.
         | 
| 85 | 
            +
                          #     But it's hard to believe it matters:
         | 
| 86 | 
            +
                          new_idx = @db.lookup_all_indexes[truncate_index_name(idx.index_name)]
         | 
| 87 | 
            +
                          puts "Dropped & re-created index: #{idx.index_name} on #{idx.table_name} WHERE #{new_idx.where_clause}"
         | 
| 88 | 
            +
                        else
         | 
| 89 | 
            +
                          puts "Dropped & re-created index: #{idx.index_name} on #{idx.table_name}"
         | 
| 90 | 
            +
                        end
         | 
| 61 91 | 
             
                      when STATUS_NEW
         | 
| 62 92 | 
             
                        @db.execute_add_index(idx)
         | 
| 63 | 
            -
                         | 
| 93 | 
            +
                        if idx.where_clause
         | 
| 94 | 
            +
                          new_idx = @db.lookup_all_indexes[truncate_index_name(idx.index_name)]
         | 
| 95 | 
            +
                          puts "Created index: #{idx.index_name} on #{idx.table_name} WHERE #{new_idx.where_clause}"
         | 
| 96 | 
            +
                        else
         | 
| 97 | 
            +
                          puts "Created index: #{idx.index_name} on #{idx.table_name}"
         | 
| 98 | 
            +
                        end
         | 
| 64 99 | 
             
                      end
         | 
| 65 100 | 
             
                      @new_indexes[truncate_index_name(idx.index_name)] = table_name
         | 
| 66 101 | 
             
                    end
         | 
| @@ -114,10 +149,14 @@ module DBLeftovers | |
| 114 149 | 
             
                      when STATUS_CHANGED
         | 
| 115 150 | 
             
                        @db.execute_drop_constraint(chk.constraint_name, chk.on_table)
         | 
| 116 151 | 
             
                        @db.execute_add_constraint(chk)
         | 
| 117 | 
            -
                         | 
| 152 | 
            +
                        # NB: This is O(n^2) where n is your check constraints.
         | 
| 153 | 
            +
                        #     But it's hard to believe it matters:
         | 
| 154 | 
            +
                        new_chk = @db.lookup_all_constraints[chk.constraint_name]
         | 
| 155 | 
            +
                        puts "Dropped & re-created CHECK constraint: #{chk.constraint_name} on #{chk.on_table} as #{new_chk.check}"
         | 
| 118 156 | 
             
                      when STATUS_NEW
         | 
| 119 157 | 
             
                        @db.execute_add_constraint(chk)
         | 
| 120 | 
            -
                         | 
| 158 | 
            +
                        new_chk = @db.lookup_all_constraints[chk.constraint_name]
         | 
| 159 | 
            +
                        puts "Created CHECK constraint: #{chk.constraint_name} on #{chk.on_table} as #{new_chk.check}"
         | 
| 121 160 | 
             
                      end
         | 
| 122 161 | 
             
                      @new_constraints[chk.constraint_name] = chk
         | 
| 123 162 | 
             
                    end
         | 
| @@ -14,7 +14,7 @@ module DBLeftovers | |
| 14 14 | 
             
                  @dsl.index(@table_name, column_names, opts)
         | 
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 | 
            -
                def foreign_key(from_column, to_table, to_column= | 
| 17 | 
            +
                def foreign_key(from_column=nil, to_table=nil, to_column=nil, opts={})
         | 
| 18 18 | 
             
                  @dsl.foreign_key(@table_name, from_column, to_table, to_column, opts)
         | 
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
    
        data/spec/db_leftovers_spec.rb
    CHANGED
    
    | @@ -187,7 +187,43 @@ describe DBLeftovers do | |
| 187 187 | 
             
                EOQ
         | 
| 188 188 | 
             
              end
         | 
| 189 189 |  | 
| 190 | 
            +
              it "should create foreign keys with optional params inferred" do
         | 
| 191 | 
            +
                DBLeftovers::DatabaseInterface.starts_with
         | 
| 192 | 
            +
                DBLeftovers::Definition.define do
         | 
| 193 | 
            +
                  foreign_key :books, :shelves
         | 
| 194 | 
            +
                  foreign_key :books, :publishers, :on_delete => :set_null
         | 
| 195 | 
            +
                  foreign_key :books, :publication_country_id, :countries
         | 
| 196 | 
            +
                  foreign_key :books, :co_author_id, :authors, :on_delete => :cascade
         | 
| 197 | 
            +
                end
         | 
| 198 | 
            +
                DBLeftovers::DatabaseInterface.sqls.should have(4).items
         | 
| 199 | 
            +
                DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
         | 
| 200 | 
            +
                    ALTER TABLE books ADD CONSTRAINT fk_books_shelf_id FOREIGN KEY (shelf_id) REFERENCES shelves (id)
         | 
| 201 | 
            +
                EOQ
         | 
| 202 | 
            +
                DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
         | 
| 203 | 
            +
                    ALTER TABLE books ADD CONSTRAINT fk_books_publisher_id FOREIGN KEY (publisher_id) REFERENCES publishers (id) ON DELETE SET NULL
         | 
| 204 | 
            +
                EOQ
         | 
| 205 | 
            +
                DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
         | 
| 206 | 
            +
                    ALTER TABLE books ADD CONSTRAINT fk_books_publication_country_id
         | 
| 207 | 
            +
                        FOREIGN KEY (publication_country_id) REFERENCES countries (id)
         | 
| 208 | 
            +
                EOQ
         | 
| 209 | 
            +
                DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
         | 
| 210 | 
            +
                    ALTER TABLE books ADD CONSTRAINT fk_books_co_author_id
         | 
| 211 | 
            +
                        FOREIGN KEY (co_author_id) REFERENCES authors (id) ON DELETE CASCADE
         | 
| 212 | 
            +
                EOQ
         | 
| 213 | 
            +
              end
         | 
| 190 214 |  | 
| 215 | 
            +
              it "should create foreign keys with optional params inferred and table block" do
         | 
| 216 | 
            +
                DBLeftovers::DatabaseInterface.starts_with
         | 
| 217 | 
            +
                DBLeftovers::Definition.define do
         | 
| 218 | 
            +
                  table :books do
         | 
| 219 | 
            +
                    foreign_key :shelves
         | 
| 220 | 
            +
                    foreign_key :publishers
         | 
| 221 | 
            +
                    foreign_key :publication_country_id, :countries
         | 
| 222 | 
            +
                    foreign_key :co_author_id, :authors, :on_delete => :cascade
         | 
| 223 | 
            +
                  end
         | 
| 224 | 
            +
                end
         | 
| 225 | 
            +
                DBLeftovers::DatabaseInterface.sqls.should have(4).items
         | 
| 226 | 
            +
              end
         | 
| 191 227 |  | 
| 192 228 | 
             
              it "should not create indexes when they already exist" do
         | 
| 193 229 | 
             
                DBLeftovers::DatabaseInterface.starts_with([
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: db_leftovers
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.9.1
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -139,7 +139,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 139 139 | 
             
                  version: '0'
         | 
| 140 140 | 
             
                  segments:
         | 
| 141 141 | 
             
                  - 0
         | 
| 142 | 
            -
                  hash:  | 
| 142 | 
            +
                  hash: 712708189
         | 
| 143 143 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 144 144 | 
             
              none: false
         | 
| 145 145 | 
             
              requirements:
         |