schema_monkey 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +0 -1
  4. data/Gemfile +2 -0
  5. data/README.md +204 -28
  6. data/lib/schema_monkey.rb +30 -17
  7. data/lib/schema_monkey/active_record.rb +25 -0
  8. data/lib/schema_monkey/client.rb +65 -0
  9. data/lib/schema_monkey/errors.rb +6 -0
  10. data/lib/schema_monkey/{tool/module.rb → module.rb} +10 -7
  11. data/lib/schema_monkey/monkey.rb +31 -0
  12. data/lib/schema_monkey/{tool/rake.rb → rake.rb} +1 -1
  13. data/lib/schema_monkey/stack.rb +44 -0
  14. data/lib/schema_monkey/{tool/tasks → tasks}/insert.rake +0 -0
  15. data/lib/schema_monkey/version.rb +1 -1
  16. data/schema_dev.yml +0 -1
  17. data/schema_monkey.gemspec +2 -2
  18. data/spec/active_record_spec.rb +75 -0
  19. data/spec/middleware_spec.rb +0 -7
  20. data/spec/spec_helper.rb +2 -2
  21. metadata +18 -41
  22. data/lib/schema_monkey/core_extensions.rb +0 -23
  23. data/lib/schema_monkey/core_extensions/active_record/base.rb +0 -31
  24. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/abstract_adapter.rb +0 -38
  25. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/mysql2_adapter.rb +0 -31
  26. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/postgresql_adapter.rb +0 -30
  27. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/schema_statements.rb +0 -83
  28. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/sqlite3_adapter.rb +0 -33
  29. data/lib/schema_monkey/core_extensions/active_record/connection_adapters/table_definition.rb +0 -42
  30. data/lib/schema_monkey/core_extensions/active_record/migration/command_recorder.rb +0 -19
  31. data/lib/schema_monkey/core_extensions/active_record/schema_dumper.rb +0 -227
  32. data/lib/schema_monkey/core_extensions/middleware.rb +0 -62
  33. data/lib/schema_monkey/tool.rb +0 -43
  34. data/lib/schema_monkey/tool/client.rb +0 -67
  35. data/lib/schema_monkey/tool/errors.rb +0 -4
  36. data/lib/schema_monkey/tool/monkey.rb +0 -46
  37. data/lib/schema_monkey/tool/stack.rb +0 -90
@@ -1,62 +0,0 @@
1
- module SchemaMonkey::CoreExtensions
2
- module Middleware
3
- module Query
4
- module ExecCache
5
- ENV = [:connection, :sql, :name, :binds, :result]
6
- end
7
-
8
- module Tables
9
- # :database and :like are only for mysql
10
- # :table_name is only for sqlite3
11
- ENV = [:connection, :query_name, :table_name, :database, :like, :tables]
12
- end
13
-
14
- module Indexes
15
- ENV = [:connection, :table_name, :query_name, :index_definitions]
16
- end
17
- end
18
-
19
- module Migration
20
- module Column
21
- ENV = [:caller, :operation, :table_name, :column_name, :type, :options]
22
- end
23
-
24
- module ColumnOptionsSql
25
- ENV = [:caller, :connection, :sql, :options]
26
- end
27
-
28
- module Index
29
- ENV = [:caller, :operation, :table_name, :column_names, :options]
30
- end
31
-
32
- module IndexComponentsSql
33
- ENV = [:connection, :table_name, :column_names, :options, :sql]
34
- end
35
- end
36
-
37
- module Dumper
38
- module Extensions
39
- ENV = [:dumper, :connection, :dump, :extensions]
40
- end
41
- module Tables
42
- ENV = [:dumper, :connection, :dump]
43
- end
44
- module Table
45
- ENV = [:dumper, :connection, :dump, :table]
46
- end
47
- module Indexes
48
- ENV = [:dumper, :connection, :dump, :table]
49
- end
50
- end
51
-
52
- module Model
53
- module Columns
54
- ENV = [:model, :columns]
55
- end
56
- module ResetColumnInformation
57
- ENV = [:model]
58
- end
59
- end
60
-
61
- end
62
- end
@@ -1,43 +0,0 @@
1
- require 'hash_keyword_args'
2
- require 'its-it'
3
- require 'key_struct'
4
- require 'active_support/core_ext/string'
5
-
6
- require_relative "tool/client"
7
- require_relative "tool/errors"
8
- require_relative "tool/module"
9
- require_relative "tool/monkey"
10
- require_relative "tool/stack"
11
- require_relative 'tool/rake'
12
-
13
- module SchemaMonkey
14
- module Tool
15
-
16
- DBMS = [:PostgreSQL, :Mysql, :SQLite3]
17
-
18
- def self.register(mod)
19
- monkey.register(mod)
20
- end
21
-
22
- def self.insert(opts={})
23
- monkey.insert(opts)
24
- end
25
-
26
- private
27
-
28
- def self.monkey
29
- @monkey ||= Monkey.new
30
- end
31
-
32
- def self.reset_for_rspec
33
- @monkey = nil
34
- self.reset_middleware
35
- end
36
-
37
- def self.reset_middleware
38
- SchemaMonkey.send :remove_const, :Middleware
39
- SchemaMonkey.send :const_set, :Middleware, ::Module.new
40
- end
41
-
42
- end
43
- end
@@ -1,67 +0,0 @@
1
- module SchemaMonkey::Tool
2
- class Client
3
- attr_reader :monkey
4
-
5
- def initialize(monkey, mod)
6
- @monkey = monkey
7
- @root = mod
8
- @inserted = {}
9
- end
10
-
11
- def insert(opts={})
12
- opts = opts.keyword_args(:dbm)
13
- include_modules(dbm: opts.dbm)
14
- insert_middleware(dbm: opts.dbm)
15
- @root.insert() if @root.respond_to?(:insert) and @root != ::SchemaMonkey
16
- end
17
-
18
- def include_modules(opts={})
19
- opts = opts.keyword_args(:dbm)
20
- # Kernel.warn "--- include modules for #{@root}, dbm=#{opts.dbm.inspect}"
21
- find_modules(:ActiveRecord, dbm: opts.dbm).each do |mod|
22
- next if mod.is_a? Class
23
- component = mod.to_s.sub(/^#{@root}::ActiveRecord::/, '')
24
- component = component.gsub(/#{opts.dbm}/i, opts.dbm.to_s) if opts.dbm # canonicalize case
25
- next unless base = Module.const_lookup(::ActiveRecord, component)
26
- # Kernel.warn "including #{mod} (dbm=#{opts.dbm})"
27
- Module.include_once base, mod
28
- end
29
- end
30
-
31
- def insert_middleware(opts={})
32
- opts = opts.keyword_args(:dbm)
33
- find_modules(:Middleware, dbm: opts.dbm).each do |mod|
34
- next if @inserted[mod]
35
-
36
- stack_path = mod.to_s.sub(/^#{@root}::Middleware::/, '')
37
- stack_path = stack_path.split('::').reject(&it =~/\b#{opts.dbm}\b/i).join('::') if opts.dbm
38
-
39
- monkey.insert_middleware_hook(mod, stack_path: stack_path) unless stack_path.empty?
40
-
41
- @inserted[mod] = true
42
- end
43
- end
44
-
45
- private
46
-
47
- def find_modules(container, opts={})
48
- opts = opts.keyword_args(dbm: nil)
49
- return [] unless (container = Module.const_lookup @root, container)
50
-
51
- if opts.dbm
52
- accept = /\b#{opts.dbm}/i
53
- reject = nil
54
- else
55
- accept = nil
56
- reject = /\b(#{DBMS.join('|')})/i
57
- end
58
-
59
- modules = []
60
- modules += Module.descendants(container, can_load: accept)
61
- modules.select!(&it.to_s =~ accept) if accept
62
- modules.reject!(&it.to_s =~ reject) if reject
63
- modules
64
- end
65
-
66
- end
67
- end
@@ -1,4 +0,0 @@
1
- module SchemaMonkey::Tool
2
- class MiddlewareError < Exception
3
- end
4
- end
@@ -1,46 +0,0 @@
1
- module SchemaMonkey::Tool
2
-
3
- # The main manager for the monkey patches. Singleton instance
4
- # created by SchemaMonkey.monkey
5
-
6
- class Monkey
7
-
8
- attr_reader :clients, :stacks
9
-
10
- def initialize
11
- @clients = []
12
- end
13
-
14
- def register(mod)
15
- clients << Client.new(self, mod)
16
- end
17
-
18
- def insert(opts={})
19
- opts = opts.keyword_args(:dbm)
20
- clients.each &it.insert(dbm: opts.dbm)
21
- end
22
-
23
- def insert_middleware_hook(mod, opts={})
24
- opts = opts.keyword_args(stack_path: :required)
25
-
26
- return unless Stack.is_hook?(mod)
27
-
28
- stack = Module.const_lookup SchemaMonkey::Middleware, opts.stack_path
29
- env = Module.const_lookup mod, "ENV"
30
-
31
- case
32
- when stack && env
33
- raise MiddlewareError, "#{mod}::ENV: stack #{stack} is already defined"
34
- when !stack && !env
35
- raise MiddlewareError, "#{mod}: No stack #{SchemaMonkey::Middleware}::#{opts.stack_path}"
36
- when !stack && env
37
- stack = Module.mkpath SchemaMonkey::Middleware, opts.stack_path
38
- stack.send :extend, Stack::StartMethod
39
- stack.send :stack=, Stack.new(module: stack, env: env)
40
- end
41
-
42
- stack.stack.append(mod)
43
- end
44
-
45
- end
46
- end
@@ -1,90 +0,0 @@
1
- module SchemaMonkey::Tool
2
- class Stack
3
- def initialize(opts={})
4
- opts = opts.keyword_args(module: :required, env: :required)
5
- @module = opts.module
6
- @env_class = @module.const_set "Env", KeyStruct[*opts.env]
7
- @hooks = []
8
- end
9
-
10
- def self.is_hook?(mod)
11
- return true if (mod.instance_methods & [:before, :around, :after, :implement]).any?
12
- return true if Module.const_lookup mod, "ENV"
13
- false
14
- end
15
-
16
- def append(mod)
17
- hook = Hook.new(self, mod)
18
- @hooks.last._next = hook if @hooks.any?
19
- @hooks << hook
20
- end
21
-
22
- def start(env_opts, &implementation)
23
- env = @env_class.new(env_opts)
24
- @implementation = implementation
25
-
26
- @hooks.each do |hook|
27
- hook.before env if hook.respond_to? :before
28
- end
29
-
30
- @hooks.first._call(env)
31
-
32
- @hooks.each do |hook|
33
- hook.after env if hook.respond_to? :after
34
- end
35
-
36
- env
37
- end
38
-
39
- def call_implementation(env)
40
- if hook = @hooks.select(&it.respond_to?(:implement)).last
41
- hook.implement(env)
42
- elsif @implementation
43
- @implementation.call env
44
- else
45
- raise MiddlewareError, "No implementation for middleware stack #{@module}"
46
- end
47
- end
48
-
49
- class Hook
50
- attr_accessor :_next
51
-
52
- def initialize(stack, mod)
53
- @stack = stack
54
- singleton_class.send :include, mod
55
- end
56
-
57
- def _call(env)
58
- if respond_to? :around
59
- around(env) { |env|
60
- _continue env
61
- }
62
- else
63
- _continue env
64
- end
65
- end
66
-
67
- def _continue(env)
68
- if self._next
69
- self._next._call(env)
70
- else
71
- @stack.call_implementation(env)
72
- end
73
- end
74
- end
75
-
76
- module StartMethod
77
- attr_reader :stack
78
-
79
- def start(env, &block)
80
- stack.start(env, &block)
81
- end
82
-
83
- private
84
-
85
- def stack=(stack)
86
- @stack = stack
87
- end
88
- end
89
- end
90
- end