skiima 0.1.000 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +11 -3
  4. data/Gemfile +12 -6
  5. data/Guardfile +13 -11
  6. data/LICENSE +20 -0
  7. data/Procfile.example +2 -0
  8. data/README.md +170 -23
  9. data/Rakefile +26 -22
  10. data/lib/skiima.rb +61 -240
  11. data/lib/skiima/config.rb +60 -0
  12. data/lib/skiima/config/struct.rb +87 -0
  13. data/lib/skiima/db/connector.rb +195 -0
  14. data/lib/skiima/db/connector/active_record.rb +11 -0
  15. data/lib/skiima/db/connector/active_record/base_connector.rb +34 -0
  16. data/lib/skiima/db/connector/active_record/mysql2_connector.rb +147 -0
  17. data/lib/skiima/db/connector/active_record/mysql_connector.rb +177 -0
  18. data/lib/skiima/db/connector/active_record/postgresql_connector.rb +39 -0
  19. data/lib/skiima/db/helpers/mysql.rb +230 -0
  20. data/lib/skiima/db/helpers/postgresql.rb +221 -0
  21. data/lib/skiima/db/resolver.rb +62 -0
  22. data/lib/skiima/dependency/reader.rb +55 -0
  23. data/lib/skiima/dependency/script.rb +63 -0
  24. data/lib/skiima/i18n.rb +24 -0
  25. data/lib/skiima/loader.rb +108 -0
  26. data/lib/skiima/locales/en.yml +2 -2
  27. data/lib/skiima/logger.rb +54 -0
  28. data/lib/skiima/railtie.rb +10 -0
  29. data/lib/skiima/railties/skiima.rake +31 -0
  30. data/lib/skiima/version.rb +2 -2
  31. data/skiima.gemspec +5 -5
  32. data/spec/config/{database.yml → database.yml.example} +16 -0
  33. data/spec/config/database.yml.travis +69 -0
  34. data/spec/db/skiima/{depends.yml → dependencies.yml} +7 -2
  35. data/spec/db/skiima/{empty_depends.yml → empty_dependencies.yml} +0 -0
  36. data/spec/db/skiima/init_test_db/database.skiima_test.mysql.current.sql +7 -0
  37. data/spec/db/skiima/init_test_db/database.skiima_test.postgresql.current.sql +7 -0
  38. data/spec/mysql2_spec.rb +61 -12
  39. data/spec/mysql_spec.rb +66 -27
  40. data/spec/postgresql_spec.rb +55 -34
  41. data/spec/shared_examples/config_shared_example.rb +40 -0
  42. data/spec/skiima/config/struct_spec.rb +78 -0
  43. data/spec/skiima/config_spec.rb +6 -0
  44. data/spec/skiima/db/connector/active_record/base_connector_spec.rb +0 -0
  45. data/spec/skiima/db/connector/active_record/mysql2_connector_spec.rb +3 -0
  46. data/spec/skiima/db/connector/active_record/mysql_connector_spec.rb +3 -0
  47. data/spec/skiima/db/connector/active_record/postgresql_connector_spec.rb +7 -0
  48. data/spec/skiima/db/connector_spec.rb +6 -0
  49. data/spec/skiima/db/resolver_spec.rb +54 -0
  50. data/spec/skiima/dependency/reader_spec.rb +52 -0
  51. data/spec/skiima/{dependency_spec.rb → dependency/script_spec.rb} +3 -41
  52. data/spec/skiima/i18n_spec.rb +29 -0
  53. data/spec/skiima/loader_spec.rb +102 -0
  54. data/spec/skiima/logger_spec.rb +0 -0
  55. data/spec/skiima_spec.rb +43 -64
  56. data/spec/spec_helper.rb +38 -4
  57. metadata +144 -100
  58. data/lib/skiima/db_adapters.rb +0 -187
  59. data/lib/skiima/db_adapters/base_mysql_adapter.rb +0 -308
  60. data/lib/skiima/db_adapters/mysql2_adapter.rb +0 -114
  61. data/lib/skiima/db_adapters/mysql_adapter.rb +0 -287
  62. data/lib/skiima/db_adapters/postgresql_adapter.rb +0 -509
  63. data/lib/skiima/dependency.rb +0 -84
  64. data/lib/skiima_helpers.rb +0 -49
  65. data/spec/skiima/db_adapters/mysql_adapter_spec.rb +0 -38
  66. data/spec/skiima/db_adapters/postgresql_adapter_spec.rb +0 -20
  67. data/spec/skiima/db_adapters_spec.rb +0 -31
@@ -5,266 +5,87 @@ require 'yaml'
5
5
  require 'logger'
6
6
  require 'fast_gettext'
7
7
  require 'erubis'
8
+ require 'ostruct'
9
+ require 'forwardable'
10
+
11
+ require 'skiima/config'
12
+ require 'skiima/config/struct'
13
+ require 'skiima/i18n'
14
+ require 'skiima/logger'
15
+ require 'skiima/loader'
16
+ require 'skiima/db/resolver'
17
+ require 'skiima/db/connector'
18
+ require 'skiima/dependency/script'
19
+ require 'skiima/dependency/reader'
8
20
 
9
- require 'skiima_helpers'
10
-
11
- # include FastGettext unless it already is
12
21
  include FastGettext unless ::Object.included_modules.include?(FastGettext)
13
22
 
14
23
  module Skiima
15
24
  include FastGettext::Translation
16
- extend SkiimaHelpers
17
- extend ModuleHelpers
18
-
19
- # require 'skiima/base'
20
- autoload :Dependency, 'skiima/dependency'
21
- autoload :DbAdapters, 'skiima/db_adapters'
22
-
23
- set_defaults(:config, {
24
- :root_path => 'specify/in/config/block',
25
- :config_path => 'config',
26
- :database_yaml => 'database.yml',
27
- :scripts_path => 'db/skiima',
28
- :depends_yaml => 'depends.yml',
29
- :interpolator => '&',
30
- :locale => 'en',
31
- :logging_out => 'STDOUT',
32
- :logging_level => '3' })
33
- #should time zone be added to configs?
25
+ extend Skiima::Config
26
+ extend Skiima::I18n
27
+ extend Skiima::LoggerHelpers
34
28
 
35
29
  class << self
36
- def setup
37
- yield self
38
- set_translation_repository
39
- end
40
-
41
- def new(env, opts = {})
42
- Skiima::Loader.new(env, opts)
43
- end
44
-
45
- def up(*args)
46
- opts = args.last.is_a?(Hash) ? args.pop : {}
47
- ski = Skiima.new(env, opts).up(*args)
48
- ensure
49
- ski.connection.close
50
- end
51
-
52
- def down(*args)
53
- opts = args.last.is_a?(Hash) ? args.pop : {}
54
- Skiima.new(env, opts).down(*args)
55
- ensure
56
- ski.connection.close
57
- end
58
-
59
- def msg(*args)
60
- locale = args.last.is_a?(Symbol) ? args.pop : default_locale
61
- lookup = args.join('.')
62
- Skiima._(lookup)
63
- end
64
-
65
- def log_message(logger, msg)
66
- logger.debug msg
67
- end
68
-
69
- def default_locale
70
- ::Skiima.locale
71
- end
72
-
73
- def set_translation_repository
74
- FastGettext.add_text_domain('skiima', :path => File.join(File.dirname(__FILE__), 'skiima', 'locales'), :type => :yaml)
75
- Skiima.text_domain = 'skiima'
76
- Skiima.locale = locale.to_s
77
- end
78
-
79
- def self.exe_with_connection(db, &block)
80
- resolver = Skiima::DbAdapters::Resolver.new db
81
- connection = nil
82
-
83
- begin
84
- connection = self.send(resolver.adapter_method, db)
85
- yield connection
86
- rescue => ex
87
- puts "Oh Noes!!"
88
- ensure
89
- connection.close
90
- end
91
- end
92
-
93
- def interpolate_sql(char, sql, vars = {})
94
- vars.inject(sql) do |memo, (k,v)|
95
- memo = memo.gsub("#{char}#{k.to_s}", v)
96
- end
97
- end
98
-
99
- def full_scripts_path(root = self.root_path, config = self.scripts_path)
100
- File.join(root, config)
101
- end
102
-
103
- def full_database_path(root = self.root_path, config = self.config_path, db = self.database_yaml)
104
- File.join(root, config, db)
105
- end
106
-
107
- def full_depends_path(root = self.root_path, config = self.scripts_path, depends = self.depends_yaml)
108
- File.join(root, config, depends)
109
- end
110
-
111
- def read_db_yaml(file)
112
- Skiima.symbolize_keys(self.read_yaml_or_throw(file, MissingFileException, "#{Skiima.msg('errors.open_db_yaml')} #{file}"))
113
- end
114
-
115
- def read_depends_yaml(file)
116
- Skiima.symbolize_keys(self.read_yaml_or_throw(file, MissingFileException, "#{Skiima.msg('errors.open_depends_yaml')} #{file}"))
117
- end
30
+ extend Forwardable
31
+ delegate new: Skiima::Loader
32
+ end
118
33
 
119
- def read_sql_file(folder, file)
120
- File.open(File.join(Skiima.full_scripts_path, folder, file)).read
121
- end
34
+ def self.setup
35
+ yield config
36
+ set_translation_repository
37
+ end
122
38
 
123
- def read_yaml_or_throw(file, errclass, errmsg)
124
- yaml = begin
125
- input = File.read(file)
126
- eruby = Erubis::Eruby.new(input)
127
- YAML::load(eruby.result(binding())) || {}
128
- rescue => ex
129
- raise errclass, errmsg
130
- end
39
+ require 'skiima/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
40
+
41
+ def self.defaults
42
+ { root_path: 'specify/in/config/block',
43
+ config_path: 'config',
44
+ database_yml: 'database.yml',
45
+ scripts_path: 'db/skiima',
46
+ dependencies_yml: 'dependencies.yml',
47
+ interpolator: '&',
48
+ locale: 'en',
49
+ logging_out: 'STDOUT',
50
+ logging_level: '3' }
51
+ end
131
52
 
132
- Skiima.symbolize_keys(yaml)
133
- end
53
+ def self.up(env, *args)
54
+ opts = args.last.is_a?(Hash) ? args.pop : {}
55
+ ski = Skiima::Loader.new(env, opts).up(*args, opts)
56
+ ensure
57
+ ski.connector.disconnect! if ski && ski.connector
58
+ end
134
59
 
135
- def method_missing(method, *args, &block)
136
- setter = method.to_s.gsub(/=$/, '').to_sym if method.to_s =~ /=$/
60
+ def self.down(env, *args)
61
+ opts = args.last.is_a?(Hash) ? args.pop : {}
62
+ ski = Skiima::Loader.new(env, opts).down(*args, opts)
63
+ ensure
64
+ ski.connector.disconnect! if ski && ski.connector
65
+ end
137
66
 
138
- val = case
139
- when (@@config.keys.include?(method)) then @@config[method]
140
- when (setter and @@config.keys.include?(setter)) then @@config[setter] = args.first
141
- end
67
+ def self.exe_with_connection(db, &block)
68
+ resolver = Skiima::Db::Resolver.new db
69
+ connection = nil
142
70
 
143
- val || super
71
+ begin
72
+ connection = self.send(resolver.adapter_method, db)
73
+ yield connection
74
+ rescue => ex
75
+ puts "Oh Noes!!"
76
+ ensure
77
+ connection.close
144
78
  end
145
79
  end
146
80
 
147
- #BaseExceptions
81
+ end
82
+
83
+ module Skiima
148
84
  class BaseException < ::StandardError; end
149
85
  class MissingFileException < BaseException; end
150
86
  class SqlGroupNotFound < BaseException; end
151
87
  class SqlScriptNotFound < BaseException; end
152
-
153
- #DbAdapterExceptions
154
88
  class AdapterNotSpecified < BaseException; end
155
89
  class LoadError < BaseException; end
156
90
  class StatementInvalid < BaseException; end
157
-
158
- class Loader
159
- attr_accessor :config, :logger
160
- attr_accessor :db, :connection
161
- attr_accessor :scripts
162
-
163
- def initialize(env, opts = {})
164
- db_config = Skiima.symbolize_keys(opts[:db] || {})
165
-
166
- self.config = Skiima.config.merge(opts)
167
- create_logger
168
- @db = Skiima.symbolize_keys(Skiima.read_db_yaml(full_database_path)[env].merge(db_config))
169
- make_connection
170
- @depends = Skiima.read_depends_yaml(full_depends_path)
171
- end
172
-
173
- def up(*args)
174
- opts = args.last.is_a?(Hash) ? args.pop : {}
175
- reader = Skiima::Dependency::Reader.new(@depends, @db[:adapter], opts)
176
- scripts = reader.get_load_order(*args)
177
- scripts.each do |s|
178
- s.read_content(:up, full_scripts_path)
179
- s.interpolate_sql(interpolator, interpolation_vars)
180
- end
181
- scripts.each {|s| connection.execute(s.sql)}
182
- end
183
-
184
- def down(*args)
185
- opts = args.last.is_a?(Hash) ? args.pop : {}
186
- reader = Skiima::Dependency::Reader.new(@depends, @db[:adapter], opts)
187
- scripts = reader.get_load_order(*args).reverse
188
- scripts.each do |s|
189
- s.read_content(:down, full_scripts_path)
190
- s.content ||= connection.drop(s.type, s.name, {:attr => s.attr}.merge(opts))
191
- s.interpolate_sql(interpolator, interpolation_vars)
192
- end
193
- scripts.each {|s| connection.execute(s.sql)}
194
- end
195
-
196
- def make_connection
197
- resolver = Skiima::DbAdapters::Resolver.new(@db)
198
- @connection = Skiima.send(resolver.adapter_method, logger, @db)
199
- end
200
-
201
- def log_action(msg, &block)
202
- begin
203
- logger.debug "[#{Time.now}] Started: #{msg}"
204
- results = yield
205
- logger.debug "[#{Time.now}] Finished: #{msg}"
206
- results
207
- rescue
208
- logger.error "[#{Time.now}] Error: #{msg}"
209
- raise
210
- end
211
- end
212
-
213
- def log_message(msg)
214
- Skiima.log_message(logger, msg)
215
- end
216
-
217
- def interpolation_vars(vars = {})
218
- { :database => db[:database] }.merge(vars)
219
- end
220
-
221
- def method_missing(method, *args, &block)
222
- setter = method.to_s.gsub(/=$/, '').to_sym if method.to_s =~ /=$/
223
-
224
- val = case
225
- when (@config.keys.include?(method)) then @config[method]
226
- when (setter and @config.keys.include?(setter)) then @config[setter] = args
227
- end
228
-
229
- val || super
230
- end
231
-
232
- private
233
-
234
- def full_database_path
235
- Skiima.full_database_path(self.root_path, self.config_path, self.database_yaml)
236
- end
237
-
238
- def full_depends_path
239
- Skiima.full_depends_path(self.root_path, self.scripts_path, self.depends_yaml)
240
- end
241
-
242
- def full_scripts_path
243
- Skiima.full_scripts_path(self.root_path, self.scripts_path)
244
- end
245
-
246
- def get_logger_out(str)
247
- case str
248
- when /STDOUT/i then ::STDOUT
249
- when /STDERR/i then ::STDERR
250
- else File.join(root_path, str)
251
- end
252
- end
253
-
254
- def get_logger_level(str)
255
- case str
256
- when '4', /fatal/i then ::Logger::FATAL
257
- when '3', /error/i then ::Logger::ERROR
258
- when '2', /warn/i then ::Logger::WARN
259
- when '1', /info/i then ::Logger::INFO
260
- when '0', /debug/i then ::Logger::DEBUG
261
- else ::Logger::ERROR
262
- end
263
- end
264
-
265
- def create_logger
266
- self.logger = ::Logger.new(get_logger_out(@config[:logging_out]))
267
- self.logger.level = get_logger_level(@config[:logging_level])
268
- end
269
- end
270
- end
91
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ module Skiima
3
+ module Config
4
+
5
+ def config
6
+ @config ||= (Skiima::Config::Struct.new(defaults.to_hash))
7
+ end
8
+
9
+ def config=(struct)
10
+ @config = struct
11
+ end
12
+
13
+ def full_scripts_path(root = self.root_path, config = self.scripts_path)
14
+ File.join(root, config)
15
+ end
16
+
17
+ def full_database_path(root = self.root_path, config = self.config_path, db = self.database_yml)
18
+ File.join(root, config, db)
19
+ end
20
+
21
+ def full_dependencies_path(root = self.root_path, config = self.scripts_path, dependencies = self.dependencies_yml)
22
+ File.join(root, config, dependencies)
23
+ end
24
+
25
+ def read_sql_file(folder, file)
26
+ File.open(File.join(Skiima.full_scripts_path, folder, file)).read
27
+ end
28
+
29
+ def read_db_yml(file)
30
+ symbolize_keys(read_yml_or_throw(file, MissingFileException, "#{Skiima.msg('errors.open_db_yml')} #{file}"))
31
+ end
32
+
33
+ def read_dependencies_yml(file)
34
+ symbolize_keys(read_yml_or_throw(file, MissingFileException, "#{Skiima.msg('errors.open_dependencies_yml')} #{file}"))
35
+ end
36
+
37
+ def read_yml_or_throw(file, errclass, errmsg)
38
+ input = File.read(file)
39
+ eruby = Erubis::Eruby.new(input)
40
+ symbolize_keys(YAML::load(eruby.result(binding()))) || {}
41
+ rescue => ex
42
+ raise errclass, errmsg
43
+ end
44
+
45
+ def symbolize_keys(hash)
46
+ hash.inject({}) do |options, (key, value)|
47
+ options[(key.to_sym rescue key) || key] = value
48
+ options
49
+ end
50
+ end
51
+
52
+ def interpolate_sql(char, sql, vars = {})
53
+ vars.inject(sql) { |m,(k,v)| m.gsub("#{char}#{k.to_s}", v) }
54
+ end
55
+
56
+ def method_missing(method, *args, &block)
57
+ config.respond_to?(method) ? config.send(method, *args) : super
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,87 @@
1
+ module Skiima
2
+ module Config
3
+
4
+ class Struct < OpenStruct
5
+ def initialize(opts = {})
6
+ @table = Skiima.symbolize_keys(opts)
7
+ @table.each_key { |k,v| new_ostruct_member(k) }
8
+ end
9
+
10
+ def new_ostruct_member(name)
11
+ name = convert_key(name)
12
+ unless self.respond_to?(name)
13
+ self.instance_eval <<EOS
14
+ def #{name.to_s}
15
+ v = @table[:#{name.to_s}]
16
+ if v.is_a?(Hash)
17
+ self.class.new(v)
18
+ else
19
+ v
20
+ end
21
+ end
22
+
23
+ def #{name.to_s}=(x)
24
+ modifiable[:#{name.to_s}] = x
25
+ end
26
+ EOS
27
+ end
28
+ name
29
+ end
30
+
31
+ def method_missing(mid, *args, &block)
32
+ mname, len = mid.id2name, args.length
33
+
34
+ case
35
+ when (mname.chomp!('=') && (mid != :[]=))
36
+ raise_argument_error(len, caller(1)) if len != 1
37
+ modifiable[new_ostruct_member(mname)] = args[0]
38
+ when (len == 0 && (mid != :[]) && block_given?)
39
+ cs = self.class.new(Hash.new).ostruct_eval(&block)
40
+ modifiable[new_ostruct_member(mname)] = cs
41
+ when (len == 0 && mid != :[])
42
+ @table[mid]
43
+ when (len == 1 && mid != :[])
44
+ modifiable[new_ostruct_member(mname)] = args[0]
45
+ else raise_no_method_error(mid, caller(1))
46
+ end
47
+
48
+ end
49
+
50
+ def [](key)
51
+ @table[key]
52
+ end
53
+
54
+ def []=(key,val)
55
+ modifiable[key] = val
56
+ end
57
+
58
+ def slice(*keys)
59
+ keys.inject(Hash.new) { |m,k| m[k] = @table[k] if @table.key?(k); m }
60
+ end
61
+
62
+ def merge(hash)
63
+ hash.each { |k,v| self[k] = v; new_ostruct_member(k) unless self.respond_to? k }
64
+ self
65
+ end
66
+
67
+ def to_hash
68
+ @table
69
+ end
70
+
71
+ def convert_key(key)
72
+ key.kind_of?(Symbol) ? key : (key.to_sym rescue key)
73
+ end
74
+
75
+ private
76
+
77
+ def raise_argument_error(len, caller)
78
+ raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller
79
+ end
80
+
81
+ def raise_no_method_error(mid, caller)
82
+ raise NoMethodError, "undefined method `#{mid}' for #{self}", caller
83
+ end
84
+ end
85
+
86
+ end
87
+ end