baza 0.0.27 → 0.0.28
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/VERSION +1 -1
- data/baza.gemspec +9 -3
- data/lib/baza/base_sql_driver.rb +61 -17
- data/lib/baza/database.rb +2 -2
- data/lib/baza/driver/mysql/database.rb +15 -2
- data/lib/baza/driver/mysql/sql/column.rb +39 -0
- data/lib/baza/driver/mysql/sql/create_indexes.rb +51 -0
- data/lib/baza/driver/mysql/sql/create_table.rb +37 -0
- data/lib/baza/driver/mysql/sql.rb +3 -0
- data/lib/baza/driver/pg/columns.rb +18 -2
- data/lib/baza/driver/pg/database.rb +2 -24
- data/lib/baza/driver/pg/indexes.rb +16 -0
- data/lib/baza/driver/pg/table.rb +1 -16
- data/lib/baza/driver/pg/tables.rb +34 -2
- data/lib/baza/driver/pg.rb +13 -1
- data/lib/baza/dump.rb +43 -13
- data/lib/baza/sql_queries/generic_insert.rb +15 -1
- data/lib/baza/sql_queries/postgres_upsert_duplicate_key.rb +2 -2
- data/spec/baza/sql_queries/generic_insert_spec.rb +26 -0
- data/spec/drivers/pg/columns_spec.rb +45 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a62941ce9303dc76e57c84b8db5045e9ffb060a6
|
4
|
+
data.tar.gz: 88ab7cd45d1f8caf0fdb1139edb27931a3f0dfbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8797dfcd1e18c7d0de33f048e7de2e903caa48c6abb10be47cf0b4e075ebc7607f27373497633ab23e79c5b3064d9ecf110d20a07a063c2904e1b6f0fdf23e1
|
7
|
+
data.tar.gz: 59a1951ceea82bc29831ceeea9751f0755de1bc1ffa7ce89970c2492e51d2bd933eb7c730c190d141468e0ad75f7b10a1137e50aed030e0d3a26808726a54edf
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.28
|
data/baza.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: baza 0.0.
|
5
|
+
# stub: baza 0.0.28 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "baza".freeze
|
9
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.28"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Kasper Johansen".freeze]
|
14
|
-
s.date = "2017-03
|
14
|
+
s.date = "2017-07-03"
|
15
15
|
s.description = "A database abstraction layer, model framework and database framework.".freeze
|
16
16
|
s.email = "kj@gfish.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -65,6 +65,10 @@ Gem::Specification.new do |s|
|
|
65
65
|
"lib/baza/driver/mysql/index.rb",
|
66
66
|
"lib/baza/driver/mysql/indexes.rb",
|
67
67
|
"lib/baza/driver/mysql/result.rb",
|
68
|
+
"lib/baza/driver/mysql/sql.rb",
|
69
|
+
"lib/baza/driver/mysql/sql/column.rb",
|
70
|
+
"lib/baza/driver/mysql/sql/create_indexes.rb",
|
71
|
+
"lib/baza/driver/mysql/sql/create_table.rb",
|
68
72
|
"lib/baza/driver/mysql/sqlspecs.rb",
|
69
73
|
"lib/baza/driver/mysql/table.rb",
|
70
74
|
"lib/baza/driver/mysql/tables.rb",
|
@@ -157,12 +161,14 @@ Gem::Specification.new do |s|
|
|
157
161
|
"lib/baza/table.rb",
|
158
162
|
"spec/active_record/models/user.rb",
|
159
163
|
"spec/baza/cloner_spec.rb",
|
164
|
+
"spec/baza/sql_queries/generic_insert_spec.rb",
|
160
165
|
"spec/drivers/active_record_mysql2_spec.rb",
|
161
166
|
"spec/drivers/active_record_mysql_spec.rb",
|
162
167
|
"spec/drivers/active_record_pg_spec.rb",
|
163
168
|
"spec/drivers/active_record_sqlite3_spec.rb",
|
164
169
|
"spec/drivers/mysql2_spec.rb",
|
165
170
|
"spec/drivers/mysql_spec.rb",
|
171
|
+
"spec/drivers/pg/columns_spec.rb",
|
166
172
|
"spec/drivers/pg_spec.rb",
|
167
173
|
"spec/drivers/sqlite3_spec.rb",
|
168
174
|
"spec/info_active_record_example.rb",
|
data/lib/baza/base_sql_driver.rb
CHANGED
@@ -2,24 +2,29 @@ class Baza::BaseSqlDriver
|
|
2
2
|
attr_reader :db, :conn, :sep_database, :sep_table, :sep_col, :sep_val, :sep_index
|
3
3
|
attr_accessor :tables, :cols, :indexes
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
SEPARATOR_DATABASE = "`".freeze
|
6
|
+
SEPARATOR_TABLE = "`".freeze
|
7
|
+
SEPARATOR_COLUMN = "`".freeze
|
8
|
+
SEPARATOR_VALUE = "'".freeze
|
9
|
+
SEPARATOR_INDEX = "`".freeze
|
10
|
+
|
11
|
+
def self.from_object(_args); end
|
7
12
|
|
8
13
|
def initialize(db)
|
9
14
|
@db = db
|
10
15
|
|
11
|
-
@sep_database =
|
12
|
-
@sep_table =
|
13
|
-
@sep_col =
|
14
|
-
@sep_val =
|
15
|
-
@sep_index =
|
16
|
+
@sep_database = SEPARATOR_DATABASE
|
17
|
+
@sep_table = SEPARATOR_TABLE
|
18
|
+
@sep_col = SEPARATOR_COLUMN
|
19
|
+
@sep_val = SEPARATOR_VALUE
|
20
|
+
@sep_index = SEPARATOR_INDEX
|
16
21
|
end
|
17
22
|
|
18
23
|
def foreign_key_support?
|
19
24
|
true
|
20
25
|
end
|
21
26
|
|
22
|
-
def escape(string)
|
27
|
+
def self.escape(string)
|
23
28
|
string.to_s.gsub(/([\0\n\r\032\'\"\\])/) do
|
24
29
|
case Regexp.last_match(1)
|
25
30
|
when "\0" then "\\0"
|
@@ -31,32 +36,52 @@ class Baza::BaseSqlDriver
|
|
31
36
|
end
|
32
37
|
end
|
33
38
|
|
39
|
+
def escape(string)
|
40
|
+
self.class.escape(string)
|
41
|
+
end
|
42
|
+
|
34
43
|
alias esc escape
|
35
44
|
alias escape_alternative escape
|
36
45
|
|
37
46
|
# Escapes a string to be used as a column.
|
47
|
+
def self.escape_column(string)
|
48
|
+
string = string.to_s
|
49
|
+
raise "Invalid column-string: #{string}" if string.include?(SEPARATOR_COLUMN)
|
50
|
+
string
|
51
|
+
end
|
52
|
+
|
38
53
|
def escape_column(string)
|
54
|
+
self.class.escape_column(string)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.escape_table(string)
|
39
58
|
string = string.to_s
|
40
|
-
raise "Invalid
|
59
|
+
raise "Invalid table-string: #{string}" if string.include?(SEPARATOR_TABLE)
|
41
60
|
string
|
42
61
|
end
|
43
62
|
|
44
63
|
def escape_table(string)
|
64
|
+
self.class.escape_table(string)
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.escape_database(string)
|
45
68
|
string = string.to_s
|
46
|
-
raise "Invalid
|
69
|
+
raise "Invalid database-string: #{string}" if string.include?(SEPARATOR_DATABASE)
|
47
70
|
string
|
48
71
|
end
|
49
72
|
|
50
73
|
def escape_database(string)
|
74
|
+
self.class.escape_database(string)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.escape_index(string)
|
51
78
|
string = string.to_s
|
52
|
-
raise "Invalid
|
79
|
+
raise "Invalid index-string: #{string}" if string.include?(SEPARATOR_INDEX)
|
53
80
|
string
|
54
81
|
end
|
55
82
|
|
56
83
|
def escape_index(string)
|
57
|
-
string
|
58
|
-
raise "Invalid index-string: #{string}" if string.include?(@sep_index)
|
59
|
-
string
|
84
|
+
self.class.escape_index(string)
|
60
85
|
end
|
61
86
|
|
62
87
|
def transaction
|
@@ -88,10 +113,15 @@ class Baza::BaseSqlDriver
|
|
88
113
|
def insert_multi(tablename, arr_hashes, args = {})
|
89
114
|
sql = [] if args && args[:return_sql]
|
90
115
|
|
91
|
-
|
116
|
+
if args && args[:return_sql]
|
92
117
|
arr_hashes.each do |hash|
|
93
|
-
|
94
|
-
|
118
|
+
sql << @db.insert(tablename, hash, args)
|
119
|
+
end
|
120
|
+
else
|
121
|
+
@db.transaction do
|
122
|
+
arr_hashes.each do |hash|
|
123
|
+
@db.insert(tablename, hash, args)
|
124
|
+
end
|
95
125
|
end
|
96
126
|
end
|
97
127
|
|
@@ -183,6 +213,20 @@ class Baza::BaseSqlDriver
|
|
183
213
|
# Returns the correct SQL-value for the given value.
|
184
214
|
# If it is a number, then just the raw number as a string will be returned.
|
185
215
|
# nil's will be NULL and strings will have quotes and will be escaped.
|
216
|
+
def self.sqlval(val)
|
217
|
+
if val.is_a?(Fixnum) || val.is_a?(Integer)
|
218
|
+
val.to_s
|
219
|
+
elsif val == nil
|
220
|
+
"NULL"
|
221
|
+
elsif val.is_a?(Date)
|
222
|
+
"#{SEPARATOR_VALUE}#{Datet.in(val).dbstr(time: false)}#{SEPARATOR_VALUE}"
|
223
|
+
elsif val.is_a?(Time) || val.is_a?(DateTime) || val.is_a?(Datet)
|
224
|
+
"#{SEPARATOR_VALUE}#{Datet.in(val).dbstr}#{SEPARATOR_VALUE}"
|
225
|
+
else
|
226
|
+
"#{SEPARATOR_VALUE}#{escape(val)}#{SEPARATOR_VALUE}"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
186
230
|
def sqlval(val)
|
187
231
|
return @conn.sqlval(val) if @conn.respond_to?(:sqlval)
|
188
232
|
|
data/lib/baza/database.rb
CHANGED
@@ -11,10 +11,10 @@ class Baza::Database
|
|
11
11
|
@name_was = @name
|
12
12
|
end
|
13
13
|
|
14
|
-
def import_file!(path)
|
14
|
+
def import_file!(path, args = {})
|
15
15
|
File.open(path, "r") do |io|
|
16
16
|
use do
|
17
|
-
Baza::Commands::Importer.new(db: @db, io: io).execute
|
17
|
+
Baza::Commands::Importer.new({db: @db, io: io}.merge(args)).execute
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -41,9 +41,22 @@ class Baza::Driver::Mysql::Database < Baza::Database
|
|
41
41
|
|
42
42
|
sql << ")"
|
43
43
|
|
44
|
-
return [sql] if args && args[:return_sql]
|
44
|
+
# return [sql] if args && args[:return_sql]
|
45
45
|
|
46
|
-
|
46
|
+
sql = Baza::Driver::Mysql::Sql::CreateTable.new(
|
47
|
+
columns: data.fetch(:columns),
|
48
|
+
indexes: data[:indexes],
|
49
|
+
name: name,
|
50
|
+
temporary: data[:temp]
|
51
|
+
).sql
|
52
|
+
|
53
|
+
return sql if args && args[:return_sql]
|
54
|
+
|
55
|
+
use do
|
56
|
+
sql.each do |sql_i|
|
57
|
+
@db.query(sql_i)
|
58
|
+
end
|
59
|
+
end
|
47
60
|
end
|
48
61
|
|
49
62
|
def rename(new_name)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Baza::Driver::Mysql::Sql::Column
|
2
|
+
DATA_SQL_ALLOWED_KEYS = [:type, :maxlength, :name, :primarykey, :autoincr, :default, :comment, :after, :first, :storage, :null, :renames].freeze
|
3
|
+
|
4
|
+
attr_reader :data
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@data = data
|
8
|
+
end
|
9
|
+
|
10
|
+
def sql
|
11
|
+
data.each_key do |key|
|
12
|
+
raise "Invalid key: '#{key}' (#{key.class.name})." unless DATA_SQL_ALLOWED_KEYS.include?(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
raise "No type given." unless data[:type]
|
16
|
+
type = data[:type].to_sym
|
17
|
+
|
18
|
+
data[:maxlength] = 255 if type == :varchar && data[:maxlength].to_s.strip.empty?
|
19
|
+
|
20
|
+
sql = "#{Baza::Driver::Mysql::SEPARATOR_COLUMN}#{Baza::Driver::Mysql.escape_column(data.fetch(:name))}#{Baza::Driver::Mysql::SEPARATOR_COLUMN} #{type}"
|
21
|
+
sql << "(#{data[:maxlength]})" if data[:maxlength]
|
22
|
+
sql << " PRIMARY KEY" if data[:primarykey]
|
23
|
+
sql << " AUTO_INCREMENT" if data[:autoincr]
|
24
|
+
sql << " NOT NULL" if data.key?(:null) && !data[:null]
|
25
|
+
|
26
|
+
if data.key?(:default_func)
|
27
|
+
sql << " DEFAULT #{data[:default_func]}"
|
28
|
+
elsif data.key?(:default) && !data[:default].nil?
|
29
|
+
sql << " DEFAULT #{Baza::Driver::Mysql.sqlval(data.fetch(:default))}"
|
30
|
+
end
|
31
|
+
|
32
|
+
sql << " COMMENT '#{Baza::Driver::Mysql.escape(data.fetch(:comment))}'" if data.key?(:comment)
|
33
|
+
sql << " AFTER #{Baza::Driver::Mysql::SEPARATOR_COLUMN}#{Baza::Driver::Mysql.escape_column(data.fetch(:after))}#{Baza::Driver::Mysql::SEPARATOR_COLUMN}" if data[:after] && !data[:first]
|
34
|
+
sql << " FIRST" if data[:first]
|
35
|
+
sql << " STORAGE #{data[:storage].to_s.upcase}" if data[:storage]
|
36
|
+
|
37
|
+
[sql]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Baza::Driver::Mysql::Sql::CreateIndexes
|
2
|
+
def initialize(args)
|
3
|
+
@create = args[:create]
|
4
|
+
@indexes = args.fetch(:indexes)
|
5
|
+
@on_table = args[:on_table]
|
6
|
+
@table_name = args.fetch(:table_name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def sql
|
10
|
+
sql = ""
|
11
|
+
first = true
|
12
|
+
|
13
|
+
@indexes.each do |index_data|
|
14
|
+
sql << "CREATE" if @create || @create.nil?
|
15
|
+
|
16
|
+
if index_data.is_a?(String) || index_data.is_a?(Symbol)
|
17
|
+
index_data = {name: index_data, columns: [index_data]}
|
18
|
+
end
|
19
|
+
|
20
|
+
raise "No name was given: '#{index_data}'." if !index_data.key?(:name) || index_data[:name].to_s.strip.empty?
|
21
|
+
raise "No columns was given on index: '#{index_data.fetch(:name)}'." if !index_data[:columns] || index_data[:columns].empty?
|
22
|
+
|
23
|
+
if first
|
24
|
+
first = false
|
25
|
+
else
|
26
|
+
sql << ", "
|
27
|
+
end
|
28
|
+
|
29
|
+
sql << " UNIQUE" if index_data[:unique]
|
30
|
+
sql << " INDEX #{Baza::Driver::Mysql::SEPARATOR_INDEX}#{Baza::Driver::Mysql.escape_index(index_data.fetch(:name))}#{Baza::Driver::Mysql::SEPARATOR_INDEX}"
|
31
|
+
|
32
|
+
if @on_table || @on_table.nil?
|
33
|
+
sql << " ON #{Baza::Driver::Mysql::SEPARATOR_TABLE}#{Baza::Driver::Mysql.escape_table(@table_name)}#{Baza::Driver::Mysql::SEPARATOR_TABLE}"
|
34
|
+
end
|
35
|
+
|
36
|
+
sql << " ("
|
37
|
+
|
38
|
+
first = true
|
39
|
+
index_data[:columns].each do |col_name|
|
40
|
+
sql << ", " unless first
|
41
|
+
first = false if first
|
42
|
+
|
43
|
+
sql << "#{Baza::Driver::Mysql::SEPARATOR_COLUMN}#{Baza::Driver::Mysql.escape_column(col_name)}#{Baza::Driver::Mysql::SEPARATOR_COLUMN}"
|
44
|
+
end
|
45
|
+
|
46
|
+
sql << ")"
|
47
|
+
end
|
48
|
+
|
49
|
+
[sql]
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Baza::Driver::Mysql::Sql::CreateTable
|
2
|
+
def initialize(args)
|
3
|
+
@name = args.fetch(:name)
|
4
|
+
@columns = args.fetch(:columns)
|
5
|
+
@indexes = args[:indexes]
|
6
|
+
@temporary = args[:temporary]
|
7
|
+
end
|
8
|
+
|
9
|
+
def sql
|
10
|
+
sql = "CREATE"
|
11
|
+
sql << " TEMPORARY" if @temporary
|
12
|
+
sql << " TABLE #{Baza::Driver::Mysql::SEPARATOR_TABLE}#{Baza::Driver::Mysql.escape_table(@name)}#{Baza::Driver::Mysql::SEPARATOR_TABLE} ("
|
13
|
+
|
14
|
+
first = true
|
15
|
+
@columns.each do |col_data|
|
16
|
+
sql << ", " unless first
|
17
|
+
first = false if first
|
18
|
+
col_data.delete(:after) if col_data[:after]
|
19
|
+
|
20
|
+
sql << Baza::Driver::Mysql::Sql::Column.new(col_data).sql.first
|
21
|
+
end
|
22
|
+
|
23
|
+
if @indexes && !@indexes.empty?
|
24
|
+
sql << ", "
|
25
|
+
sql << Baza::Driver::Mysql::Sql::CreateIndexes.new(
|
26
|
+
indexes: @indexes,
|
27
|
+
create: false,
|
28
|
+
on_table: false,
|
29
|
+
table_name: @name
|
30
|
+
).sql.first
|
31
|
+
end
|
32
|
+
|
33
|
+
sql << ")"
|
34
|
+
|
35
|
+
[sql]
|
36
|
+
end
|
37
|
+
end
|
@@ -9,15 +9,31 @@ class Baza::Driver::Pg::Columns
|
|
9
9
|
raise "Invalid key: '#{key}' (#{key.class.name})." unless DATA_SQL_ALLOWED_KEYS.include?(key)
|
10
10
|
end
|
11
11
|
|
12
|
+
maxlength = data[:maxlength]
|
13
|
+
|
12
14
|
raise "No type given." unless data[:type]
|
13
15
|
type = data[:type].to_sym
|
14
|
-
type = :serial if type == :int && data[:autoincr]
|
15
16
|
type = :timestamp if type == :datetime
|
16
17
|
|
18
|
+
if type == :int && data[:autoincr]
|
19
|
+
type = :serial
|
20
|
+
maxlength = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
if type == :int
|
24
|
+
type = :integer
|
25
|
+
maxlength = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
if type == :tinyint
|
29
|
+
type = :smallint
|
30
|
+
maxlength = nil
|
31
|
+
end
|
32
|
+
|
17
33
|
data[:maxlength] = 255 if type == :varchar && !data.key?(:maxlength)
|
18
34
|
|
19
35
|
sql = "#{@db.sep_col}#{@db.escape_column(data.fetch(:name))}#{@db.sep_col} #{type}"
|
20
|
-
sql << "(#{
|
36
|
+
sql << "(#{maxlength})" if maxlength
|
21
37
|
sql << " PRIMARY KEY" if data[:primarykey]
|
22
38
|
sql << " NOT NULL" if data.key?(:null) && !data[:null]
|
23
39
|
|
@@ -63,31 +63,9 @@ class Baza::Driver::Pg::Database < Baza::Database
|
|
63
63
|
CREATE_ALLOWED_KEYS = [:columns, :indexes, :temp, :return_sql].freeze
|
64
64
|
# Creates a new table by the given name and data.
|
65
65
|
def create_table(table_name, data, args = nil)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
sql = "CREATE"
|
70
|
-
sql << " TEMPORARY" if data[:temp]
|
71
|
-
sql << " TABLE #{db.sep_table}#{@db.escape_table(table_name)}#{db.sep_table} ("
|
72
|
-
|
73
|
-
first = true
|
74
|
-
data.fetch(:columns).each do |col_data|
|
75
|
-
sql << ", " unless first
|
76
|
-
first = false if first
|
77
|
-
col_data.delete(:after) if col_data[:after]
|
78
|
-
sql << @db.columns.data_sql(col_data)
|
79
|
-
end
|
80
|
-
|
81
|
-
sql << ")"
|
82
|
-
|
83
|
-
use { @db.query(sql) } if !args || !args[:return_sql]
|
84
|
-
|
85
|
-
if data[:indexes] && !data[:indexes].empty?
|
86
|
-
table = @db.tables[table_name]
|
87
|
-
table.create_indexes(data.fetch(:indexes))
|
66
|
+
use do
|
67
|
+
@db.tables.create(table_name, data, args)
|
88
68
|
end
|
89
|
-
|
90
|
-
return [sql] if args && args[:return_sql]
|
91
69
|
end
|
92
70
|
|
93
71
|
def rename(new_name)
|
@@ -1,5 +1,21 @@
|
|
1
1
|
class Baza::Driver::Pg::Indexes
|
2
|
+
attr_reader :db
|
3
|
+
|
2
4
|
def initialize(args)
|
3
5
|
@db = args.fetch(:db)
|
4
6
|
end
|
7
|
+
|
8
|
+
def create_index(index_list, args = {})
|
9
|
+
sqls = Baza::Driver::Pg::CreateIndexSqlCreator.new(db: db, indexes: index_list, create_args: args, on_table: args.fetch(:table_name)).sqls
|
10
|
+
|
11
|
+
unless args[:return_sql]
|
12
|
+
db.transaction do
|
13
|
+
sqls.each do |sql|
|
14
|
+
db.query(sql)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
sqls if args[:return_sql]
|
20
|
+
end
|
5
21
|
end
|
data/lib/baza/driver/pg/table.rb
CHANGED
@@ -160,22 +160,7 @@ class Baza::Driver::Pg::Table < Baza::Table
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def create_indexes(index_list, args = {})
|
163
|
-
|
164
|
-
end
|
165
|
-
|
166
|
-
def self.create_indexes(index_list, args = {})
|
167
|
-
db = args.fetch(:db)
|
168
|
-
sqls = Baza::Driver::Pg::CreateIndexSqlCreator.new(db: db, indexes: index_list, create_args: args).sqls
|
169
|
-
|
170
|
-
unless args[:return_sql]
|
171
|
-
db.transaction do
|
172
|
-
sqls.each do |sql|
|
173
|
-
db.query(sql)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
sqls if args[:return_sql]
|
163
|
+
db.indexes.create_index(index_list, args.merge(table_name: name))
|
179
164
|
end
|
180
165
|
|
181
166
|
def rename(new_name)
|
@@ -39,7 +39,39 @@ class Baza::Driver::Pg::Tables
|
|
39
39
|
tables_list
|
40
40
|
end
|
41
41
|
|
42
|
-
def create(
|
43
|
-
|
42
|
+
def create(table_name, data, args = nil)
|
43
|
+
table_name = table_name.to_s
|
44
|
+
raise "Invalid table name: #{table_name}" if table_name.strip.empty?
|
45
|
+
raise "No columns was given for '#{table_name}'." if !data[:columns] || data[:columns].empty?
|
46
|
+
|
47
|
+
create_table_sql = "CREATE"
|
48
|
+
create_table_sql << " TEMPORARY" if data[:temp]
|
49
|
+
create_table_sql << " TABLE #{db.sep_table}#{db.escape_table(table_name)}#{db.sep_table} ("
|
50
|
+
|
51
|
+
first = true
|
52
|
+
data.fetch(:columns).each do |col_data|
|
53
|
+
create_table_sql << ", " unless first
|
54
|
+
first = false if first
|
55
|
+
col_data.delete(:after) if col_data[:after]
|
56
|
+
create_table_sql << db.columns.data_sql(col_data)
|
57
|
+
end
|
58
|
+
|
59
|
+
create_table_sql << ")"
|
60
|
+
|
61
|
+
sqls = [create_table_sql]
|
62
|
+
|
63
|
+
if data[:indexes] && !data[:indexes].empty?
|
64
|
+
sqls += db.indexes.create_index(data.fetch(:indexes), table_name: table_name, return_sql: true)
|
65
|
+
end
|
66
|
+
|
67
|
+
if !args || !args[:return_sql]
|
68
|
+
db.transaction do
|
69
|
+
sqls.each do |sql|
|
70
|
+
db.query(sql)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
sqls
|
75
|
+
end
|
44
76
|
end
|
45
77
|
end
|
data/lib/baza/driver/pg.rb
CHANGED
@@ -46,11 +46,23 @@ class Baza::Driver::Pg < Baza::BaseSqlDriver
|
|
46
46
|
|
47
47
|
if db.opts[:conn]
|
48
48
|
@conn = db.opts.fetch(:conn)
|
49
|
-
|
49
|
+
elsif db.opts[:db]
|
50
50
|
reconnect
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
def connected?
|
55
|
+
@conn ? true : false
|
56
|
+
end
|
57
|
+
|
58
|
+
def escape(string)
|
59
|
+
if @conn
|
60
|
+
@conn.escape_string(string.to_s)
|
61
|
+
else
|
62
|
+
PG::Connection.escape_string(string.to_s)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
54
66
|
def reconnect
|
55
67
|
require "pg" unless ::Object.const_defined?(:PG)
|
56
68
|
|
data/lib/baza/dump.rb
CHANGED
@@ -5,8 +5,15 @@ class Baza::Dump
|
|
5
5
|
# dump = Baza::Dump.new(:db => db)
|
6
6
|
def initialize(args)
|
7
7
|
@db = args.fetch(:db)
|
8
|
+
@db_type = args[:db_type]
|
8
9
|
@debug = args[:debug]
|
9
10
|
@tables = args[:tables]
|
11
|
+
|
12
|
+
if @db_type
|
13
|
+
@export_db = Baza::Db.new(type: @db_type)
|
14
|
+
else
|
15
|
+
@export_db = @db
|
16
|
+
end
|
10
17
|
end
|
11
18
|
|
12
19
|
# Method used to update the status.
|
@@ -24,12 +31,6 @@ class Baza::Dump
|
|
24
31
|
debug "Going through tables."
|
25
32
|
@rows_count = 0
|
26
33
|
|
27
|
-
if @tables
|
28
|
-
tables = @tables
|
29
|
-
else
|
30
|
-
tables = @db.tables.list
|
31
|
-
end
|
32
|
-
|
33
34
|
if @on_status
|
34
35
|
@on_status.call(text: "Preparing.")
|
35
36
|
|
@@ -39,10 +40,7 @@ class Baza::Dump
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
42
|
-
|
43
|
-
table_obj = @db.tables[table_obj] if table_obj.is_a?(String) || table_obj.is_a?(Symbol)
|
44
|
-
next if table_obj.native?
|
45
|
-
|
43
|
+
each_table do |table_obj|
|
46
44
|
# Figure out keys.
|
47
45
|
@keys = []
|
48
46
|
table_obj.columns do |col|
|
@@ -54,6 +52,8 @@ class Baza::Dump
|
|
54
52
|
debug "Dumping table: '#{table_obj.name}'."
|
55
53
|
dump_table(io, table_obj)
|
56
54
|
end
|
55
|
+
|
56
|
+
dump_foreign_keys(io)
|
57
57
|
end
|
58
58
|
|
59
59
|
# A block can be executed when a new status occurs.
|
@@ -71,7 +71,7 @@ class Baza::Dump
|
|
71
71
|
create_data.delete(:name)
|
72
72
|
|
73
73
|
# Get SQL for creating table and add it to IO.
|
74
|
-
sqls = @
|
74
|
+
sqls = @export_db.tables.create(table_obj.name, create_data, return_sql: true)
|
75
75
|
sqls.each do |sql|
|
76
76
|
io.write("#{sql};\n")
|
77
77
|
end
|
@@ -94,7 +94,7 @@ class Baza::Dump
|
|
94
94
|
|
95
95
|
|
96
96
|
@db.select(table_obj.name, nil, unbuffered: true) do |row|
|
97
|
-
rows << row
|
97
|
+
rows << row
|
98
98
|
@rows_count += 1
|
99
99
|
|
100
100
|
if rows.length >= 1000
|
@@ -111,7 +111,13 @@ class Baza::Dump
|
|
111
111
|
# Dumps the given rows from the given table into the given IO.
|
112
112
|
def dump_insert_multi(io, table_obj, rows)
|
113
113
|
debug "Inserting #{rows.length} into #{table_obj.name}."
|
114
|
-
sqls = @
|
114
|
+
sqls = @export_db.insert_multi(
|
115
|
+
table_obj.name,
|
116
|
+
rows,
|
117
|
+
replace_line_breaks: true,
|
118
|
+
return_sql: true,
|
119
|
+
keys: @keys
|
120
|
+
)
|
115
121
|
sqls.each do |sql|
|
116
122
|
io.write("#{sql};\n")
|
117
123
|
end
|
@@ -121,4 +127,28 @@ class Baza::Dump
|
|
121
127
|
# Ensure garbage collection or we might start using A LOT of memory.
|
122
128
|
GC.start
|
123
129
|
end
|
130
|
+
|
131
|
+
def dump_foreign_keys(_io)
|
132
|
+
each_table do |table|
|
133
|
+
next unless table.respond_to?(:foreign_keys)
|
134
|
+
|
135
|
+
table.foreign_keys.each do |foreign_key|
|
136
|
+
# Dump foreign key
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def each_table
|
142
|
+
if @tables
|
143
|
+
tables = @tables
|
144
|
+
else
|
145
|
+
tables = @db.tables.list
|
146
|
+
end
|
147
|
+
|
148
|
+
tables.each do |table_obj|
|
149
|
+
table_obj = @db.tables[table_obj] if table_obj.is_a?(String) || table_obj.is_a?(Symbol)
|
150
|
+
next if table_obj.native?
|
151
|
+
yield table_obj
|
152
|
+
end
|
153
|
+
end
|
124
154
|
end
|
@@ -6,6 +6,7 @@ class Baza::SqlQueries::GenericInsert
|
|
6
6
|
@buffer = args[:buffer]
|
7
7
|
@return_sql = args[:return_sql]
|
8
8
|
@return_id = args[:return_id]
|
9
|
+
@replace_line_breaks = args[:replace_line_breaks]
|
9
10
|
end
|
10
11
|
|
11
12
|
def execute
|
@@ -72,10 +73,23 @@ private
|
|
72
73
|
sql << ", "
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
+
quoted = @db.sqlval(value)
|
77
|
+
quoted = convert_line_breaks(quoted) if @replace_line_breaks
|
78
|
+
|
79
|
+
sql << quoted
|
76
80
|
end
|
77
81
|
|
78
82
|
sql << ")"
|
79
83
|
sql
|
80
84
|
end
|
85
|
+
|
86
|
+
def convert_line_breaks(quoted)
|
87
|
+
return quoted unless quoted.include?("\n")
|
88
|
+
|
89
|
+
if @db.postgres?
|
90
|
+
quoted.gsub("\n", "' || CHR(10) || '")
|
91
|
+
else
|
92
|
+
"CONCAT(#{quoted.gsub("\n", "', CHR(10), '")}"
|
93
|
+
end
|
94
|
+
end
|
81
95
|
end
|
@@ -62,10 +62,10 @@ private
|
|
62
62
|
|
63
63
|
first = true
|
64
64
|
@updates.keys.each do |column_name|
|
65
|
-
sql << ", "
|
65
|
+
sql << ", " unless first
|
66
66
|
first = false if first
|
67
67
|
|
68
|
-
sql << "
|
68
|
+
sql << "#{@db.sep_col}#{@db.escape_column(column_name)}#{@db.sep_col}"
|
69
69
|
end
|
70
70
|
|
71
71
|
sql
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Baza::SqlQueries::GenericInsert do
|
4
|
+
let(:constant) do
|
5
|
+
const_name = "InfoPg"
|
6
|
+
require StringCases.camel_to_snake(const_name)
|
7
|
+
raise "Constant was not defined: '#{const_name}'." unless Baza.const_defined?(const_name)
|
8
|
+
Baza.const_get(const_name)
|
9
|
+
end
|
10
|
+
let(:db) { constant.new.db }
|
11
|
+
|
12
|
+
describe "#convert_line_breaks" do
|
13
|
+
it "converts line breaks to valid postgres sql" do
|
14
|
+
generic_insert = Baza::SqlQueries::GenericInsert.new(
|
15
|
+
db: db,
|
16
|
+
table_name: "test_table",
|
17
|
+
data: {
|
18
|
+
"test_column" => "data\nwith\nline\nbreaks"
|
19
|
+
},
|
20
|
+
replace_line_breaks: true
|
21
|
+
)
|
22
|
+
|
23
|
+
expect(generic_insert.to_sql).to eq "INSERT INTO \"test_table\" (\"test_column\") VALUES ('data' || CHR(10) || 'with' || CHR(10) || 'line' || CHR(10) || 'breaks')"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Baza::Driver::Pg::Columns do
|
4
|
+
let(:constant) do
|
5
|
+
const_name = "InfoPg"
|
6
|
+
require StringCases.camel_to_snake(const_name)
|
7
|
+
raise "Constant was not defined: '#{const_name}'." unless Baza.const_defined?(const_name)
|
8
|
+
Baza.const_get(const_name)
|
9
|
+
end
|
10
|
+
let(:db) { constant.new.db }
|
11
|
+
|
12
|
+
describe "#data_sql" do
|
13
|
+
it "convert int(11) to integer" do
|
14
|
+
result = db.columns.data_sql(
|
15
|
+
name: "test",
|
16
|
+
type: :int,
|
17
|
+
maxlength: 11
|
18
|
+
)
|
19
|
+
|
20
|
+
expect(result).to eq '"test" integer'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "converts int with auto increment to serial" do
|
24
|
+
result = db.columns.data_sql(
|
25
|
+
name: "test",
|
26
|
+
type: :int,
|
27
|
+
maxlength: 11,
|
28
|
+
autoincr: true
|
29
|
+
)
|
30
|
+
|
31
|
+
expect(result).to eq '"test" serial'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "converts tinyint to smallint" do
|
35
|
+
result = db.columns.data_sql(
|
36
|
+
name: "test",
|
37
|
+
type: :tinyint,
|
38
|
+
maxlength: 11,
|
39
|
+
autoincr: true
|
40
|
+
)
|
41
|
+
|
42
|
+
expect(result).to eq '"test" smallint'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: baza
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kasper Johansen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03
|
11
|
+
date: 2017-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: array_enumerator
|
@@ -372,6 +372,10 @@ files:
|
|
372
372
|
- lib/baza/driver/mysql/index.rb
|
373
373
|
- lib/baza/driver/mysql/indexes.rb
|
374
374
|
- lib/baza/driver/mysql/result.rb
|
375
|
+
- lib/baza/driver/mysql/sql.rb
|
376
|
+
- lib/baza/driver/mysql/sql/column.rb
|
377
|
+
- lib/baza/driver/mysql/sql/create_indexes.rb
|
378
|
+
- lib/baza/driver/mysql/sql/create_table.rb
|
375
379
|
- lib/baza/driver/mysql/sqlspecs.rb
|
376
380
|
- lib/baza/driver/mysql/table.rb
|
377
381
|
- lib/baza/driver/mysql/tables.rb
|
@@ -464,12 +468,14 @@ files:
|
|
464
468
|
- lib/baza/table.rb
|
465
469
|
- spec/active_record/models/user.rb
|
466
470
|
- spec/baza/cloner_spec.rb
|
471
|
+
- spec/baza/sql_queries/generic_insert_spec.rb
|
467
472
|
- spec/drivers/active_record_mysql2_spec.rb
|
468
473
|
- spec/drivers/active_record_mysql_spec.rb
|
469
474
|
- spec/drivers/active_record_pg_spec.rb
|
470
475
|
- spec/drivers/active_record_sqlite3_spec.rb
|
471
476
|
- spec/drivers/mysql2_spec.rb
|
472
477
|
- spec/drivers/mysql_spec.rb
|
478
|
+
- spec/drivers/pg/columns_spec.rb
|
473
479
|
- spec/drivers/pg_spec.rb
|
474
480
|
- spec/drivers/sqlite3_spec.rb
|
475
481
|
- spec/info_active_record_example.rb
|