psql-cm 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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'