activerecord-bulk_insert 0.0.1 → 0.0.2
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/.rubocop.yml +4 -0
 - data/.travis.yml +3 -0
 - data/README.md +36 -0
 - data/lib/active_record/bulk_insert.rb +33 -38
 - data/lib/active_record/bulk_insert/version.rb +1 -1
 - metadata +1 -1
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 54c973ddc1c628c1960a516fbb77529e88c2ef55b7f81390524f08d9551954a9
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 782d2dc1342711ee66625fcb191d2b7dedd9198d4ad7489462ca118196ae5f16
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d114588226c16377c365ede8468978685de4c6379593f0a5b1d57ce5f2456ce34b607c7f70bd2513804c58dd335fdf9bd0ffb8a9e1c06da45c2601d6d2a706f5
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 40998b00099c24b7056826a270addcab48ae94110767a3f3e110983bb5be03fc61098a6bd7a381e613df8781d4ecf36a73746edf62382d1623c3f1a75bd3fe1d
         
     | 
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/.travis.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | 
         @@ -16,10 +16,42 @@ And then execute: 
     | 
|
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
            ## Usage
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
      
 19 
     | 
    
         
            +
            `bulk_insert` with new records.  
         
     | 
| 
      
 20 
     | 
    
         
            +
            Insert new records one by one.
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 23 
     | 
    
         
            +
            users = [*1..10].map { |i| User.new(name: "user#{i}") }
         
     | 
| 
      
 24 
     | 
    
         
            +
            User.bulk_insert(users)
         
     | 
| 
      
 25 
     | 
    
         
            +
            ```
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            ```sql
         
     | 
| 
      
 28 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user1', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 29 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user2', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 30 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user3', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 31 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user4', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 32 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user5', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 33 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user6', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 34 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user7', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 35 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user8', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 36 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user9', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 37 
     | 
    
         
            +
            INSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES ('user10', '2019-08-23 15:37:46', '2019-08-23 15:37:46');
         
     | 
| 
      
 38 
     | 
    
         
            +
            ```
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            Specify `ignore_new_record` for bulk insert.  
         
     | 
| 
      
 41 
     | 
    
         
            +
            autoincrement and default values are not reflected.
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       19 
43 
     | 
    
         
             
            ```ruby
         
     | 
| 
       20 
44 
     | 
    
         
             
            users = [*1..10].map { |i| User.new(name: "user#{i}") }
         
     | 
| 
       21 
45 
     | 
    
         
             
            User.bulk_insert(users, ignore_new_record: false)
         
     | 
| 
      
 46 
     | 
    
         
            +
            ```
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            ```sql
         
     | 
| 
      
 49 
     | 
    
         
            +
            INSERT INTO `users`(`created_at`,`updated_at`,`name`) VALUES ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user1'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user2'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user3'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user4'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user5'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user6'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user7'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user8'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35', 'user9'), ('2019-08-23 15:28:35', '2019-08-23 15:28:35.964720', 'user10');
         
     | 
| 
      
 50 
     | 
    
         
            +
            ```
         
     | 
| 
       22 
51 
     | 
    
         | 
| 
      
 52 
     | 
    
         
            +
            Existing records are bulk updated.
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            ```ruby
         
     | 
| 
       23 
55 
     | 
    
         
             
            users = User.all
         
     | 
| 
       24 
56 
     | 
    
         
             
            users.each do |user|
         
     | 
| 
       25 
57 
     | 
    
         
             
              user.name = "user#{user.id * 2}"
         
     | 
| 
         @@ -27,6 +59,10 @@ end 
     | 
|
| 
       27 
59 
     | 
    
         
             
            User.bulk_insert(users)
         
     | 
| 
       28 
60 
     | 
    
         
             
            ```
         
     | 
| 
       29 
61 
     | 
    
         | 
| 
      
 62 
     | 
    
         
            +
            ```sql
         
     | 
| 
      
 63 
     | 
    
         
            +
            INSERT INTO `users`(`created_at`,`updated_at`,`name`) VALUES ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user2'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user4'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user6'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user8'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user10'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user12'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user14'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user16'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user18'), ('2019-08-23 15:28:35', '2019-08-23 15:34:49', 'user20') ON DUPLICATE KEY UPDATE `created_at`=VALUES(`created_at`),`updated_at`=VALUES(`updated_at`),`name`=VALUES(`name`);
         
     | 
| 
      
 64 
     | 
    
         
            +
            ```
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
       30 
66 
     | 
    
         
             
            ## Development
         
     | 
| 
       31 
67 
     | 
    
         | 
| 
       32 
68 
     | 
    
         
             
            After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         
     | 
| 
         @@ -1,60 +1,55 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require "active_record"
         
     | 
| 
       2 
     | 
    
         
            -
            require "active_support/concern"
         
     | 
| 
       3 
2 
     | 
    
         
             
            require "active_support/lazy_load_hooks"
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
4 
     | 
    
         
             
            require "active_record/bulk_insert/version"
         
     | 
| 
       6 
5 
     | 
    
         | 
| 
       7 
6 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       8 
7 
     | 
    
         
             
              module BulkInsert
         
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                      if is_new_record
         
     | 
| 
       15 
     | 
    
         
            -
                        if ignore_new_record
         
     | 
| 
       16 
     | 
    
         
            -
                          records.each(&:save!)
         
     | 
| 
       17 
     | 
    
         
            -
                        else
         
     | 
| 
       18 
     | 
    
         
            -
                          insert_all!(build_attributes(records))
         
     | 
| 
       19 
     | 
    
         
            -
                        end
         
     | 
| 
      
 8 
     | 
    
         
            +
                def bulk_insert(objects, ignore_new_record: true)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  result = objects.group_by(&:new_record?).map { |is_new_record, records|
         
     | 
| 
      
 10 
     | 
    
         
            +
                    if is_new_record
         
     | 
| 
      
 11 
     | 
    
         
            +
                      if ignore_new_record
         
     | 
| 
      
 12 
     | 
    
         
            +
                        records.each(&:save!)
         
     | 
| 
       20 
13 
     | 
    
         
             
                      else
         
     | 
| 
       21 
     | 
    
         
            -
                         
     | 
| 
      
 14 
     | 
    
         
            +
                        insert_all!(build_attributes(records))
         
     | 
| 
       22 
15 
     | 
    
         
             
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
                    else
         
     | 
| 
      
 17 
     | 
    
         
            +
                      upsert_all(build_attributes(records))
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
       23 
19 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 20 
     | 
    
         
            +
                    records
         
     | 
| 
      
 21 
     | 
    
         
            +
                  }
         
     | 
| 
       26 
22 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
                  result.flatten
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
       29 
25 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
      
 26 
     | 
    
         
            +
                private
         
     | 
| 
       31 
27 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 28 
     | 
    
         
            +
                  def build_attributes(objects)
         
     | 
| 
      
 29 
     | 
    
         
            +
                    keys = [required_keys, changed_keys(objects)].flatten.uniq
         
     | 
| 
       34 
30 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
                    objects.map { |object| Hash[keys.map { |k| [k, object.public_send(k)] }] }
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
       37 
33 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def required_keys
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @required_keys ||= columns.map { |column|
         
     | 
| 
      
 36 
     | 
    
         
            +
                      next if column.null
         
     | 
| 
       41 
37 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
      
 38 
     | 
    
         
            +
                      column.name
         
     | 
| 
      
 39 
     | 
    
         
            +
                    }.compact - [primary_key]
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
       45 
41 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  def changed_keys(objects)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    now = Time.current
         
     | 
| 
      
 44 
     | 
    
         
            +
                    objects.map { |object|
         
     | 
| 
      
 45 
     | 
    
         
            +
                      object.updated_at = now
         
     | 
| 
      
 46 
     | 
    
         
            +
                      object.created_at ||= now
         
     | 
| 
      
 47 
     | 
    
         
            +
                      object.changed_attributes.keys
         
     | 
| 
      
 48 
     | 
    
         
            +
                    }.flatten.uniq.compact
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
       55 
50 
     | 
    
         
             
              end
         
     | 
| 
       56 
51 
     | 
    
         
             
            end
         
     | 
| 
       57 
52 
     | 
    
         | 
| 
       58 
53 
     | 
    
         
             
            ActiveSupport.on_load(:active_record) do
         
     | 
| 
       59 
     | 
    
         
            -
              ActiveRecord::Base. 
     | 
| 
      
 54 
     | 
    
         
            +
              ActiveRecord::Base.extend(ActiveRecord::BulkInsert)
         
     | 
| 
       60 
55 
     | 
    
         
             
            end
         
     |