baza 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +84 -0
  3. data/.rubocop_todo.yml +17 -135
  4. data/.travis.yml +21 -0
  5. data/Gemfile +10 -7
  6. data/Gemfile.lock +39 -44
  7. data/README.md +61 -3
  8. data/VERSION +1 -1
  9. data/baza.gemspec +146 -98
  10. data/config/best_project_practice_rubocop.yml +8 -0
  11. data/config/best_project_practice_rubocop_todo.yml +6 -0
  12. data/lib/baza.rb +8 -12
  13. data/lib/baza/base_sql_driver.rb +198 -52
  14. data/lib/baza/cloner.rb +1 -0
  15. data/lib/baza/column.rb +26 -0
  16. data/lib/baza/database.rb +19 -3
  17. data/lib/baza/db.rb +69 -271
  18. data/lib/baza/driver.rb +1 -6
  19. data/lib/baza/{drivers → driver}/active_record.rb +65 -21
  20. data/lib/baza/{drivers → driver}/active_record/columns.rb +0 -0
  21. data/lib/baza/driver/active_record/commands.rb +10 -0
  22. data/lib/baza/driver/active_record/databases.rb +10 -0
  23. data/lib/baza/{drivers → driver}/active_record/indexes.rb +0 -0
  24. data/lib/baza/{drivers → driver}/active_record/result.rb +3 -1
  25. data/lib/baza/{drivers → driver}/active_record/tables.rb +0 -0
  26. data/lib/baza/driver/active_record/users.rb +12 -0
  27. data/lib/baza/{drivers → driver}/mysql.rb +9 -26
  28. data/lib/baza/{drivers → driver}/mysql/column.rb +14 -35
  29. data/lib/baza/{drivers → driver}/mysql/columns.rb +9 -12
  30. data/lib/baza/driver/mysql/commands.rb +39 -0
  31. data/lib/baza/driver/mysql/database.rb +64 -0
  32. data/lib/baza/driver/mysql/databases.rb +63 -0
  33. data/lib/baza/{drivers → driver}/mysql/index.rb +0 -0
  34. data/lib/baza/{drivers → driver}/mysql/indexes.rb +0 -0
  35. data/lib/baza/{drivers → driver}/mysql/result.rb +15 -7
  36. data/lib/baza/{drivers → driver}/mysql/sqlspecs.rb +0 -0
  37. data/lib/baza/{drivers → driver}/mysql/table.rb +27 -43
  38. data/lib/baza/{drivers → driver}/mysql/tables.rb +5 -34
  39. data/lib/baza/{drivers → driver}/mysql/unbuffered_result.rb +8 -2
  40. data/lib/baza/driver/mysql/user.rb +22 -0
  41. data/lib/baza/driver/mysql/users.rb +39 -0
  42. data/lib/baza/{drivers → driver}/mysql2.rb +19 -49
  43. data/lib/baza/{drivers → driver}/mysql2/column.rb +0 -0
  44. data/lib/baza/{drivers → driver}/mysql2/columns.rb +0 -0
  45. data/lib/baza/driver/mysql2/commands.rb +2 -0
  46. data/lib/baza/{drivers → driver}/mysql2/database.rb +0 -0
  47. data/lib/baza/{drivers → driver}/mysql2/databases.rb +0 -0
  48. data/lib/baza/{drivers → driver}/mysql2/index.rb +0 -0
  49. data/lib/baza/{drivers → driver}/mysql2/indexes.rb +0 -0
  50. data/lib/baza/{drivers → driver}/mysql2/result.rb +3 -1
  51. data/lib/baza/{drivers → driver}/mysql2/table.rb +0 -0
  52. data/lib/baza/{drivers → driver}/mysql2/tables.rb +0 -0
  53. data/lib/baza/driver/mysql2/user.rb +2 -0
  54. data/lib/baza/driver/mysql2/users.rb +2 -0
  55. data/lib/baza/{drivers → driver}/mysql_java.rb +60 -38
  56. data/lib/baza/{drivers → driver}/mysql_java/column.rb +0 -0
  57. data/lib/baza/{drivers → driver}/mysql_java/columns.rb +0 -0
  58. data/lib/baza/driver/mysql_java/commands.rb +2 -0
  59. data/lib/baza/driver/mysql_java/database.rb +2 -0
  60. data/lib/baza/driver/mysql_java/databases.rb +2 -0
  61. data/lib/baza/{drivers → driver}/mysql_java/index.rb +0 -0
  62. data/lib/baza/{drivers → driver}/mysql_java/indexes.rb +0 -0
  63. data/lib/baza/{drivers → driver}/mysql_java/table.rb +0 -0
  64. data/lib/baza/{drivers → driver}/mysql_java/tables.rb +0 -0
  65. data/lib/baza/driver/mysql_java/user.rb +2 -0
  66. data/lib/baza/driver/mysql_java/users.rb +2 -0
  67. data/lib/baza/driver/pg.rb +80 -0
  68. data/lib/baza/driver/pg/column.rb +125 -0
  69. data/lib/baza/driver/pg/columns.rb +37 -0
  70. data/lib/baza/driver/pg/commands.rb +35 -0
  71. data/lib/baza/driver/pg/create_index_sql_creator.rb +51 -0
  72. data/lib/baza/driver/pg/database.rb +89 -0
  73. data/lib/baza/driver/pg/databases.rb +79 -0
  74. data/lib/baza/driver/pg/index.rb +35 -0
  75. data/lib/baza/driver/pg/indexes.rb +5 -0
  76. data/lib/baza/driver/pg/result.rb +139 -0
  77. data/lib/baza/driver/pg/table.rb +184 -0
  78. data/lib/baza/driver/pg/tables.rb +45 -0
  79. data/lib/baza/{drivers → driver}/sqlite3.rb +6 -24
  80. data/lib/baza/{drivers → driver}/sqlite3/column.rb +22 -24
  81. data/lib/baza/{drivers → driver}/sqlite3/columns.rb +6 -6
  82. data/lib/baza/driver/sqlite3/commands.rb +28 -0
  83. data/lib/baza/{drivers → driver}/sqlite3/database.rb +0 -0
  84. data/lib/baza/{drivers → driver}/sqlite3/databases.rb +0 -1
  85. data/lib/baza/{drivers → driver}/sqlite3/index.rb +0 -0
  86. data/lib/baza/{drivers → driver}/sqlite3/indexes.rb +0 -0
  87. data/lib/baza/{drivers → driver}/sqlite3/result.rb +14 -6
  88. data/lib/baza/{drivers → driver}/sqlite3/sqlspecs.rb +0 -0
  89. data/lib/baza/{drivers → driver}/sqlite3/table.rb +25 -16
  90. data/lib/baza/{drivers → driver}/sqlite3/tables.rb +5 -6
  91. data/lib/baza/{drivers → driver}/sqlite3/unbuffered_result.rb +8 -2
  92. data/lib/baza/{drivers → driver}/sqlite3_java.rb +13 -23
  93. data/lib/baza/{drivers → driver}/sqlite3_java/column.rb +0 -0
  94. data/lib/baza/{drivers → driver}/sqlite3_java/columns.rb +0 -0
  95. data/lib/baza/driver/sqlite3_java/commands.rb +2 -0
  96. data/lib/baza/{drivers → driver}/sqlite3_java/database.rb +0 -0
  97. data/lib/baza/{drivers → driver}/sqlite3_java/index.rb +0 -0
  98. data/lib/baza/{drivers → driver}/sqlite3_java/indexes.rb +0 -0
  99. data/lib/baza/{drivers → driver}/sqlite3_java/table.rb +0 -0
  100. data/lib/baza/{drivers → driver}/sqlite3_java/tables.rb +0 -0
  101. data/lib/baza/{drivers → driver}/sqlite3_java/unbuffered_result.rb +14 -9
  102. data/lib/baza/{drivers → driver}/sqlite3_rhodes.rb +6 -24
  103. data/lib/baza/errors.rb +2 -0
  104. data/lib/baza/idquery.rb +15 -8
  105. data/lib/baza/index.rb +7 -0
  106. data/lib/baza/jdbc_driver.rb +4 -16
  107. data/lib/baza/jdbc_result.rb +20 -12
  108. data/lib/baza/mysql_base_driver.rb +7 -7
  109. data/lib/baza/query_buffer.rb +20 -19
  110. data/lib/baza/row.rb +16 -16
  111. data/lib/baza/sql_queries.rb +3 -0
  112. data/lib/baza/sql_queries/generic_insert.rb +81 -0
  113. data/lib/baza/sql_queries/generic_update.rb +31 -0
  114. data/lib/baza/sql_queries/mysql_upsert.rb +52 -0
  115. data/lib/baza/sql_queries/mysql_upsert_duplicate_key.rb +57 -0
  116. data/lib/baza/sql_queries/non_atomic_upsert.rb +25 -0
  117. data/lib/baza/sql_queries/postgres_upsert_duplicate_key.rb +118 -0
  118. data/lib/baza/sql_queries/select.rb +170 -0
  119. data/lib/baza/sql_queries/sqlite_upsert_duplicate_key.rb +99 -0
  120. data/lib/baza/table.rb +35 -8
  121. data/spec/active_record/models/user.rb +3 -0
  122. data/spec/{cloner_spec.rb → baza/cloner_spec.rb} +0 -0
  123. data/spec/drivers/active_record_mysql2_spec.rb +5 -3
  124. data/spec/drivers/active_record_mysql_spec.rb +2 -1
  125. data/spec/drivers/active_record_pg_spec.rb +20 -0
  126. data/spec/drivers/active_record_sqlite3_spec.rb +2 -1
  127. data/spec/drivers/mysql2_spec.rb +1 -1
  128. data/spec/drivers/mysql_spec.rb +10 -10
  129. data/spec/drivers/pg_spec.rb +18 -0
  130. data/spec/drivers/sqlite3_spec.rb +7 -8
  131. data/spec/info_active_record_example.rb +1 -1
  132. data/spec/{info_active_record_mysql2.rb → info_active_record_mysql2_example.rb} +3 -2
  133. data/spec/info_active_record_mysql2_travis.rb +35 -0
  134. data/spec/{info_active_record_mysql.rb → info_active_record_mysql_example.rb} +5 -4
  135. data/spec/info_active_record_mysql_travis.rb +36 -0
  136. data/spec/info_active_record_pg_example.rb +36 -0
  137. data/spec/info_active_record_pg_travis.rb +34 -0
  138. data/spec/info_active_record_sqlite3.rb +1 -1
  139. data/spec/info_mysql2_example.rb +1 -3
  140. data/spec/{info_mysql2_shippable.rb → info_mysql2_travis.rb} +2 -4
  141. data/spec/info_mysql_example.rb +1 -3
  142. data/spec/{info_mysql_shippable.rb → info_mysql_travis.rb} +2 -4
  143. data/spec/info_pg_example.rb +22 -0
  144. data/spec/info_pg_travis.rb +20 -0
  145. data/spec/info_sqlite3.rb +1 -3
  146. data/spec/spec_helper.rb +1 -1
  147. data/spec/support/driver_active_record_collection.rb +62 -0
  148. data/spec/support/driver_collection.rb +136 -121
  149. data/spec/support/driver_columns_collection.rb +19 -10
  150. data/spec/support/driver_databases_collection.rb +23 -1
  151. data/spec/support/driver_indexes_collection.rb +2 -2
  152. data/spec/support/driver_tables_collection.rb +24 -4
  153. data/spec/support/driver_users_collection.rb +53 -0
  154. metadata +185 -104
  155. data/lib/baza/drivers/mysql/database.rb +0 -28
  156. data/lib/baza/drivers/mysql/databases.rb +0 -35
  157. data/lib/baza/drivers/mysql_java/database.rb +0 -2
  158. data/lib/baza/drivers/mysql_java/databases.rb +0 -2
  159. data/lib/baza/model.rb +0 -875
  160. data/lib/baza/model_custom.rb +0 -155
  161. data/lib/baza/model_handler.rb +0 -910
  162. data/lib/baza/model_handler_sqlhelper.rb +0 -484
  163. data/lib/baza/revision.rb +0 -383
  164. data/shippable.yml +0 -17
  165. data/spec/info_active_record_mysql2_shippable.rb +0 -34
  166. data/spec/info_active_record_mysql_shippable.rb +0 -34
  167. data/spec/model_handler_spec.rb +0 -431
@@ -0,0 +1,2 @@
1
+ class Baza::Driver::MysqlJava::Users < Baza::Driver::Mysql::Users
2
+ end
@@ -0,0 +1,80 @@
1
+ class Baza::Driver::Pg < Baza::BaseSqlDriver
2
+ AutoAutoloader.autoload_sub_classes(self, __FILE__)
3
+
4
+ attr_reader :conn
5
+
6
+ def self.from_object(args)
7
+ if args[:object].class.name == "PG::Connection"
8
+ return {
9
+ type: :success,
10
+ args: {
11
+ type: :pg,
12
+ conn: args[:object]
13
+ }
14
+ }
15
+ end
16
+
17
+ nil
18
+ end
19
+
20
+ def self.args
21
+ [{
22
+ label: "Host",
23
+ name: "host"
24
+ }, {
25
+ label: "Port",
26
+ name: "port"
27
+ }, {
28
+ label: "Username",
29
+ name: "user"
30
+ }, {
31
+ label: "Password",
32
+ name: "pass"
33
+ }, {
34
+ label: "Database",
35
+ name: "db"
36
+ }]
37
+ end
38
+
39
+ def initialize(db)
40
+ super
41
+
42
+ @sep_database = '"'
43
+ @sep_table = '"'
44
+ @sep_col = '"'
45
+ @sep_index = '"'
46
+
47
+ if db.opts[:conn]
48
+ @conn = db.opts.fetch(:conn)
49
+ else
50
+ reconnect
51
+ end
52
+ end
53
+
54
+ def reconnect
55
+ require "pg" unless ::Object.const_defined?(:PG)
56
+
57
+ args = {dbname: db.opts.fetch(:db)}
58
+ args[:port] = db.opts.fetch(:port) if db.opts[:port]
59
+ args[:hostaddr] = db.opts.fetch(:host) if db.opts[:host]
60
+ args[:user] = db.opts.fetch(:user) if db.opts[:user]
61
+ args[:password] = db.opts.fetch(:pass) if db.opts[:pass]
62
+
63
+ @conn = PG::Connection.new(args)
64
+ end
65
+
66
+ def query(sql)
67
+ Baza::Driver::Pg::Result.new(self, @conn.exec(sql))
68
+ end
69
+
70
+ def query_ubuf(sql)
71
+ @conn.send_query(sql)
72
+ @conn.set_single_row_mode
73
+ result = @conn.get_result
74
+ Baza::Driver::Pg::Result.new(self, result, unbuffered: true)
75
+ end
76
+
77
+ def close
78
+ @conn.close
79
+ end
80
+ end
@@ -0,0 +1,125 @@
1
+ class Baza::Driver::Pg::Column < Baza::Column
2
+ attr_reader :name
3
+
4
+ def initialize(args)
5
+ @db = args.fetch(:db)
6
+ @data = args.fetch(:data)
7
+ @name = @data.fetch(:column_name)
8
+ end
9
+
10
+ def table_name
11
+ @data.fetch(:table_name)
12
+ end
13
+
14
+ def type
15
+ unless @type
16
+ type = @data.fetch(:udt_name)
17
+
18
+ if type == "int4"
19
+ @type = :int
20
+ else
21
+ @type = type.to_sym
22
+ end
23
+ end
24
+
25
+ @type
26
+ end
27
+
28
+ def maxlength
29
+ @data.fetch(:character_maximum_length)
30
+ end
31
+
32
+ def null?
33
+ @data.fetch(:is_nullable) == "YES"
34
+ end
35
+
36
+ def primarykey?
37
+ autoincr?
38
+ end
39
+
40
+ def autoincr?
41
+ !@data.fetch(:column_default).to_s.match(/\Anextval\('#{Regexp.escape(table_name)}_#{Regexp.escape(name)}_seq'::regclass\)\Z/).nil?
42
+ end
43
+
44
+ def default
45
+ return nil if autoincr?
46
+ @data.fetch(:column_default)
47
+ end
48
+
49
+ def drop
50
+ @db.query("ALTER TABLE #{@db.sep_table}#{@db.escape_table(table_name)}#{@db.sep_table} DROP COLUMN #{@db.sep_col}#{@db.escape_column(name)}#{@db.sep_col}")
51
+ nil
52
+ end
53
+
54
+ def reload
55
+ data = @db.single([:information_schema, :columns], table_name: table_name, column_name: name)
56
+ raise Baza::Errors::ColumnNotFound unless data
57
+ @data = data
58
+ end
59
+
60
+ def change(data)
61
+ if data.key?(:name) && data.fetch(:name).to_s != name
62
+ @db.query("#{alter_table_sql} RENAME #{col_escaped} TO #{@db.sep_col}#{@db.escape_column(data.fetch(:name))}#{@db.sep_col}")
63
+ @name = data.fetch(:name).to_s
64
+ end
65
+
66
+ change_type = true if data.key?(:type) && data.fetch(:type).to_s != type.to_s
67
+ change_type = true if data.key?(:maxlength) && data.fetch(:maxlength) != maxlength
68
+
69
+ if change_type
70
+ type = data[:type].to_s || type.to_s
71
+
72
+ if type == "int"
73
+ using = " USING (trim(#{name})::integer)"
74
+ else
75
+ using = ""
76
+ end
77
+
78
+ @db.query("#{alter_column_sql} TYPE #{data.fetch(:type)}#{using}")
79
+ @type = nil
80
+ changed = true
81
+ end
82
+
83
+ if data.key?(:null) && data.fetch(:null) != null?
84
+ if data.fetch(:null)
85
+ @db.query("#{alter_column_sql} DROP NOT NULL")
86
+ else
87
+ @db.query("#{alter_column_sql} ADD NOT NULL")
88
+ end
89
+
90
+ changed = true
91
+ end
92
+
93
+ if data.key?(:default) && data.fetch(:default) != default
94
+ if data.fetch(:default).nil?
95
+ @db.query("#{alter_column_sql} DROP DEFAULT")
96
+ else
97
+ default = "'#{@db.esc(data.fetch(:default))}'"
98
+ @db.query("#{alter_column_sql} SET DEFAULT #{default}")
99
+ end
100
+
101
+ changed = true
102
+ end
103
+
104
+ reload if changed
105
+ self
106
+ end
107
+
108
+ private
109
+
110
+ def col_escaped
111
+ "#{@db.sep_col}#{@db.escape_column(name)}#{@db.sep_col}"
112
+ end
113
+
114
+ def table_escaped
115
+ "#{@db.sep_table}#{@db.escape_table(table_name)}#{@db.sep_table}"
116
+ end
117
+
118
+ def alter_table_sql
119
+ "ALTER TABLE #{table_escaped}"
120
+ end
121
+
122
+ def alter_column_sql
123
+ "#{alter_table_sql} ALTER COLUMN #{col_escaped}"
124
+ end
125
+ end
@@ -0,0 +1,37 @@
1
+ class Baza::Driver::Pg::Columns
2
+ def initialize(args)
3
+ @db = args.fetch(:db)
4
+ end
5
+
6
+ DATA_SQL_ALLOWED_KEYS = [:type, :maxlength, :name, :primarykey, :autoincr, :default, :comment, :after, :first, :storage, :null, :renames].freeze
7
+ def data_sql(data)
8
+ data.each_key do |key|
9
+ raise "Invalid key: '#{key}' (#{key.class.name})." unless DATA_SQL_ALLOWED_KEYS.include?(key)
10
+ end
11
+
12
+ raise "No type given." unless data[:type]
13
+ type = data[:type].to_sym
14
+ type = :serial if type == :int && data[:autoincr]
15
+ type = :timestamp if type == :datetime
16
+
17
+ data[:maxlength] = 255 if type == :varchar && !data.key?(:maxlength)
18
+
19
+ sql = "#{@db.sep_col}#{@db.escape_column(data.fetch(:name))}#{@db.sep_col} #{type}"
20
+ sql << "(#{data[:maxlength]})" if data[:maxlength]
21
+ sql << " PRIMARY KEY" if data[:primarykey]
22
+ sql << " NOT NULL" if data.key?(:null) && !data[:null]
23
+
24
+ if data.key?(:default_func)
25
+ sql << " DEFAULT #{data[:default_func]}"
26
+ elsif data.key?(:default) && data[:default]
27
+ sql << " DEFAULT #{@db.sqlval(data.fetch(:default))}"
28
+ end
29
+
30
+ sql << " COMMENT '#{@db.escape(data.fetch(:comment))}'" if data.key?(:comment)
31
+ sql << " AFTER #{@db.sep_col}#{@db.escape_column(data.fetch(:after))}#{@db.sep_col}" if data[:after] && !data[:first]
32
+ sql << " FIRST" if data[:first]
33
+ sql << " STORAGE #{data[:storage].to_s.upcase}" if data[:storage]
34
+
35
+ sql
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ class Baza::Driver::Pg::Commands
2
+ def initialize(args)
3
+ @db = args.fetch(:db)
4
+ end
5
+
6
+ def upsert_duplicate_key(table_name, updates, terms, args = {})
7
+ @last_insert_table_name = table_name.to_s
8
+
9
+ Baza::SqlQueries::PostgresUpsertDuplicateKey.new({
10
+ db: @db,
11
+ table_name: table_name,
12
+ updates: updates,
13
+ terms: terms
14
+ }.merge(args)).execute
15
+ end
16
+
17
+ def upsert(table_name, updates, terms, args = {})
18
+ @last_insert_table_name = table_name.to_s
19
+
20
+ Baza::SqlQueries::NonAtomicUpsert.new({
21
+ db: @db,
22
+ table_name: table_name,
23
+ terms: terms,
24
+ updates: updates
25
+ }.merge(args)).execute
26
+ end
27
+
28
+ def last_id
29
+ @db.query("SELECT LASTVAL() AS id").fetch.fetch(:id).to_i
30
+ end
31
+
32
+ def version
33
+ @version ||= @db.query("SELECT VERSION() AS version").fetch.fetch(:version).match(/\APostgreSQL ([\d\.]+)/)[1]
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ class Baza::Driver::Pg::CreateIndexSqlCreator
2
+ def initialize(args)
3
+ @db = args.fetch(:db)
4
+ @indexes = args.fetch(:indexes)
5
+ @create_args = args.fetch(:create_args)
6
+ end
7
+
8
+ def sqls
9
+ sqls = []
10
+ @indexes.each do |index_data|
11
+ sqls << create_sql(index_data, @create_args)
12
+ end
13
+
14
+ sqls
15
+ end
16
+
17
+ def name_from_table_and_columns(table_name, column_names)
18
+ "index_on_#{table_name}_#{column_names.join("_")}"
19
+ end
20
+
21
+ def create_sql(index_data, args)
22
+ sql = ""
23
+ sql << "CREATE" if args[:create] || !args.key?(:create)
24
+
25
+ if index_data.is_a?(String) || index_data.is_a?(Symbol)
26
+ index_data = {name: index_data, columns: [index_data]}
27
+ elsif index_data[:name].to_s.strip.empty?
28
+ index_data[:name] = name_from_table_and_columns(args[:table_name] || name, index_data.fetch(:columns))
29
+ end
30
+
31
+ raise "No columns was given on index: '#{index_data.fetch(:name)}'." if !index_data[:columns] || index_data[:columns].empty?
32
+
33
+ sql << " UNIQUE" if index_data[:unique]
34
+ sql << " INDEX #{@db.sep_index}#{@db.escape_index(index_data.fetch(:name))}#{@db.sep_index}"
35
+
36
+ if args[:on_table] || !args.key?(:on_table)
37
+ sql << " ON #{@db.sep_table}#{@db.escape_table(args.fetch(:table_name))}#{@db.sep_table}"
38
+ end
39
+
40
+ sql << " ("
41
+
42
+ first = true
43
+ index_data.fetch(:columns).each do |col_name|
44
+ sql << ", " unless first
45
+ first = false if first
46
+ sql << "#{@db.sep_col}#{@db.escape_column(col_name)}#{@db.sep_col}"
47
+ end
48
+
49
+ sql << ")"
50
+ end
51
+ end
@@ -0,0 +1,89 @@
1
+ class Baza::Driver::Pg::Database < Baza::Database
2
+ def save!
3
+ rename(name) unless name.to_s == name_was
4
+ self
5
+ end
6
+
7
+ def drop
8
+ @db.query("DROP DATABASE #{@db.sep_database}#{@db.escape_database(name)}#{@db.sep_database}")
9
+ self
10
+ end
11
+
12
+ def table(table_name)
13
+ table = tables(name: table_name).first
14
+ raise Baza::Errors::TableNotFound unless table
15
+ table
16
+ end
17
+
18
+ def tables(args = {})
19
+ tables_list = [] unless block_given?
20
+
21
+ where_args = {
22
+ table_catalog: name,
23
+ table_schema: "public"
24
+ }
25
+ where_args[:table_name] = args.fetch(:name) if args[:name]
26
+
27
+ use do
28
+ @db.select([:information_schema, :tables], where_args, orderby: :table_name) do |table_data|
29
+ table = Baza::Driver::Pg::Table.new(
30
+ driver: @db.driver,
31
+ data: table_data
32
+ )
33
+
34
+ next if table.native?
35
+
36
+ if tables_list
37
+ tables_list << table
38
+ else
39
+ yield table
40
+ end
41
+ end
42
+ end
43
+
44
+ tables_list
45
+ end
46
+
47
+ def use(&blk)
48
+ @db.with_database(name, &blk)
49
+ self
50
+ end
51
+
52
+ CREATE_ALLOWED_KEYS = [:columns, :indexes, :temp, :return_sql].freeze
53
+ # Creates a new table by the given name and data.
54
+ def create_table(table_name, data, args = nil)
55
+ table_name = table_name.to_s
56
+ raise "No columns was given for '#{name}'." if !data[:columns] || data[:columns].empty?
57
+
58
+ sql = "CREATE"
59
+ sql << " TEMPORARY" if data[:temp]
60
+ sql << " TABLE #{db.sep_table}#{@db.escape_table(table_name)}#{db.sep_table} ("
61
+
62
+ first = true
63
+ data.fetch(:columns).each do |col_data|
64
+ sql << ", " unless first
65
+ first = false if first
66
+ col_data.delete(:after) if col_data[:after]
67
+ sql << @db.columns.data_sql(col_data)
68
+ end
69
+
70
+ sql << ")"
71
+
72
+ use { @db.query(sql) } if !args || !args[:return_sql]
73
+
74
+ if data[:indexes] && !data[:indexes].empty?
75
+ table = @db.tables[table_name]
76
+ table.create_indexes(data.fetch(:indexes))
77
+ end
78
+
79
+ return [sql] if args && args[:return_sql]
80
+ end
81
+
82
+ private
83
+
84
+ def rename(new_name)
85
+ @db.query("ALTER DATABASE #{@db.sep_database}#{@db.escape_database(name_was)}#{@db.sep_database} RENAME TO #{@db.sep_database}#{@db.escape_database(new_name)}#{@db.sep_database}")
86
+ @name = new_name.to_s
87
+ self
88
+ end
89
+ end
@@ -0,0 +1,79 @@
1
+ class Baza::Driver::Pg::Databases
2
+ def initialize(args)
3
+ @db = args.fetch(:db)
4
+ end
5
+
6
+ def current_database
7
+ @db.databases[current_database_name]
8
+ end
9
+
10
+ def current_database_name
11
+ @db.query("SELECT current_database()").fetch.values.first
12
+ end
13
+
14
+ def create(args)
15
+ if args[:if_not_exists]
16
+ begin
17
+ __send__(:[], args.fetch(:name).to_s)
18
+ return true
19
+ # rubocop:disable Lint/HandleExceptions
20
+ rescue Baza::Errors::DatabaseNotFound
21
+ # rubocop:enable Lint/HandleExceptions
22
+ end
23
+ end
24
+
25
+ @db.query("CREATE DATABASE #{@db.sep_database}#{@db.escape_table(args.fetch(:name))}#{@db.sep_database}")
26
+ true
27
+ end
28
+
29
+ def [](name)
30
+ database = list(name: name).first
31
+ raise Baza::Errors::DatabaseNotFound unless database
32
+ database
33
+ end
34
+
35
+ def list(args = {})
36
+ where_args = {}
37
+ where_args[:datname] = args.fetch(:name) if args[:name]
38
+
39
+ database_list = [] unless block_given?
40
+ @db.select(:pg_database, where_args) do |database_data|
41
+ database = Baza::Driver::Pg::Database.new(
42
+ db: @db,
43
+ driver: @db.driver,
44
+ name: database_data.fetch(:datname)
45
+ )
46
+
47
+ if database_list
48
+ database_list << database
49
+ else
50
+ yield database
51
+ end
52
+ end
53
+
54
+ database_list
55
+ end
56
+
57
+ def with_database(name)
58
+ if @db.opts[:db].to_s == name
59
+ yield if block_given?
60
+ return self
61
+ end
62
+
63
+ previous_db_name = @db.current_database_name
64
+
65
+ @db.opts[:db] = name
66
+ @db.driver.reconnect
67
+
68
+ if block_given?
69
+ begin
70
+ yield
71
+ ensure
72
+ @db.opts[:db] = previous_db_name
73
+ @db.driver.reconnect
74
+ end
75
+ end
76
+
77
+ self
78
+ end
79
+ end