schema_plus_core 0.1.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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +18 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +434 -0
- data/Rakefile +9 -0
- data/gemfiles/Gemfile.base +4 -0
- data/gemfiles/activerecord-4.2/Gemfile.base +3 -0
- data/gemfiles/activerecord-4.2/Gemfile.mysql2 +10 -0
- data/gemfiles/activerecord-4.2/Gemfile.postgresql +10 -0
- data/gemfiles/activerecord-4.2/Gemfile.sqlite3 +10 -0
- data/lib/schema_plus/core.rb +27 -0
- data/lib/schema_plus/core/active_record/base.rb +22 -0
- data/lib/schema_plus/core/active_record/connection_adapters/abstract_adapter.rb +43 -0
- data/lib/schema_plus/core/active_record/connection_adapters/abstract_mysql_adapter.rb +17 -0
- data/lib/schema_plus/core/active_record/connection_adapters/mysql2_adapter.rb +64 -0
- data/lib/schema_plus/core/active_record/connection_adapters/postgresql_adapter.rb +46 -0
- data/lib/schema_plus/core/active_record/connection_adapters/sqlite3_adapter.rb +43 -0
- data/lib/schema_plus/core/active_record/connection_adapters/table_definition.rb +36 -0
- data/lib/schema_plus/core/active_record/migration/command_recorder.rb +16 -0
- data/lib/schema_plus/core/active_record/schema_dumper.rb +102 -0
- data/lib/schema_plus/core/middleware.rb +71 -0
- data/lib/schema_plus/core/schema_dump.rb +123 -0
- data/lib/schema_plus/core/sql_struct.rb +30 -0
- data/lib/schema_plus/core/version.rb +5 -0
- data/schema_dev.yml +8 -0
- data/schema_plus_core.gemspec +31 -0
- data/spec/dumper_spec.rb +53 -0
- data/spec/middleware_spec.rb +175 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/sql_struct_spec.rb +29 -0
- data/spec/support/enableable.rb +30 -0
- data/spec/support/test_dumper.rb +42 -0
- data/spec/support/test_reporter.rb +57 -0
- metadata +212 -0
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "schema_monkey"
|
2
|
+
|
3
|
+
module SchemaPlus
|
4
|
+
module Core
|
5
|
+
module ActiveRecord
|
6
|
+
module ConnectionAdapters
|
7
|
+
DIR = Pathname.new(__FILE__).dirname + "core/active_record/connection_adapters"
|
8
|
+
autoload :PostgresqlAdapter, DIR + "postgresql_adapter"
|
9
|
+
autoload :Mysql2Adapter, DIR + "mysql2_adapter"
|
10
|
+
autoload :AbstractMysqlAdapter, DIR + "abstract_mysql_adapter"
|
11
|
+
autoload :Sqlite3Adapter, DIR + "sqlite3_adapter"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require_relative "core/active_record/base"
|
18
|
+
require_relative "core/active_record/connection_adapters/abstract_adapter"
|
19
|
+
require_relative "core/active_record/connection_adapters/table_definition"
|
20
|
+
require_relative "core/active_record/migration/command_recorder"
|
21
|
+
require_relative "core/active_record/schema_dumper"
|
22
|
+
require_relative "core/middleware"
|
23
|
+
require_relative "core/schema_dump"
|
24
|
+
require_relative "core/sql_struct"
|
25
|
+
require_relative "core/version"
|
26
|
+
|
27
|
+
SchemaMonkey.register(SchemaPlus::Core)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module Base
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def columns
|
8
|
+
SchemaMonkey::Middleware::Model::Columns.start(model: self, columns: []) { |env|
|
9
|
+
env.columns += super
|
10
|
+
}.columns
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_column_information
|
14
|
+
SchemaMonkey::Middleware::Model::ResetColumnInformation.start(model: self) do |env|
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module AbstractAdapter
|
6
|
+
|
7
|
+
def add_column(table_name, name, type, options = {})
|
8
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :add, table_name: table_name, column_name: name, type: type, options: options.deep_dup) do |env|
|
9
|
+
super env.table_name, env.column_name, env.type, env.options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_reference(table_name, name, options = {})
|
14
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :add, table_name: table_name, column_name: "#{name}_id", type: :reference, options: options.deep_dup) do |env|
|
15
|
+
super env.table_name, env.column_name.sub(/_id$/, ''), env.options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_index_options(table_name, column_names, options={})
|
20
|
+
SchemaMonkey::Middleware::Sql::IndexComponents.start(connection: self, table_name: table_name, column_names: Array.wrap(column_names), options: options.deep_dup, sql: SqlStruct::IndexComponents.new) { |env|
|
21
|
+
env.sql.name, env.sql.type, env.sql.columns, env.sql.options, env.sql.algorithm, env.sql.using = super env.table_name, env.column_names, env.options
|
22
|
+
}.sql.to_hash.values
|
23
|
+
end
|
24
|
+
|
25
|
+
module SchemaCreation
|
26
|
+
|
27
|
+
def add_column_options!(sql, options)
|
28
|
+
sql << " " + SchemaMonkey::Middleware::Sql::ColumnOptions.start(caller: self, connection: self.instance_variable_get('@conn'), sql: "", column: options[:column], options: options.except(:column)) { |env|
|
29
|
+
super env.sql, env.options.merge(column: env.column)
|
30
|
+
}.sql.lstrip
|
31
|
+
end
|
32
|
+
|
33
|
+
def visit_TableDefinition(o)
|
34
|
+
SchemaMonkey::Middleware::Sql::Table.start(caller: self, connection: self.instance_variable_get('@conn'), table_definition: o, sql: SqlStruct::Table.new) { |env|
|
35
|
+
env.sql.parse! super env.table_definition
|
36
|
+
}.sql.assemble
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module AbstractMysqlAdapter
|
6
|
+
module SchemaCreation
|
7
|
+
def visit_TableDefinition(o)
|
8
|
+
SchemaMonkey::Middleware::Sql::Table.start(caller: self, connection: self.instance_variable_get('@conn'), table_definition: o, sql: SqlStruct::Table.new) { |env|
|
9
|
+
env.sql.parse! super env.table_definition
|
10
|
+
}.sql.assemble
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Mysql2Adapter
|
6
|
+
|
7
|
+
def change_column(table_name, name, type, options = {})
|
8
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :change, table_name: table_name, column_name: name, type: type, options: options.deep_dup) do |env|
|
9
|
+
super env.table_name, env.column_name, env.type, env.options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_index(table_name, column_names, options={})
|
14
|
+
SchemaMonkey::Middleware::Migration::Index.start(caller: self, operation: :add, table_name: table_name, column_names: column_names, options: options.deep_dup) do |env|
|
15
|
+
super env.table_name, env.column_names, env.options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def indexes(table_name, query_name=nil)
|
20
|
+
SchemaMonkey::Middleware::Schema::Indexes.start(connection: self, table_name: table_name, query_name: query_name, index_definitions: []) { |env|
|
21
|
+
env.index_definitions += super env.table_name, env.query_name
|
22
|
+
}.index_definitions
|
23
|
+
end
|
24
|
+
|
25
|
+
def tables(query_name=nil, database=nil, like=nil)
|
26
|
+
SchemaMonkey::Middleware::Schema::Tables.start(connection: self, query_name: query_name, database: database, like: like, tables: []) { |env|
|
27
|
+
env.tables += super env.query_name, env.database, env.like
|
28
|
+
}.tables
|
29
|
+
end
|
30
|
+
|
31
|
+
def select_rows(sql, name=nil, binds=[])
|
32
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
33
|
+
env.result = super env.sql, env.query_name, env.binds
|
34
|
+
}.result
|
35
|
+
end
|
36
|
+
|
37
|
+
def exec_query(sql, name='SQL', binds=[])
|
38
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
39
|
+
env.result = super env.sql, env.query_name, env.binds
|
40
|
+
}.result
|
41
|
+
end
|
42
|
+
|
43
|
+
alias exec_without_stmt exec_query
|
44
|
+
|
45
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
46
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
47
|
+
env.result = super env.sql, env.query_name, env.binds, pk, sequence_name
|
48
|
+
}.result
|
49
|
+
end
|
50
|
+
|
51
|
+
def exec_delete(sql, name, binds)
|
52
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
53
|
+
env.result = super env.sql, env.query_name, env.binds
|
54
|
+
}.result
|
55
|
+
end
|
56
|
+
|
57
|
+
alias :exec_update :exec_delete
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module PostgresqlAdapter
|
6
|
+
|
7
|
+
def change_column(table_name, name, type, options = {})
|
8
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :change, table_name: table_name, column_name: name, type: type, options: options.deep_dup) do |env|
|
9
|
+
super env.table_name, env.column_name, env.type, env.options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_index(table_name, column_names, options={})
|
14
|
+
SchemaMonkey::Middleware::Migration::Index.start(caller: self, operation: :add, table_name: table_name, column_names: column_names, options: options.deep_dup) do |env|
|
15
|
+
super env.table_name, env.column_names, env.options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def exec_cache(sql, name, binds)
|
20
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
21
|
+
env.result = super env.sql, env.query_name, env.binds
|
22
|
+
}.result
|
23
|
+
end
|
24
|
+
|
25
|
+
def exec_no_cache(sql, name, binds)
|
26
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
27
|
+
env.result = super env.sql, env.query_name, env.binds
|
28
|
+
}.result
|
29
|
+
end
|
30
|
+
|
31
|
+
def indexes(table_name, query_name=nil)
|
32
|
+
SchemaMonkey::Middleware::Schema::Indexes.start(connection: self, table_name: table_name, query_name: query_name, index_definitions: []) { |env|
|
33
|
+
env.index_definitions += super env.table_name, env.query_name
|
34
|
+
}.index_definitions
|
35
|
+
end
|
36
|
+
|
37
|
+
def tables(query_name=nil)
|
38
|
+
SchemaMonkey::Middleware::Schema::Tables.start(connection: self, query_name: query_name, tables: []) { |env|
|
39
|
+
env.tables += super env.query_name
|
40
|
+
}.tables
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module Sqlite3Adapter
|
6
|
+
|
7
|
+
def change_column(table_name, name, type, options = {})
|
8
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :change, table_name: table_name, column_name: name, type: type, options: options.deep_dup) do |env|
|
9
|
+
super env.table_name, env.column_name, env.type, env.options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_index(table_name, column_names, options={})
|
14
|
+
SchemaMonkey::Middleware::Migration::Index.start(caller: self, operation: :add, table_name: table_name, column_names: column_names, options: options.deep_dup) do |env|
|
15
|
+
super env.table_name, env.column_names, env.options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def exec_query(sql, name=nil, binds=[])
|
20
|
+
SchemaMonkey::Middleware::Query::Exec.start(connection: self, sql: sql, query_name: name, binds: binds) { |env|
|
21
|
+
env.result = super env.sql, env.query_name, env.binds
|
22
|
+
}.result
|
23
|
+
end
|
24
|
+
|
25
|
+
def indexes(table_name, query_name=nil)
|
26
|
+
SchemaMonkey::Middleware::Schema::Indexes.start(connection: self, table_name: table_name, query_name: query_name, index_definitions: []) { |env|
|
27
|
+
env.index_definitions += super env.table_name, env.query_name
|
28
|
+
}.index_definitions
|
29
|
+
end
|
30
|
+
|
31
|
+
def tables(query_name=nil, table_name=nil)
|
32
|
+
SchemaMonkey::Middleware::Schema::Tables.start(connection: self, query_name: query_name, table_name: table_name, tables: []) { |env|
|
33
|
+
env.tables += super env.query_name, env.table_name
|
34
|
+
}.tables
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module TableDefinition
|
6
|
+
|
7
|
+
def column(name, type, options = {})
|
8
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :define, table_name: self.name, column_name: name, type: type, options: options.deep_dup) do |env|
|
9
|
+
super env.column_name, env.type, env.options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def references(name, options = {})
|
14
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :define, table_name: self.name, column_name: "#{name}_id", type: :reference, options: options.deep_dup) do |env|
|
15
|
+
super env.column_name.sub(/_id$/, ''), env.options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def belongs_to(name, options = {})
|
20
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :define, table_name: self.name, column_name: "#{name}_id", type: :reference, options: options.deep_dup) do |env|
|
21
|
+
super env.column_name.sub(/_id$/, ''), env.options
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def index(*args)
|
26
|
+
options = args.extract_options!
|
27
|
+
column_name = args.first
|
28
|
+
SchemaMonkey::Middleware::Migration::Index.start(caller: self, operation: :define, table_name: self.name, column_names: column_name, options: options.deep_dup) do |env|
|
29
|
+
super env.column_names, env.options
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SchemaPlus
|
2
|
+
module Core
|
3
|
+
module ActiveRecord
|
4
|
+
module Migration
|
5
|
+
module CommandRecorder
|
6
|
+
|
7
|
+
def add_column(table_name, column_name, type, options = {})
|
8
|
+
SchemaMonkey::Middleware::Migration::Column.start(caller: self, operation: :record, table_name: table_name, column_name: column_name, type: type, options: options.deep_dup) do |env|
|
9
|
+
super env.table_name, env.column_name, env.type, env.options
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'tsort'
|
3
|
+
|
4
|
+
module SchemaPlus
|
5
|
+
module Core
|
6
|
+
module ActiveRecord
|
7
|
+
module SchemaDumper
|
8
|
+
|
9
|
+
def self.prepended(base)
|
10
|
+
base.class_eval do
|
11
|
+
public :ignored?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def dump(stream)
|
16
|
+
@dump = SchemaDump.new(self)
|
17
|
+
super stream
|
18
|
+
@dump.assemble(stream)
|
19
|
+
end
|
20
|
+
|
21
|
+
def foreign_keys(table, _)
|
22
|
+
stream = StringIO.new
|
23
|
+
super table, stream
|
24
|
+
@dump.final += stream.string.split("\n").map(&:strip)
|
25
|
+
end
|
26
|
+
|
27
|
+
def trailer(_)
|
28
|
+
stream = StringIO.new
|
29
|
+
super stream
|
30
|
+
@dump.trailer = stream.string
|
31
|
+
end
|
32
|
+
|
33
|
+
def extensions(_)
|
34
|
+
SchemaMonkey::Middleware::Dumper::Initial.start(dumper: self, connection: @connection, dump: @dump, initial: @dump.initial) do |env|
|
35
|
+
stream = StringIO.new
|
36
|
+
super stream
|
37
|
+
env.dump.initial << stream.string unless stream.string.blank?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def tables(_)
|
42
|
+
SchemaMonkey::Middleware::Dumper::Tables.start(dumper: self, connection: @connection, dump: @dump) do |env|
|
43
|
+
super nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def table(table, _)
|
48
|
+
SchemaMonkey::Middleware::Dumper::Table.start(dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table] = SchemaDump::Table.new(name: table)) do |env|
|
49
|
+
stream = StringIO.new
|
50
|
+
super env.table.name, stream
|
51
|
+
m = stream.string.match %r{
|
52
|
+
\A \s*
|
53
|
+
create_table \s*
|
54
|
+
[:'"](?<name>[^'"\s]+)['"]? \s*
|
55
|
+
,? \s*
|
56
|
+
(?<options>.*) \s+
|
57
|
+
do \s* \|t\| \s* $
|
58
|
+
(?<columns>.*)
|
59
|
+
^\s*end\s*$
|
60
|
+
(?<trailer>.*)
|
61
|
+
\Z
|
62
|
+
}xm
|
63
|
+
env.table.pname = m[:name]
|
64
|
+
env.table.options = m[:options].strip
|
65
|
+
env.table.trailer = m[:trailer].split("\n").map(&:strip).reject{|s| s.blank?}
|
66
|
+
env.table.columns = m[:columns].strip.split("\n").map { |col|
|
67
|
+
m = col.strip.match %r{
|
68
|
+
^
|
69
|
+
t\.(?<type>\S+) \s*
|
70
|
+
[:'"](?<name>[^"\s]+)[,"]? \s*
|
71
|
+
,? \s*
|
72
|
+
(?<options>.*)
|
73
|
+
$
|
74
|
+
}x
|
75
|
+
SchemaDump::Table::Column.new(name: m[:name], type: m[:type], options: m[:options])
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def indexes(table, _)
|
81
|
+
SchemaMonkey::Middleware::Dumper::Indexes.start(dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table]) do |env|
|
82
|
+
stream = StringIO.new
|
83
|
+
super env.table.name, stream
|
84
|
+
env.table.indexes += stream.string.split("\n").map { |string|
|
85
|
+
m = string.strip.match %r{
|
86
|
+
^
|
87
|
+
add_index \s*
|
88
|
+
[:'"](?<table>[^'"\s]+)['"]? \s* , \s*
|
89
|
+
(?<columns>.*) \s*
|
90
|
+
name: \s* [:'"](?<name>[^'"\s]+)['"]? \s*
|
91
|
+
(, \s* (?<options>.*))?
|
92
|
+
$
|
93
|
+
}x
|
94
|
+
columns = m[:columns].tr(%q{[]'":}, '').strip.split(/\s*,\s*/)
|
95
|
+
SchemaDump::Table::Index.new name: m[:name], columns: columns, options: m[:options]
|
96
|
+
}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|