psql-cm 0.0.6 → 0.0.7

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.
data/History.md CHANGED
@@ -1,3 +1,12 @@
1
+ # 0.0.7 - 2012-04-20
2
+
3
+ --database CLI option for specifying a single database name.
4
+
5
+ --change CLI option for submitting either a sql change string or an sql change
6
+ file name.
7
+
8
+ Implemented 'submit' action.
9
+
1
10
  # 0.0.6 - 2012-04-20
2
11
 
3
12
  Merged {base.sql, cm.sql} into a single sql-path/{database}/{schema}.sql file.
data/README.md CHANGED
@@ -44,40 +44,67 @@ Once the prerequisites have been satisfied on your system, using the
44
44
  Setup the psql\_cm control tables on the target databases, use a comma (',')
45
45
  to separate multiple database names.
46
46
 
47
- $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" setup
47
+ $ psql-cm setup --database psqlcm_test
48
48
 
49
49
  ## Dump
50
50
 
51
51
  Dump the current database schema to the specified --sql-path directory, if none
52
52
  specified it dumps to $PWD/sql
53
53
 
54
- $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" dump
54
+ $ psql-cm dump --database psqlcm_test
55
55
 
56
56
  ## Restore
57
57
 
58
58
  Restore a previously psql-cm dumped database schema into a brand new postgresql
59
59
  database cluster.
60
60
 
61
- $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" restore
61
+ $ psql-cm restore --database psqlcm_test
62
62
 
63
- ## Change
63
+ ## Submit
64
64
 
65
- TODO: Document how to commit a change.
65
+ There are two ways to submit schema changes. The first is by passing the schema
66
+ change on the command line as a string and the second is by specifying the path
67
+ to a sql file. An example of each follows.
66
68
 
67
- ## Command line parameters
69
+ ### SQL String
68
70
 
69
- --databases argument may take multiple database targets, to do this pass them
70
- in ',' separated format, no spaces. Specifically the format is,
71
+ $ psql-cm submit --database psqlcm_test --schema schema_two --change "ALTER TABLE a_varchar ADD COLUMN a_timestamp timestamptz;"
71
72
 
72
- $ psql-cm --databases adatabase,anotherdatabase,... ...
73
+ Note that if you do not specify --schema the change is applied against the
74
+ default schema (typically 'public').
73
75
 
74
- --uri has the format,
76
+ ### SQL File
77
+
78
+ $ echo "ALTER TABLE a_varchar ADD COLUMN a_timestamp timestamptz;" > add_a_timestamp.sql
79
+ $ psql-cm submit --database psqlcm_test --schema schema_two --change add_a_timestamp.sql
80
+
81
+ Note that when we do not specify a full path to the file, psql-cm will look
82
+ for the file in the current working directory.
83
+
84
+ ## Options
85
+
86
+ Available actions are those exposed above
87
+
88
+ ````--database```` argument specifies a single database name and can be used
89
+ multiple times if required, although using the --databases argument (below) is
90
+ more succient and preferred.
91
+
92
+ $ psql-cm --database a_database
93
+
94
+ ````--database```` argument may take multiple database targets, to do this pass
95
+ them in ',' separated format, no spaces. Specifically the format is,
96
+
97
+ $ psql-cm --databases a_database,another_database,... ...
98
+
99
+ ````--uri```` can be given to change from the default of
100
+ "postgres://127.0.0.1:5432" and has the format,
75
101
 
76
102
  $ psql-cm --uri "postgres://{user}:{password}@{host}:{port}/{database}?{sslmode}={mode}"
77
103
 
78
- user, password, port, the ? and everything after it (the query) are all optional.
104
+ Host and database are the only required entries in a uri string. Eg. user,
105
+ password, port, the ? and everything after it (the query) are all optional.
79
106
 
80
- sslmode mode may be one of disable, allow, prefer, require if used.
107
+ sslmode mode may be one of {disable, allow, prefer, require} if it is used.
81
108
 
82
109
  # Walkthrough
83
110
 
@@ -90,16 +117,12 @@ by default when the database is created) and a table for each schema for our
90
117
  database.
91
118
 
92
119
  $ psql psqlcm_test -c '
93
- SET search_path = public;
94
120
  CREATE SCHEMA schema_one;
95
- CREATE TABLE a_bool(a BOOL);
96
-
97
- SET search_path = schema_one;
98
- CREATE TABLE an_integer(an INTEGER);
99
-
100
121
  CREATE SCHEMA schema_two;
101
- SET search_path = schema_two;
102
- CREATE TABLE a_varchar(a VARCHAR);'
122
+ CREATE TABLE public.a_bool(a BOOL);
123
+ CREATE TABLE schema_one.an_integer(an INTEGER);
124
+ CREATE TABLE schema_two.a_varchar(a VARCHAR);'
125
+
103
126
 
104
127
  Now that we have a base set of database(s) and schemas that we wish to apply
105
128
  change management process to we can setup the psql-cm control tables.
@@ -107,7 +130,7 @@ change management process to we can setup the psql-cm control tables.
107
130
  The setup action adds one table called 'pg\_psql\_cm' to each of the target
108
131
  database schemas.
109
132
 
110
- $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" setup
133
+ $ psql-cm --database psqlcm_test setup
111
134
 
112
135
  Use a PostgreSQL client tool (psql/pgAdmin/Navicat/...) and examine the schemas
113
136
  for the psqlcm\_test database for which there should be three:
@@ -120,29 +143,23 @@ each with two tables, the pg\_psql\_cm control table and one other table.
120
143
 
121
144
  Next we'll dump the schema to sql/ within our working directory
122
145
 
123
- $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" dump
146
+ $ psql-cm --database psqlcm_test dump
124
147
 
125
148
  At this point we have the base schema for the psqlcm\_test database recorded to
126
149
  the filesystem. You can see the filesystem structure and contents with
127
150
  a find command on \*nix:
128
151
 
129
- $ find sql/psqlcm_test
152
+ $ find sql/psqlcm_test/
130
153
  sql/psqlcm_test
131
- sql/psqlcm_test/public
132
- sql/psqlcm_test/public/base.sql
133
- sql/psqlcm_test/public/cm.sql
134
- sql/psqlcm_test/schema_one
135
- sql/psqlcm_test/schema_one/base.sql
136
- sql/psqlcm_test/schema_one/cm.sql
137
- sql/psqlcm_test/schema_two
138
- sql/psqlcm_test/schema_two/base.sql
139
- sql/psqlcm_test/schema_two/cm.sql
154
+ sql/psqlcm_test/public.sql
155
+ sql/psqlcm_test/schema_one.sql
156
+ sql/psqlcm_test/schema_two.sql
140
157
 
141
158
  We can now do a restore restore by droping the database and then running the
142
159
  psql-cm restore action.
143
160
 
144
161
  $ dropdb psqlcm_test
145
- $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" restore
162
+ $ psql-cm --database psqlcm_test restore
146
163
 
147
164
  Once again useing a client tool and verify that the schema is inded what it was
148
165
  after setup was run.
@@ -176,3 +193,7 @@ seen including all debugging output by running:
176
193
  rake restore # Create psqlcm_development, run psql-cm actions {setup, dump, restore} in order.
177
194
  rake setup # Create psqlcm_development and run psql-cm setup on it
178
195
 
196
+ Specifically to do a full-cycle walkthrough on the psqlcm\_development database,
197
+
198
+ rake drop create setup dump drop restore
199
+
data/lib/psql-cm/base.rb CHANGED
@@ -22,7 +22,7 @@ module PSQLCM
22
22
  exec("SELECT datname as name FROM pg_database WHERE datname !~ 'template*|postgres';").
23
23
  map {|row| row['name']}
24
24
 
25
- if config.databases.to_a.empty?
25
+ if config.databases.empty?
26
26
  halt! 'A list of databases must be given:\n --databases={database_one}[,{database_two}[,...]]'
27
27
  else # filter out databases not specified.
28
28
  @databases.select!{ |name| config.databases.include?(name) }
@@ -31,13 +31,16 @@ module PSQLCM
31
31
  @databases
32
32
  end
33
33
 
34
- def schemas(name = 'postgres')
35
- @schemas = db(name).
36
- exec("SELECT nspname AS name FROM pg_namespace WHERE nspname !~ '^pg_.*|information_schema';").
37
- map{|row| row['name']}
34
+ def schemas(dbname = 'postgres')
35
+ schema_select = "SELECT nspname AS name FROM pg_namespace WHERE nspname !~ '^pg_.*|information_schema';"
36
+
37
+ @schemas = db(dbname).exec(schema_select).map{|row| row['name']}
38
38
 
39
39
  # Filter out schemas not specified, if specified.
40
- @schemas.select!{ |name| config.schemas.include?(name) } if config.schemas
40
+ unless config.schemas.empty?
41
+ @schemas.select!{ |name| config.schemas.include?(name) }
42
+ end
43
+
41
44
  debug "schemas> #{@schemas}"
42
45
  @schemas
43
46
  end
@@ -78,7 +81,7 @@ module PSQLCM
78
81
 
79
82
  def uri
80
83
  return config.uri unless config.uri.to_s.empty?
81
- $stdout.puts "NOTICE: uri is not set, defaulting to postgres://127.0.0.1:5432 (format: postgres://{user}:{password}@{host}:{port}/{database}\nwhere user, password, port and database are optional)"
84
+ $stdout.puts "NOTICE: uri is not set, defaulting to postgres://127.0.0.1:5432 (format: postgres://{user}:{password}@{host}:{port}/{database} (where user, password, port and database are optional)"
82
85
  config.uri = "postgres://127.0.0.1:5432"
83
86
  end
84
87
 
@@ -128,6 +131,9 @@ module PSQLCM
128
131
  end # class << self
129
132
  end
130
133
 
134
+ # Module configuration, initial values
131
135
  ::PSQLCM.config.debug = !!ENV['DEBUG']
132
136
  ::PSQLCM.config.cm_table = 'pg_psql_cm' # Default --cm-table name.
137
+ ::PSQLCM.config.databases = []
138
+ ::PSQLCM.config.schemas = []
133
139
 
data/lib/psql-cm/cli.rb CHANGED
@@ -10,18 +10,38 @@ module PSQLCM
10
10
  options.separator ''
11
11
  options.separator 'Specific options:'
12
12
 
13
- options.on('-s', '--sql-path PATH', 'Path to dump SQL cm files into.') do |path|
13
+ options.on('-p', '--sql-path PATH', 'Path to dump SQL cm files into.') do |path|
14
14
  ::PSQLCM.config.sql_path = path
15
15
  end
16
16
 
17
- options.on('-a', '--databases=NAMES', 'A comma separated list of databases to cm.') do |names|
18
- ::PSQLCM.config.databases = names.split(',')
17
+ options.on('-d', '--database NAME', 'A single databases name.') do |name|
18
+ ::PSQLCM.config.databases << name
19
19
  end
20
20
 
21
- options.on('-u', '--uri=URI', 'Path to the sink database connection file.') do |uri|
21
+ options.on('-a', '--databases NAMES', 'A comma separated list of databases to cm.') do |names|
22
+ ::PSQLCM.config.databases += names.split(',')
23
+ end
24
+
25
+ options.on('-s', '--schema NAME', 'A single schemas name.') do |name|
26
+ ::PSQLCM.config.schemas << name
27
+ end
28
+
29
+ options.on('-m', '--schemas NAMES', 'A comma separated list of schemas to cm.') do |names|
30
+ ::PSQLCM.config.schemas += names.split(',')
31
+ end
32
+
33
+ options.on('-u', '--uri URI', 'Path to the sink database connection file.') do |uri|
22
34
  ::PSQLCM.config.uri = uri
23
35
  end
24
36
 
37
+ options.on('-c', '--change SQL|FILE') do |change|
38
+ ::PSQLCM.config.change = change
39
+ end
40
+
41
+ options.on('-t', '--cm-table TABLE') do |cm_table|
42
+ ::PSQLCM.config.cm_table = cm_table
43
+ end
44
+
25
45
  options.on('-D', '--[no-]debug', 'Output debugging information.') do |debug|
26
46
  ::PSQLCM.config.debug = debug.nil? ? false : true
27
47
  end
@@ -30,10 +50,6 @@ module PSQLCM
30
50
  ::PSQLCM.config.verbose = verbose
31
51
  end
32
52
 
33
- options.on('-c', '--cm-table=TABLE') do |cm_table|
34
- ::PSQLCM.config.cm_table = cm_table
35
- end
36
-
37
53
  options.on_tail('-h', '--help', 'Print help and exit.') do
38
54
  puts options
39
55
  exit 0
data/lib/psql-cm/setup.rb CHANGED
@@ -10,14 +10,19 @@ module PSQLCM
10
10
  Tempfile.open('base.sql') do |temp_file|
11
11
  sh " pg_dump #{db(database).psql_args} --schema-only --no-owner --schema=#{schema} --file=#{temp_file.path} #{database}"
12
12
 
13
- contents = %x{cat #{temp_file.path}}
14
- implementer = %Q|#{%x[git config user.name].strip} <#{%x[git config user.email].strip}>|
13
+ content = %x{cat #{temp_file.path}}
14
+ name = %x{git config user.name}.strip
15
+ email = %x{git config user.email}.strip
16
+ implementer = "#{name}"
17
+ implementer << "<#{email}>" unless email.empty?
18
+
15
19
  db(database).exec(
16
- "INSERT INTO #{schema}.#{config.cm_table} (is_base, implementer, content) VALUES (true, $1, $2);",
17
- [implementer, contents]
20
+ "INSERT INTO #{schema}.#{config.cm_table}
21
+ (is_base, implementer, content)
22
+ VALUES (true, $1, $2);",
23
+ [implementer, content]
18
24
  )
19
25
  end
20
-
21
26
  end
22
27
  end
23
28
 
@@ -1,14 +1,42 @@
1
1
  module PSQLCM
2
2
  class << self
3
3
  def submit!
4
- puts "TODO: allow change string and/or file to be specified and add to the
5
- specified database scema control table"
4
+ databases.each do |database|
5
+ schemas(database).each do |schema|
6
+ if config.change.to_s.empty?
7
+ halt! "Content must be given! (--content=<file or \"sql string\">)"
8
+ elsif File.exists?(config.change)
9
+ content = File.open(config.change, 'r') { |file| file.read }
10
+ else # SQL String
11
+ content = config.change
12
+ end
6
13
 
7
- # TOOD: get values x,y,z
8
- sql = "INSERT INTO #{schema}.#{config.cm_table} (is_base,implementer,content) VALUES (x,y,z)"
9
- debug "submit:#{database}:#{schema}> sql\n#{sql}"
10
- db(database).exec sql
14
+ name = %x{git config user.name}.strip
15
+ email = %x{git config user.email}.strip
16
+ implementer = "#{name}"
17
+ implementer << "<#{email}>" unless email.empty?
18
+
19
+ debug "validate> #{database}.#{schema}.#{config.cm_table}: #{config.change}"
20
+
21
+ # Transactional Validation -- Submit if successful, blow up otherwise.
22
+ transaction = "BEGIN;SET search_path TO #{schema},public; #{content}; COMMIT;"
23
+ result = db(database).exec(transaction)
24
+
25
+ debug "submit> #{database}.#{schema}.#{config.cm_table}: #{config.change}"
26
+ db(database).exec(
27
+ "INSERT INTO #{schema}.#{config.cm_table}
28
+ (is_base,implementer,content)
29
+ VALUES (false,$1,$2)",
30
+ [implementer,content]
31
+ )
32
+ end # schemas
33
+ end # databases
11
34
  end # def submit!
35
+
36
+ private
37
+
38
+ def validate(change)
39
+
40
+ end
12
41
  end
13
42
  end
14
-
@@ -1,4 +1,4 @@
1
1
  module PSQLCM
2
- Version = '0.0.6'
2
+ Version = '0.0.7'
3
3
  end
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: psql-cm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -48,8 +48,6 @@ files:
48
48
  - LICENCE
49
49
  - README.md
50
50
  - History.md
51
- - spec/psql-cm_spec.rb
52
- - spec/spec_helper.rb
53
51
  homepage: http://rubygems.org/gems/psql-cm/
54
52
  licenses: []
55
53
  post_install_message:
@@ -74,6 +72,4 @@ rubygems_version: 1.8.22
74
72
  signing_key:
75
73
  specification_version: 3
76
74
  summary: PostgreSQL CM
77
- test_files:
78
- - spec/psql-cm_spec.rb
79
- - spec/spec_helper.rb
75
+ test_files: []
data/spec/psql-cm_spec.rb DELETED
@@ -1,6 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- describe PSQLCM do
4
- before do
5
- end
6
- end
data/spec/spec_helper.rb DELETED
@@ -1,4 +0,0 @@
1
- require 'minitest/spec'
2
- require 'minitest/autorun'
3
-
4
- require 'psql-cm'