psql-cm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2009 Wayne E. Seguin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # PostgreSQL Change Management Tool
2
+
3
+
4
+
data/bin/psql-cm ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'psql-cm'
4
+ require 'psql-cm/cli'
5
+
6
+ ::PSQLCM::CLI.parse!(ARGV)
7
+
8
+ ::PSQLCM.run!(ARGV.shift)
9
+
10
+
@@ -0,0 +1,114 @@
1
+ module PSQLCM
2
+ class << self
3
+ def verbose(message)
4
+ $stdout.puts message if (config.verbose || config.debug)
5
+ end
6
+
7
+ def debug(message)
8
+ $stdout.puts message if config.debug
9
+ end
10
+
11
+ def halt!(message)
12
+ $stderr.puts message
13
+ exit 1
14
+ end
15
+
16
+ def config
17
+ require 'ostruct'
18
+ @config ||= OpenStruct.new
19
+ end # def self.config
20
+
21
+ def databases
22
+ @databases = db.
23
+ exec("SELECT datname as name FROM pg_database WHERE datname !~ 'template*|postgres';").
24
+ map {|row| row["name"]}
25
+
26
+ debug "databases> #{@databases}"
27
+ unless config.databases.to_a.empty?
28
+ @databases.select!{ |name| config.databases.include?(name) }
29
+ end
30
+ @databases
31
+ end
32
+
33
+ def schemas
34
+ @schemas = db.
35
+ exec("SELECT nspname as name FROM pg_namespace WHERE nspname !~ '^pg_.*|information_schema';").
36
+ map{|row| row["name"]}
37
+ debug "schemas> #{@schemas}"
38
+ @schemas
39
+ end
40
+
41
+ def tree
42
+ return @tree if @tree
43
+ @tree = {}
44
+ databases.each do |name|
45
+ @config.connection["dbname"] = name and reconnect!
46
+ @tree[name] = {}
47
+ schemas.each do |schema|
48
+ @tree[name][schema] = ['base.sql', 'cm.sql']
49
+ end
50
+ end
51
+ debug "tree> tree: #{@tree}"
52
+ @tree
53
+ end
54
+
55
+ def generate!
56
+ unless config.sql_path
57
+ $stdout.puts "Warning: --sql-path was not set, defaulting to $PWD/sql."
58
+ config.sql_path = "#{ENV["PWD"]}/sql"
59
+ end
60
+
61
+ FileUtils.mkdir(config.sql_path) unless File.directory?(config.sql_path)
62
+
63
+ debug "generate> sql_path: #{config.sql_path}"
64
+ Dir.chdir(config.sql_path) do
65
+ tree.each_pair do |database, hash|
66
+ debug "generate> database: #{database}"
67
+
68
+ File.directory?(File.join(config.sql_path,database)) or
69
+ FileUtils.mkdir(File.join(config.sql_path,database))
70
+
71
+ hash.each_pair do |schema, files|
72
+ debug "generate> schema: #{schema}"
73
+ File.directory?(File.join(config.sql_path,database,schema)) or
74
+ FileUtils.mkdir(File.join(config.sql_path,database,schema))
75
+
76
+ base_file = File.join(config.sql_path,database,schema,'base.sql')
77
+ cm_file = File.join(config.sql_path,database,schema,'cm.sql')
78
+
79
+ FileUtils.touch(base_file)
80
+ FileUtils.touch(cm_file)
81
+
82
+ command = "pg_dump --schema-only --no-owner --schema=#{schema} "
83
+ if File.size(base_file) > 0
84
+ command += "--file=#{cm_file} --table=psql_cm "
85
+ else
86
+ command += "--file=#{base_file} --exclude-table=psql_cm "
87
+ end
88
+ command += "#{database}"
89
+ debug "generate> #{command}"
90
+
91
+ %x[#{command}]
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ def run!(action = config.action, parent_id = config.parent_id)
98
+ case action
99
+ when "console"
100
+ ::PSQLCM.debug "Starting Console"
101
+ require 'psql-cm/cli'
102
+ ::PSQLCM::Console.run!
103
+ when "generate"
104
+ generate!
105
+ else
106
+ halt! "Action '#{action}' is not handled."
107
+ end
108
+ end
109
+
110
+ end # class << self
111
+ end
112
+
113
+ ::PSQLCM.config.debug = !!ENV['DEBUG']
114
+
@@ -0,0 +1,64 @@
1
+ require 'optparse'
2
+
3
+ module PSQLCM
4
+ class CLI
5
+
6
+ class << self
7
+ def parse!(arguments)
8
+ ::OptionParser.new do |options|
9
+ options.banner = "Usage: psql-cm [options]"
10
+ options.separator ""
11
+ options.separator "Specific options:"
12
+
13
+ options.on("-s", "--sql-path PATH", "Path to generate SQL cm files.") do |path|
14
+ ::PSQLCM.config.sql_path = path
15
+ end
16
+
17
+ options.on("-a", "--databases NAMES", "A comma separated list of databases to cm.") do |names|
18
+ ::PSQLCM.config.databases = names.split(',')
19
+ end
20
+
21
+ options.on("-u", "--uri URI", "Path to the sink database connection file.") do |uri|
22
+ ::PSQLCM.configure!(uri)
23
+ end
24
+
25
+ options.on("-D", "--[no-]debug", "Output debugging information.") do |debug|
26
+ ::PSQLCM.config.debug = debug.nil? ? false : true
27
+ end
28
+
29
+ options.on("-v", "--[no-]verbose", "Output verbosley.") do |verbose|
30
+ ::PSQLCM.config.verbose = verbose
31
+ end
32
+
33
+ options.on_tail("-h", "--help", "Print help and exit.") do
34
+ puts options
35
+ exit 0
36
+ end
37
+
38
+ options.on_tail("--version", "Print version and exit.") do
39
+ require 'psql-cm/version'
40
+ puts ::PSQLCM::Version
41
+ exit 0
42
+ end
43
+
44
+ options.parse!(arguments)
45
+
46
+ options
47
+ end # OptionParser.new
48
+ end # def self.parse
49
+
50
+ end # class << self
51
+ end # class CLI
52
+
53
+ class Console
54
+ class << self
55
+
56
+ def run!
57
+ require 'irb'
58
+ IRB.start
59
+ end
60
+
61
+ end # class << self
62
+ end # class Console
63
+ end # module PSQLCM
64
+
@@ -0,0 +1,41 @@
1
+ require 'uri'
2
+
3
+ module PSQLCM
4
+ # "postgres://{user}:{password}@{host}:{port}/{database}"
5
+ class << self
6
+ def db
7
+ return @db if @db
8
+ connect!
9
+ end
10
+
11
+ def connect!
12
+ @config.connection ||= {"dbname" => "postgres"}
13
+ @db = PG.connect(@config.connection)
14
+ end
15
+
16
+ def reconnect!
17
+ @db.close
18
+ connect!
19
+ end
20
+
21
+ def configure!(uri)
22
+ uri = URI.parse(::PSQLCM.config.uri)
23
+
24
+ query = uri.query.to_s.split('&')
25
+
26
+ timeout = query.detect { |k| k.match /connect_timeout=/ }.to_s.sub(/.*=/,'')
27
+ sslmode = query.detect { |k| k.match /sslmode=/ }.to_s.sub(/.*=/,'')
28
+
29
+ @config.connection = {
30
+ :host => uri.host,
31
+ :port => uri.port || 5432,
32
+ :dbname => "postgres", # uri.path.sub('/',''),
33
+ :user => uri.user,
34
+ :password => uri.password,
35
+ :connect_timeout => timeout.empty? ? 20 : timeout.to_i,
36
+ :sslmode => sslmode.empty? ? "disable" : sslmode # (disable|allow|prefer|require)
37
+ }.delete_if { |key, value| value.nil? }
38
+ end
39
+ end # class << self
40
+ end # module PSQLCM
41
+
@@ -0,0 +1,4 @@
1
+ module PSQLCM
2
+ Version = '0.0.1'
3
+ end
4
+
data/lib/psql-cm.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'pg'
2
+ require 'fileutils'
3
+
4
+ require_relative 'psql-cm/base'
5
+ require_relative 'psql-cm/database'
6
+
@@ -0,0 +1,6 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe PSQLCM do
4
+ before do
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+
4
+ require 'psql-cm'
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: psql-cm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Wayne E. Seguin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: pg
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: PostgreSQL Change Management Tool
31
+ email:
32
+ - wayneeseguin@gmail.com
33
+ executables:
34
+ - psql-cm
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - bin/psql-cm
39
+ - lib/psql-cm/base.rb
40
+ - lib/psql-cm/cli.rb
41
+ - lib/psql-cm/database.rb
42
+ - lib/psql-cm/version.rb
43
+ - lib/psql-cm.rb
44
+ - LICENCE
45
+ - README.md
46
+ - spec/psql-cm_spec.rb
47
+ - spec/spec_helper.rb
48
+ homepage: http://rubygems.org/gems/psql-cm/
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ version: 1.9.3
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 1.8.22
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.22
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: PostgreSQL CM
72
+ test_files:
73
+ - spec/psql-cm_spec.rb
74
+ - spec/spec_helper.rb