sqlstmt 0.2.16 → 0.2.17
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/lib/sqlstmt/data.rb +1 -1
- data/lib/sqlstmt/mysql/build.rb +6 -1
- data/lib/sqlstmt/mysql/check.rb +15 -2
- data/lib/sqlstmt/sqlstmt.rb +6 -0
- data/test/insert_values_test.rb +57 -0
- metadata +5 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: da75fc21521c962370ecfb05b8a2eefeffe08c27a3d3e74d3c8162de45e18870
|
|
4
|
+
data.tar.gz: 36240342fd174f6d35da9fc3232f71f36c7cf96ab30f64adfc6d1f3809604ae5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b76f9db91f918f54229ab0bb5fff5820ee3559649a9fea0f8a307f9329d8502737139b1ae046b42f2c1e354135f13fc47bded74520f29313a813425f3e2253a
|
|
7
|
+
data.tar.gz: d7749cf573be6bfa522d3efa817f9a90e04095d38be98271e9abe1435ce965a4c665ee58eb38ccfd9a70834cdcd063341626cd7c25068936f7046848001fd6ca
|
data/lib/sqlstmt/data.rb
CHANGED
|
@@ -20,7 +20,7 @@ SqlTable = Struct.new(:str, :name, :alias, :index)
|
|
|
20
20
|
SqlJoin = Struct.new(:kwstr, :table, :on_expr)
|
|
21
21
|
|
|
22
22
|
# :table_ids is a set of all table names and aliases, including ones added by a join
|
|
23
|
-
SPECIAL_DATA_FIELDS = %i(stmt_type table_ids where_behavior).freeze
|
|
23
|
+
SPECIAL_DATA_FIELDS = %i(stmt_type table_ids where_behavior values_clause values_alias).freeze
|
|
24
24
|
ARRAY_DATA_FIELDS = MULTI_VALUE_KEYWORDS.map {|keyword| "#{keyword}s".to_sym} + %i(tables joins set_fields set_values tables_to_delete).freeze
|
|
25
25
|
|
|
26
26
|
# calling uniq on this in case some fields end up in multiple categories
|
data/lib/sqlstmt/mysql/build.rb
CHANGED
|
@@ -58,7 +58,12 @@ class MysqlBuilder
|
|
|
58
58
|
field_list = @data.set_fields.join(',')
|
|
59
59
|
parts << "(#{field_list})"
|
|
60
60
|
end
|
|
61
|
-
|
|
61
|
+
if @data.values_clause
|
|
62
|
+
parts << "VALUES (#{@data.set_values.join(',')})"
|
|
63
|
+
parts << "AS #{@data.values_alias}" if @data.values_alias
|
|
64
|
+
else
|
|
65
|
+
parts << shared_select(@data.set_values)
|
|
66
|
+
end
|
|
62
67
|
if @data.on_duplicate
|
|
63
68
|
parts << "ON DUPLICATE KEY UPDATE #{@data.on_duplicate}"
|
|
64
69
|
elsif @data.ignore_duplicate
|
data/lib/sqlstmt/mysql/check.rb
CHANGED
|
@@ -10,7 +10,7 @@ class MysqlChecker
|
|
|
10
10
|
|
|
11
11
|
def run
|
|
12
12
|
check_basics
|
|
13
|
-
check_where
|
|
13
|
+
check_where if !@data.tables.empty?
|
|
14
14
|
check_statement_type_specific
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -18,7 +18,10 @@ class MysqlChecker
|
|
|
18
18
|
if !@data.stmt_type
|
|
19
19
|
raise SqlStmtError, "must call :select, :update, :insert or :delete"
|
|
20
20
|
end
|
|
21
|
-
if @data.
|
|
21
|
+
if @data.values_clause
|
|
22
|
+
raise SqlStmtError, "must not call :values on #{@data.stmt_type} statement" if @data.stmt_type != 'insert'
|
|
23
|
+
raise SqlStmtError, "must not call :table with :values" if !@data.tables.empty?
|
|
24
|
+
elsif @data.tables.empty?
|
|
22
25
|
raise SqlStmtError, "must call :table"
|
|
23
26
|
end
|
|
24
27
|
end
|
|
@@ -52,6 +55,16 @@ class MysqlChecker
|
|
|
52
55
|
def check_stmt_insert
|
|
53
56
|
raise SqlStmtError, "must call :set on insert statement" if @data.set_values.empty?
|
|
54
57
|
raise SqlStmtError, "must call :into on insert statement" if @data.into.nil?
|
|
58
|
+
check_values_clause if @data.values_clause
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def check_values_clause
|
|
62
|
+
%i(where join having).each do |clause|
|
|
63
|
+
raise SqlStmtError, "must not call :#{clause} with :values" if !@data["#{clause}s"].empty?
|
|
64
|
+
end
|
|
65
|
+
%i(group_by order_by limit offset outfile distinct straight_join with_rollup).each do |field|
|
|
66
|
+
raise SqlStmtError, "must not call :#{field} with :values" if @data[field]
|
|
67
|
+
end
|
|
55
68
|
end
|
|
56
69
|
|
|
57
70
|
def check_stmt_delete
|
data/lib/sqlstmt/sqlstmt.rb
CHANGED
|
@@ -135,6 +135,12 @@ class SqlStmt
|
|
|
135
135
|
return set(field, value.to_sql)
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
def values(values_alias = nil)
|
|
139
|
+
@data.values_clause = true
|
|
140
|
+
@data.values_alias = values_alias
|
|
141
|
+
return self
|
|
142
|
+
end
|
|
143
|
+
|
|
138
144
|
###### these are simple wrappers around various keywords
|
|
139
145
|
|
|
140
146
|
SqlStmtLib::FLAG_KEYWORDS.each do |keyword|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
class TestInsertValues < Minitest::Test
|
|
4
|
+
def test_minimum_requirements
|
|
5
|
+
assert_raises(SqlStmtError) { SqlStmt.new.insert.into('target').values.to_s }
|
|
6
|
+
assert_raises(SqlStmtError) { SqlStmt.new.insert.into('target').set('blah', 'blee').to_s }
|
|
7
|
+
assert_raises(SqlStmtError) { SqlStmt.new.insert.into('target').values.set('blah', 'blee').table('source').to_s }
|
|
8
|
+
assert_raises(SqlStmtError) { SqlStmt.new.select.values.get('blah').to_s }
|
|
9
|
+
assert_raises(SqlStmtError) { SqlStmt.new.update.table('target').values.set('blah', 'blee').no_where.to_s }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_simple
|
|
13
|
+
assert_equal('INSERT INTO target (blah) VALUES (blee)', SqlStmt.new.insert.into('target').values.set('blah', 'blee').to_s)
|
|
14
|
+
assert_equal("INSERT INTO target (duration,blah) VALUES (5,'blee')", SqlStmt.new.insert.into('target').values.set('duration', 5).setq('blah', 'blee').to_s)
|
|
15
|
+
assert_equal('INSERT IGNORE INTO target (blah) VALUES (blee)', SqlStmt.new.insert.ignore.into('target').values.set('blah', 'blee').to_s)
|
|
16
|
+
assert_equal('REPLACE INTO target (blah) VALUES (blee)', SqlStmt.new.insert.replace.into('target').values.set('blah', 'blee').to_s)
|
|
17
|
+
assert_equal('INSERT INTO target (blah) VALUES (blee) AS new', SqlStmt.new.insert.into('target').values('new').set('blah', 'blee').to_s)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_ignore_duplicate
|
|
21
|
+
sqlt = SqlStmt.new.insert.into('target').values.set('idkey', 1)
|
|
22
|
+
assert_equal('INSERT INTO target (idkey) VALUES (1) ON DUPLICATE KEY UPDATE idkey = idkey', sqlt.dup.ignore_duplicate('idkey').to_s)
|
|
23
|
+
assert_equal('INSERT INTO target (idkey) VALUES (1) ON DUPLICATE KEY UPDATE idkey = idkey + 1', sqlt.dup.on_duplicate('idkey = idkey + 1').to_s)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_values_alias
|
|
27
|
+
sqlt = SqlStmt.new.insert.into('target').values('new')
|
|
28
|
+
sqlt.set('idkey', 1).setq('blah', 'blee')
|
|
29
|
+
sqlt.on_duplicate('blah = new.blah')
|
|
30
|
+
assert_equal("INSERT INTO target (idkey,blah) VALUES (1,'blee') AS new ON DUPLICATE KEY UPDATE blah = new.blah", sqlt.to_s)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_from_clauses_rejected
|
|
34
|
+
sqlt = SqlStmt.new.insert.into('target').values.set('blah', 'blee')
|
|
35
|
+
assert_raises(SqlStmtError) { sqlt.dup.where('blah = 1').to_s }
|
|
36
|
+
assert_raises(SqlStmtError) { sqlt.dup.join('other_tbl o', 'o.blah = 1').to_s }
|
|
37
|
+
assert_raises(SqlStmtError) { sqlt.dup.having('blah > 1').to_s }
|
|
38
|
+
assert_raises(SqlStmtError) { sqlt.dup.group_by('blah').to_s }
|
|
39
|
+
assert_raises(SqlStmtError) { sqlt.dup.order_by('blah').to_s }
|
|
40
|
+
assert_raises(SqlStmtError) { sqlt.dup.limit(1).to_s }
|
|
41
|
+
assert_raises(SqlStmtError) { sqlt.dup.distinct.to_s }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_dup
|
|
45
|
+
shared_builder = SqlStmt.new.insert.into('target').values
|
|
46
|
+
first_builder = shared_builder
|
|
47
|
+
other_builder = shared_builder.dup
|
|
48
|
+
|
|
49
|
+
first_builder.set('created_at', 'NOW()')
|
|
50
|
+
|
|
51
|
+
other_builder.set('info', 'then')
|
|
52
|
+
other_builder.setq('status', 'good')
|
|
53
|
+
|
|
54
|
+
assert_equal('INSERT INTO target (created_at) VALUES (NOW())', first_builder.to_s)
|
|
55
|
+
assert_equal("INSERT INTO target (info,status) VALUES (then,'good')", other_builder.to_s)
|
|
56
|
+
end
|
|
57
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sqlstmt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.17
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ATPSoft
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
12
|
description: Build SQL statements using method calls instead of strings. This is not
|
|
14
13
|
an ORM. It has only been used and tested with MySQL so far but the intention is
|
|
@@ -33,6 +32,7 @@ files:
|
|
|
33
32
|
- test/delete_test.rb
|
|
34
33
|
- test/helper.rb
|
|
35
34
|
- test/insert_select_test.rb
|
|
35
|
+
- test/insert_values_test.rb
|
|
36
36
|
- test/select_test.rb
|
|
37
37
|
- test/to_sql_test.rb
|
|
38
38
|
- test/update_test.rb
|
|
@@ -40,7 +40,6 @@ homepage: https://github.com/atpsoft/sqlstmt
|
|
|
40
40
|
licenses:
|
|
41
41
|
- MIT
|
|
42
42
|
metadata: {}
|
|
43
|
-
post_install_message:
|
|
44
43
|
rdoc_options: []
|
|
45
44
|
require_paths:
|
|
46
45
|
- lib
|
|
@@ -55,8 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
55
54
|
- !ruby/object:Gem::Version
|
|
56
55
|
version: '0'
|
|
57
56
|
requirements: []
|
|
58
|
-
rubygems_version:
|
|
59
|
-
signing_key:
|
|
57
|
+
rubygems_version: 4.0.17
|
|
60
58
|
specification_version: 4
|
|
61
59
|
summary: build SQL statements using method calls instead of strings
|
|
62
60
|
test_files:
|
|
@@ -64,6 +62,7 @@ test_files:
|
|
|
64
62
|
- test/delete_test.rb
|
|
65
63
|
- test/helper.rb
|
|
66
64
|
- test/insert_select_test.rb
|
|
65
|
+
- test/insert_values_test.rb
|
|
67
66
|
- test/select_test.rb
|
|
68
67
|
- test/to_sql_test.rb
|
|
69
68
|
- test/update_test.rb
|