simple-sql 0.2.10 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6970e8a68e60cb864a751516eab22b48cf747d13
4
- data.tar.gz: f953e02ac5408f7ca1beed4a5247b109c526acf0
3
+ metadata.gz: c57a6e1295b2ce84040e5e0f8167aa83d367e0cf
4
+ data.tar.gz: 10527d7193cc63784a21ce703427f6e111fc9e39
5
5
  SHA512:
6
- metadata.gz: 51cf095dc99c3e312273c8655bb2ef7ed6c7de8d50dd8241c870e688aeede9606eb4a96c1f52e0b27433be4b655314926dfeaadac73a0193ff505bcc4bfe0afe
7
- data.tar.gz: 572250ea4fc3e22be6605932eba180988b188db195af51bd5eb330ddec72b078c4edab035ca1638745dcbc98f5ca7fa3fa0841682884c8d6f3f3f5131933e4aa
6
+ metadata.gz: b9254b98c19843789d4ec814047316caefe96a020c3393d686ba5dcc4faac2aafcab638d01f1a04dce4286e676674a55fc7d5668d965a3452c68e80330e836ff
7
+ data.tar.gz: 3e662b58ff18e2608f3005d8f53c55e445dce91d8cd02011dcde2292d461e264b93bf0cabc7b54d12ec6df9ad84e11ade46bff5021f5e20c3d5c041a5a85d8d0
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple-sql (0.2.10)
4
+ simple-sql (0.3.0)
5
5
  pg (~> 0.20)
6
6
  pg_array_parser (~> 0)
7
7
 
@@ -25,12 +25,13 @@ module Simple
25
25
  end
26
26
 
27
27
  def default_logger
28
- logger = ActiveRecord::Base.logger if defined?(ActiveRecord)
29
- return logger if logger
30
-
31
- logger = Logger.new(STDERR)
32
- logger.level = Logger::INFO
33
- logger
28
+ if defined?(ActiveRecord)
29
+ ActiveRecord::Base.logger
30
+ else
31
+ logger = Logger.new(STDERR)
32
+ logger.level = Logger::INFO
33
+ logger
34
+ end
34
35
  end
35
36
 
36
37
  # execute one or more sql statements. This method does not allow to pass in
@@ -1,89 +1,41 @@
1
- # rubocop:disable Style/StructInheritance
1
+ # rubocop:disable Metrics/MethodLength
2
+ # rubocop:disable Metrics/AbcSize
2
3
 
3
4
  module Simple
4
5
  module SQL
5
- class Fragment < Struct.new(:to_sql)
6
- end
7
-
8
- def fragment(str)
9
- Fragment.new(str)
10
- end
11
-
12
- #
13
- # Creates duplicates of record in a table.
14
- #
15
- # This method handles timestamp columns (these will be set to the current
16
- # time) and primary keys (will be set to NULL.) You can pass in overrides
17
- # as a third argument for specific columns.
18
- #
19
- # Parameters:
20
- #
21
- # - ids: (Integer, Array<Integer>) primary key ids
22
- # - overrides: Hash[column_names => SQL::Fragment]
23
- #
24
- def duplicate(table, ids, overrides = {})
6
+ def duplicate(table, ids, except: [])
25
7
  ids = Array(ids)
26
8
  return [] if ids.empty?
27
9
 
28
- Duplicator.new(table, overrides).call(ids)
29
- end
30
-
31
- class Duplicator
32
- attr_reader :table_name, :custom_overrides
33
-
34
- def initialize(table_name, overrides)
35
- @table_name = table_name
36
- @custom_overrides = validated_overrides(overrides)
37
- end
38
-
39
- def call(ids)
40
- Simple::SQL.all query, ids
41
- rescue PG::UndefinedColumn => e
42
- raise ArgumentError, e.message
43
- end
44
-
45
- private
46
-
47
- # This stringify all keys of the overrides hash, and verifies that
48
- # all values in there are SQL::Fragments
49
- def validated_overrides(overrides)
50
- overrides.inject({}) do |hsh, (key, value)|
51
- raise ArgumentError, "Unknown value #{value.inspect}" unless value.is_a?(Fragment)
52
- hsh.update key.to_s => value.to_sql
53
- end
54
- end
10
+ timestamp_columns = Reflection.timestamp_columns(table)
11
+ primary_key_columns = Reflection.primary_key_columns(table)
55
12
 
56
- def timestamp_overrides
57
- Reflection.timestamp_columns(table_name).inject({}) do |hsh, column|
58
- hsh.update column => "now() AS #{column}"
59
- end
60
- end
13
+ # duplicate all columns in the table that need to be SELECTed.
14
+ #
15
+ columns_to_dupe = Reflection.columns(table)
61
16
 
62
- def copy_columns
63
- (Reflection.columns(table_name) - Reflection.primary_key_columns(table_name)).inject({}) do |hsh, column|
64
- hsh.update column => column
65
- end
66
- end
17
+ # Primary keys will not be selected from the table, they should be set
18
+ # automatically by the database, via a DEFAULT role on the column.
19
+ columns_to_dupe -= primary_key_columns
67
20
 
68
- # build SQL query
69
- def query
70
- sources = {}
21
+ # timestamp_columns will not be selected from the table, they will be
22
+ # set to now() explicitely.
23
+ columns_to_dupe -= timestamp_columns
71
24
 
72
- sources.update copy_columns
73
- sources.update timestamp_overrides
74
- sources.update custom_overrides
25
+ # If some other columns must be excluded they have to be added in the
26
+ # except: keyword argument. This is helpful for UNIQUE columns, but
27
+ # a column which is supposed to be UNIQUE and NOT NULL can not be dealt
28
+ # with.
29
+ columns_to_dupe -= except.map(&:to_s)
75
30
 
76
- # convert into an Array, to make sure that keys and values aka firsts
77
- # and lasts are always in the correct order.
78
- sources = sources.to_a
31
+ # build query
32
+ select_columns = columns_to_dupe + timestamp_columns
33
+ select_values = columns_to_dupe + timestamp_columns.map { |col| "now() AS #{col}" }
79
34
 
80
- <<~SQL
81
- INSERT INTO #{table_name}(#{sources.map(&:first).join(', ')})
82
- SELECT #{sources.map(&:last).join(', ')}
83
- FROM #{table_name}
84
- WHERE id = ANY($1) RETURNING id
85
- SQL
86
- end
35
+ Simple::SQL.all <<~SQL, ids
36
+ INSERT INTO #{table}(#{select_columns.join(', ')})
37
+ SELECT #{select_values.join(', ')} FROM #{table} WHERE id = ANY($1) RETURNING id
38
+ SQL
87
39
  end
88
40
  end
89
41
  end
@@ -1,5 +1,5 @@
1
1
  module Simple
2
2
  module SQL
3
- VERSION = "0.2.10"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -10,24 +10,24 @@ describe "Simple::SQL.duplicate" do
10
10
  end
11
11
 
12
12
  it "does not fail on a non-existing user" do
13
- dupe_ids = SQL.duplicate "users", -1
13
+ dupe_ids = SQL.duplicate "users", source_ids.first
14
14
 
15
- expect(dupe_ids.length).to eq(0)
16
- expect(SQL.ask("SELECT COUNT(*) FROM users")).to eq(USER_COUNT)
15
+ expect(dupe_ids.length).to eq(1)
16
+ expect(SQL.ask("SELECT COUNT(*) FROM users")).to eq(3)
17
17
  end
18
18
 
19
19
  it "duplicates a single user" do
20
20
  dupe_ids = SQL.duplicate "users", source_ids.first
21
21
 
22
22
  expect(dupe_ids.length).to eq(1)
23
- expect(SQL.ask("SELECT COUNT(*) FROM users")).to eq(1 + USER_COUNT)
23
+ expect(SQL.ask("SELECT COUNT(*) FROM users")).to eq(3)
24
24
  end
25
25
 
26
26
  it "duplicates many users" do
27
27
  dupe_ids = SQL.duplicate "users", (source_ids + [ -10 ])
28
28
 
29
29
  expect(dupe_ids.length).to eq(2)
30
- expect(SQL.ask("SELECT COUNT(*) FROM users")).to eq(2 + USER_COUNT)
30
+ expect(SQL.ask("SELECT COUNT(*) FROM users")).to eq(4)
31
31
  end
32
32
 
33
33
  it "updates the timestamp columns" do
@@ -15,6 +15,11 @@ describe "Simple::SQL.insert" do
15
15
  expect(user.first_name).to eq("foo")
16
16
  expect(user.last_name).to eq("bar")
17
17
  expect(user.created_at).to be_a(Time)
18
+
19
+ #
20
+ # r = SQL.record("SELECT COUNT(*) AS count FROM users")
21
+ # r = SQL.record("SELECT COUNT(*) AS count FROM users")
22
+ # expect(r).to eq({count: 2})
18
23
  end
19
24
  end
20
25
 
@@ -35,13 +35,4 @@ ActiveRecord::Schema.define do
35
35
 
36
36
  t.timestamps null: true
37
37
  end
38
-
39
- create_table :unique_users, force: true do |t|
40
- t.string :first_name
41
- t.string :last_name
42
- end
43
-
44
- execute <<-SQL
45
- CREATE UNIQUE INDEX unique_users_ix1 ON unique_users(first_name, last_name)
46
- SQL
47
38
  end
@@ -1,14 +1,8 @@
1
1
  FactoryGirl.define do
2
2
  factory :user do
3
3
  role_id 123
4
-
5
- sequence :first_name do |n| "First #{n}" end
6
- sequence :last_name do |n| "Last #{n}" end
4
+ first_name "Uni"
5
+ last_name "Corn"
7
6
  access_level "viewable"
8
7
  end
9
-
10
- factory :unique_user do
11
- sequence :first_name do |n| "First #{n}" end
12
- sequence :last_name do |n| "Last #{n}" end
13
- end
14
8
  end
@@ -1,5 +1,2 @@
1
1
  class User < ActiveRecord::Base
2
2
  end
3
-
4
- class UniqueUser < ActiveRecord::Base
5
- end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.10
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - radiospiel
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-02-21 00:00:00.000000000 Z
12
+ date: 2018-02-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pg_array_parser
@@ -198,7 +198,6 @@ files:
198
198
  - spec/simple/sql_config_spec.rb
199
199
  - spec/simple/sql_conversion_spec.rb
200
200
  - spec/simple/sql_duplicate_spec.rb
201
- - spec/simple/sql_duplicate_unique_spec.rb
202
201
  - spec/simple/sql_insert_spec.rb
203
202
  - spec/simple/sql_record_spec.rb
204
203
  - spec/simple/sql_reflection_spec.rb
@@ -239,7 +238,6 @@ test_files:
239
238
  - spec/simple/sql_config_spec.rb
240
239
  - spec/simple/sql_conversion_spec.rb
241
240
  - spec/simple/sql_duplicate_spec.rb
242
- - spec/simple/sql_duplicate_unique_spec.rb
243
241
  - spec/simple/sql_insert_spec.rb
244
242
  - spec/simple/sql_record_spec.rb
245
243
  - spec/simple/sql_reflection_spec.rb
@@ -1,37 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Simple::SQL.duplicate/unique indices" do
4
- let!(:unique_users) { 1.upto(USER_COUNT).map { create(:unique_user) } }
5
-
6
- let!(:source_ids) { SQL.all("SELECT id FROM unique_users") }
7
-
8
- it "cannot duplicate unique_user" do
9
- expect {
10
- SQL.duplicate "unique_users", source_ids
11
- }.to raise_error(PG::UniqueViolation)
12
- end
13
-
14
- it "raises an ArgumentError when called with unknown columns" do
15
- expect {
16
- SQL.duplicate "unique_users", source_ids, foo: SQL.fragment("baz")
17
- }.to raise_error(ArgumentError)
18
- end
19
-
20
- it "raises an ArgumentError when called with invalid overrides" do
21
- expect {
22
- SQL.duplicate "unique_users", source_ids, first_name: "I am invalid"
23
- }.to raise_error(ArgumentError)
24
- end
25
-
26
- it "duplicates unique_users" do
27
- overrides = {
28
- first_name: SQL.fragment("first_name || '.' || id"),
29
- last_name: SQL.fragment("last_name || '.' || id")
30
- }
31
-
32
- dupe_ids = SQL.duplicate "unique_users", source_ids, overrides
33
-
34
- expect(dupe_ids.length).to eq(2)
35
- expect(SQL.ask("SELECT COUNT(*) FROM unique_users")).to eq(4)
36
- end
37
- end