simple-sql 0.2.10 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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