Permalink
Browse files

psql-cm submit implemented.

  • Loading branch information...
1 parent 24b1a6c commit a075880ba328c1d43418dd4ae539568263f08325 @wayneeseguin committed Apr 20, 2012
Showing with 103 additions and 61 deletions.
  1. +2 −0 History.md
  2. +20 −11 README.md
  3. +36 −18 Rakefile
  4. +9 −5 lib/psql-cm/base.rb
  5. +9 −1 lib/psql-cm/cli.rb
  6. +27 −26 lib/psql-cm/submit.rb
View
2 History.md
@@ -5,6 +5,8 @@
--change CLI option for submitting either a sql change string or an sql change
file name.
+Implemented 'submit' action.
+
# 0.0.6 - 2012-04-20
Merged {base.sql, cm.sql} into a single sql-path/{database}/{schema}.sql file.
View
31 README.md
@@ -68,31 +68,36 @@ to a sql file. An example of each follows.
### SQL String
- $ psql-cm submit --database psqlcm_test --change "ALTER TABLE schema_two.a_varchar ADD COLUMN a_timestamp timestamptz;"
+ $ psql-cm submit --database psqlcm_test --schema schema_two --change "ALTER TABLE a_varchar ADD COLUMN a_timestamp timestamptz;"
+
+Note that if you do not specify --schema the change is applied against the
+default schema (typically 'public').
### SQL File
- $ echo "ALTER TABLE schema_two.a_varchar ADD COLUMN a_timestamp timestamptz;" > add_a_timestamp.sql
- $ psql-cm submit --database psqlcm_test --change add_a_timestamp.sql
+ $ echo "ALTER TABLE a_varchar ADD COLUMN a_timestamp timestamptz;" > add_a_timestamp.sql
+ $ psql-cm submit --database psqlcm_test --schema schema_two --change add_a_timestamp.sql
Note that when we do not specify a full path to the file, psql-cm will look
for the file in the current working directory.
-## Command line parameters
+## Options
+
+Available actions are those exposed above
---database argument specifies a single database name and can be used multiple
-times if required, although using the --databases argument (below) is more
-succient and preferred.
+````--database```` argument specifies a single database name and can be used
+multiple times if required, although using the --databases argument (below) is
+more succient and preferred.
$ psql-cm --database a_database
---database argument may take multiple database targets, to do this pass them
-in ',' separated format, no spaces. Specifically the format is,
+````--database```` argument may take multiple database targets, to do this pass
+them in ',' separated format, no spaces. Specifically the format is,
$ psql-cm --databases a_database,another_database,... ...
---uri can be given to change from the default of "postgres://127.0.0.1:5432" and
-has the format,
+````--uri```` can be given to change from the default of
+"postgres://127.0.0.1:5432" and has the format,
$ psql-cm --uri "postgres://{user}:{password}@{host}:{port}/{database}?{sslmode}={mode}"
@@ -188,3 +193,7 @@ seen including all debugging output by running:
rake restore # Create psqlcm_development, run psql-cm actions {setup, dump, restore} in order.
rake setup # Create psqlcm_development and run psql-cm setup on it
+Specifically to do a full-cycle walkthrough on the psqlcm\_development database,
+
+ rake drop create setup dump drop restore
+
View
54 Rakefile
@@ -7,11 +7,18 @@ def database
end
def psqlcm(action, params = {})
- command = %Q|psql-cm --databases #{database} #{action}|
- sh command, params
+ command = "psql-cm #{action}"
+ params[:database] ||= database
+ [:database,:schema,:change].each do |param|
+ if params[param]
+ command << " --#{param} '#{params[param]}'"
+ params.delete(param)
+ end
+ end
+ shell command, params
end
-def sh(command, options = {})
+def shell(command, options = {})
$stdout.puts command if ENV['debug'] || ENV['DEBUG']
exec command if options[:exec]
if ENV['verbose'] || ENV["VERBOSE"]
@@ -28,13 +35,13 @@ end
desc "Build the psql-cm gem."
task :build do
- sh "gem build psql-cm.gemspec"
+ shell "gem build psql-cm.gemspec"
end
desc "Build then install the psql-cm gem."
task :install => :build do
require 'psql-cm/version'
- sh "gem install psql-cm-#{::PSQLCM::Version}.gem"
+ shell "gem install psql-cm-#{::PSQLCM::Version}.gem"
end
desc "Development console, builds installs then runs console"
@@ -44,12 +51,12 @@ end
desc "Drop the development database #{database}"
task :drop do
- sh "dropdb #{database};"
+ shell "dropdb #{database};"
end
desc "Create the development database #{database}, including two schemas."
task :create => [:debug, :install] do
- sh "
+ shell "
createdb #{database} &&
psql #{database} -c '
CREATE SCHEMA schema_one;
@@ -60,8 +67,8 @@ task :create => [:debug, :install] do
"
end
-desc "Create #{database} and run psql-cm setup on it"
-task :setup => [:create] do
+desc "Run psql-cm restore action on #{database}."
+task :setup do
psqlcm "setup"
end
@@ -70,27 +77,38 @@ task :clean do
FileUtils.rm_rf("#{ENV['PWD']}/sql") if Dir.exists?("#{ENV['PWD']}/sql")
end
-desc "Remove sql/ from CWD and then run the psql-cm dump action on #{database}"
+desc "Run psql-cm restore action on #{database}."
task :dump => [:clean] do
psqlcm "dump"
end
-desc "Create #{database}, run psql-cm actions {setup, dump, restore} in order."
-task :restore => [:setup, :dump] do
- psqlcm "setup"
+desc "Run psql-cm restore action on #{database}."
+task :restore do
+ psqlcm "restore"
end
-task :submit => [:setup] do
- # TODO: Add some change submissions here
- psqlcm "submit"
+namespace :submit do
+ task :string => [:install] do
+ sql = "ALTER TABLE a_varchar ADD COLUMN a_timestamp timestamptz;"
+ psqlcm "submit", :schema => "schema_two", :change => sql
+ end
+
+ task :file => [:install] do
+ sql = "CREATE TABLE a_timestamp (a_timestamp timestamptz);"
+ require 'tempfile'
+ Tempfile.open('change.sql') do |change_file|
+ change_file.write sql
+ psqlcm "submit", :schema => "schema_two", :change => change_file.path
+ end
+ end
end
task :release do
require 'psql-cm/version'
- sh "
+ shell "
git tag #{::PSQLCM::Version};
git push origin --tags;
gem build psql-cm.gemspec;
- gem push psql-cm-#{::PSQLCM::Version}.gem
+ gem push psql-cm-#{::PSQLCM::Version}.gem;
"
end
View
14 lib/psql-cm/base.rb
@@ -31,13 +31,16 @@ def databases
@databases
end
- def schemas(name = 'postgres')
- @schemas = db(name).
- exec("SELECT nspname AS name FROM pg_namespace WHERE nspname !~ '^pg_.*|information_schema';").
- map{|row| row['name']}
+ def schemas(dbname = 'postgres')
+ schema_select = "SELECT nspname AS name FROM pg_namespace WHERE nspname !~ '^pg_.*|information_schema';"
+
+ @schemas = db(dbname).exec(schema_select).map{|row| row['name']}
# Filter out schemas not specified, if specified.
- @schemas.select!{ |name| config.schemas.include?(name) } if config.schemas
+ unless config.schemas.empty?
+ @schemas.select!{ |name| config.schemas.include?(name) }
+ end
+
debug "schemas> #{@schemas}"
@schemas
end
@@ -132,4 +135,5 @@ def sql_path
::PSQLCM.config.debug = !!ENV['DEBUG']
::PSQLCM.config.cm_table = 'pg_psql_cm' # Default --cm-table name.
::PSQLCM.config.databases = []
+::PSQLCM.config.schemas = []
View
10 lib/psql-cm/cli.rb
@@ -22,11 +22,19 @@ def parse!(arguments)
::PSQLCM.config.databases += names.split(',')
end
+ options.on('-s', '--schema NAME', 'A single schemas name.') do |name|
+ ::PSQLCM.config.schemas << name
+ end
+
+ options.on('-m', '--schemas NAMES', 'A comma separated list of schemas to cm.') do |names|
+ ::PSQLCM.config.schemas += names.split(',')
+ end
+
options.on('-u', '--uri URI', 'Path to the sink database connection file.') do |uri|
::PSQLCM.config.uri = uri
end
- options.on('-c', '--change SQL') do |change|
+ options.on('-c', '--change SQL|FILE') do |change|
::PSQLCM.config.change = change
end
View
53 lib/psql-cm/submit.rb
@@ -1,35 +1,36 @@
module PSQLCM
class << self
def submit!
- puts "TODO: allow change string and/or file to be specified and add to the
- specified database scema control table"
-
- if config.change.to_s.empty?
- halt! "Content must be given! (--content=<file or \"sql string\">)"
- elsif File.exists?(config.change)
- content = File.open(config.change, 'r') { |file| file.read }
- else # SQL String
- content = %x{cat #{temp_file.path}}
- end
-
- debug "validate> #{database}.#{schema}.#{config.cm_table}: #{config.change}"
-
- # TODO:
- # - Ensure no 'INSERT' or 'COPY' if SQL string.
- # - Transactional Validation
-
- name = %x{git config user.name}.strip
- email = %x{git config user.email}.strip
- implementer = "#{name}"
- implementer << "<#{email}>" unless email.empty?
-
- debug "submit> #{database}.#{schema}.#{config.cm_table}: #{config.change}"
- db(database).exec(
- "INSERT INTO #{schema}.#{config.cm_table}
+ databases.each do |database|
+ schemas(database).each do |schema|
+ if config.change.to_s.empty?
+ halt! "Content must be given! (--content=<file or \"sql string\">)"
+ elsif File.exists?(config.change)
+ content = File.open(config.change, 'r') { |file| file.read }
+ else # SQL String
+ content = config.change
+ end
+
+ name = %x{git config user.name}.strip
+ email = %x{git config user.email}.strip
+ implementer = "#{name}"
+ implementer << "<#{email}>" unless email.empty?
+
+ debug "validate> #{database}.#{schema}.#{config.cm_table}: #{config.change}"
+
+ # Transactional Validation -- Submit if successful, blow up otherwise.
+ transaction = "BEGIN;SET search_path TO #{schema},public; #{content}; COMMIT;"
+ result = db(database).exec(transaction)
+
+ debug "submit> #{database}.#{schema}.#{config.cm_table}: #{config.change}"
+ db(database).exec(
+ "INSERT INTO #{schema}.#{config.cm_table}
(is_base,implementer,content)
VALUES (false,$1,$2)",
[implementer,content]
- )
+ )
+ end # schemas
+ end # databases
end # def submit!
private

0 comments on commit a075880

Please sign in to comment.