psql-cm 0.0.5 → 0.0.6

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,15 @@
1
+ # 0.0.6 - 2012-04-20
2
+
3
+ Merged {base.sql, cm.sql} into a single sql-path/{database}/{schema}.sql file.
4
+
5
+ Base is now the first change in the {schema}.sql CM file.
6
+
7
+ Made Configuration Managment table name configurable via cli using -c|--cm-table=
8
+
9
+ Made debug message output more structured and clear.
10
+
11
+ Created {drop,create,setup,dump,restore} rake tasks for qa-ing.
12
+
1
13
  # 0.0.5 - 2012-04-18
2
14
 
3
15
  Added git repository feature to sql-path for dump action, a commit per run of
data/README.md CHANGED
@@ -15,8 +15,7 @@ combined with complimentary process and adherence.
15
15
 
16
16
  ## What psql-cm is not
17
17
 
18
- psql-cm is not intended on being a solution whatsoever for data backup.
19
-
18
+ psql-cm is not intended on being a solution for data backup.
20
19
  For backup of data instead use the
21
20
  [pg\_dump](http://www.postgresql.org/docs/current/static/app-pgdump.html)
22
21
  command line utility for backing up data in addition to a
@@ -61,12 +60,16 @@ database cluster.
61
60
 
62
61
  $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" restore
63
62
 
63
+ ## Change
64
+
65
+ TODO: Document how to commit a change.
66
+
64
67
  ## Command line parameters
65
68
 
66
69
  --databases argument may take multiple database targets, to do this pass them
67
70
  in ',' separated format, no spaces. Specifically the format is,
68
71
 
69
- $ psql-cm --databases psqlcm_test,psqlcm_test2,... ...
72
+ $ psql-cm --databases adatabase,anotherdatabase,... ...
70
73
 
71
74
  --uri has the format,
72
75
 
@@ -119,16 +122,57 @@ Next we'll dump the schema to sql/ within our working directory
119
122
 
120
123
  $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" dump
121
124
 
122
- At this point we have the base schema for the psqlcm\_test database recorded and
123
- we can test to see that this is true by droping the database and then running
124
- the psql-cm restore action.
125
+ At this point we have the base schema for the psqlcm\_test database recorded to
126
+ the filesystem. You can see the filesystem structure and contents with
127
+ a find command on \*nix:
128
+
129
+ $ find sql/psqlcm_test
130
+ 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
140
+
141
+ We can now do a restore restore by droping the database and then running the
142
+ psql-cm restore action.
125
143
 
126
144
  $ dropdb psqlcm_test
127
145
  $ psql-cm --databases psqlcm_test --uri "postgres://127.0.0.1:5432" restore
128
146
 
129
- Once again use yoru favorite client tool and verify that the schema is inded
130
- what it was after setup was run.
147
+ Once again useing a client tool and verify that the schema is inded what it was
148
+ after setup was run.
149
+
150
+ NOTE: one caveat is that psql-cm does not handle ROLEs and USERs so these will
151
+ have to be accounted for after doing a restore.
152
+
153
+ ## Debugging
154
+
155
+ Debugging output can be enabled by exporting DEBUG=true in the environment
156
+ before calling the psql-cm command:
157
+
158
+ $ export debug=true
159
+
160
+ ## Development
161
+
162
+ To play around inside of a running psql-cm Ruby environment use the console:
163
+
164
+ rake console # Development console, builds installs then runs console
165
+
166
+ The 'Walkthrough' from above is encoded as rake tasks, each step can be
167
+ seen including all debugging output by running:
131
168
 
132
- Note that one caveat is that psql-cm does not handle ROLEs and USERs so these
133
- will have to be accounted for after doing a restore.
169
+ rake clean # Remove the sql/ directory in the current working directory.
170
+ rake create # Create the development database psqlcm_development, including two schemas.
171
+ rake debug # Enable debugging using environment variable DEBUG
172
+ rake drop # Drop the development database psqlcm_development
173
+ rake dump # Remove sql/ from CWD and then run the psql-cm dump action on psqlcm_development
174
+ rake build # Build the psql-cm gem.
175
+ rake install # Build then install the psql-cm gem.
176
+ rake restore # Create psqlcm_development, run psql-cm actions {setup, dump, restore} in order.
177
+ rake setup # Create psqlcm_development and run psql-cm setup on it
134
178
 
data/lib/psql-cm/base.rb CHANGED
@@ -20,12 +20,13 @@ module PSQLCM
20
20
  def databases
21
21
  @databases = db.
22
22
  exec("SELECT datname as name FROM pg_database WHERE datname !~ 'template*|postgres';").
23
- map {|row| row["name"]}
23
+ map {|row| row['name']}
24
24
 
25
- unless config.databases.to_a.empty? # filter out databases not specified.
25
+ if config.databases.to_a.empty?
26
+ halt! 'A list of databases must be given:\n --databases={database_one}[,{database_two}[,...]]'
27
+ else # filter out databases not specified.
26
28
  @databases.select!{ |name| config.databases.include?(name) }
27
29
  end
28
-
29
30
  debug "databases> #{@databases}"
30
31
  @databases
31
32
  end
@@ -33,7 +34,10 @@ module PSQLCM
33
34
  def schemas(name = 'postgres')
34
35
  @schemas = db(name).
35
36
  exec("SELECT nspname AS name FROM pg_namespace WHERE nspname !~ '^pg_.*|information_schema';").
36
- map{|row| row["name"]}
37
+ map{|row| row['name']}
38
+
39
+ # Filter out schemas not specified, if specified.
40
+ @schemas.select!{ |name| config.schemas.include?(name) } if config.schemas
37
41
  debug "schemas> #{@schemas}"
38
42
  @schemas
39
43
  end
@@ -42,149 +46,88 @@ module PSQLCM
42
46
  return @tree if @tree
43
47
  @tree = {}
44
48
  databases.each do |dbname|
45
- @tree[dbname] = {}
46
- schemas(dbname).each do |schema|
47
- @tree[dbname][schema] = ['base.sql', 'cm.sql']
48
- end
49
+ @tree[dbname] = schemas(dbname)
49
50
  end
50
- debug "tree> tree: #{@tree}"
51
+ debug "tree> #{@tree}"
51
52
  @tree
52
53
  end
53
54
 
54
- def dump!
55
- unless config.sql_path
56
- $stdout.puts "Warning: --sql-path was not set, defaulting to $PWD/sql."
57
- config.sql_path = "#{ENV["PWD"]}/sql"
55
+ def run!(action = config.action)
56
+ case action
57
+ when 'console'
58
+ require 'psql-cm/cli'
59
+ ::PSQLCM::Console.run!
60
+ when 'dump'
61
+ dump!
62
+ when 'restore'
63
+ restore!
64
+ when 'setup'
65
+ setup!
66
+ when 'submit'
67
+ submit!
68
+ else
69
+ halt! "An action must be given! {setup, dump, restore}" if action.nil?
70
+ halt! "Action '#{action}' is not handled."
58
71
  end
72
+ end
59
73
 
60
- debug "dump> sql_path: #{config.sql_path}"
61
- FileUtils.mkdir(config.sql_path) unless File.directory?(config.sql_path)
62
- Dir.chdir(config.sql_path) do
63
- tree.each_pair do |database, schema_hash|
64
- debug "dump> database: #{database}"
65
-
66
- File.directory?(File.join(config.sql_path,database)) or
67
- FileUtils.mkdir(File.join(config.sql_path,database))
68
-
69
- schema_hash.each_pair do |schema, files|
70
- debug "dump> schema: #{schema}"
71
- File.directory?(File.join(config.sql_path,database,schema)) or
72
- FileUtils.mkdir(File.join(config.sql_path,database,schema))
73
-
74
- base_file = File.join(config.sql_path,database,schema,'base.sql')
75
- cm_file = File.join(config.sql_path,database,schema,'cm.sql')
76
-
77
- FileUtils.touch(base_file)
78
- FileUtils.touch(cm_file)
74
+ def sh(command)
75
+ debug "$ #{command}"
76
+ %x[#{command} 2>&1 | awk '! /NOTICE/']
77
+ end
79
78
 
80
- command = "pg_dump #{db(database).psql_args} --schema-only --no-owner --schema=#{schema} "
81
- if File.size(base_file) > 0
82
- command += "--file=#{cm_file} --table=psql_cm "
83
- else
84
- command += "--file=#{base_file} --exclude-table=psql_cm "
85
- end
86
- command += "#{database}"
87
- sh 'dump', command
88
- end
89
- end
79
+ def uri
80
+ 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)"
82
+ config.uri = "postgres://127.0.0.1:5432"
83
+ end
90
84
 
91
- sh 'git', "git init; git add ." unless File.exists?('.git') && File.directory?('.git')
85
+ private
92
86
 
93
- sh 'git', "git commit -a -m 'PostgreSQL Change Management (psql-cm).\nDatabases: #{databases}\nTree: #{tree}'"
94
- end
95
- end # def dump!
96
-
97
- def setup!
98
- # Create psql_cm tables for each schema on the target db.
99
- debug "setup> Setting up pg_psql_cm table in each target schema."
100
- tree.each_pair do |database, schema_hash|
101
- schema_hash.keys.each do |schema|
102
- sql = <<-SQL
103
- SET search_path = #{schema}, public;
104
- CREATE TABLE IF NOT EXISTS #{schema}.pg_psql_cm
105
- (
106
- id bigserial NOT NULL PRIMARY KEY ,
107
- is_base boolean NOT NULL,
108
- created_at timestamp with time zone DEFAULT now(),
109
- implementer text NOT NULL,
110
- content text NOT NULL
111
- );
112
- SQL
113
- debug "setup:#{database}:#{schema}> sql\n#{sql}"
114
- db(database).exec sql
115
- end
87
+ def ensure_database_exists(database)
88
+ begin
89
+ db('postgres').exec("CREATE DATABASE #{database};")
90
+ debug "create> #{database}"
91
+ rescue => error
92
+ raise error unless error.message =~ /already exists/
116
93
  end
117
94
  end
118
95
 
119
- def restore!
120
- unless config.sql_path
121
- $stdout.puts "Warning: --sql-path was not set, defaulting to $PWD/sql."
122
- config.sql_path = "#{ENV["PWD"]}/sql"
123
- end
124
-
125
- debug "restore> sql_path: #{config.sql_path}"
126
- File.directory?(config.sql_path) or
127
- halt! "Cannot restore from a path that does not exist: #{config.sql_path}"
128
-
129
- Dir.chdir(config.sql_path) do
130
-
131
- Dir['*'].each do |database|
132
- next unless File.directory? database
133
-
134
- Dir.chdir(database) do
135
- sh "restore", "createdb #{db(database).psql_args} #{database}"
136
-
137
- debug "restore:#{database}>"
138
- Dir['*'].each do |schema|
139
- next unless File.directory? schema
140
-
141
- base_file = File.join(config.sql_path,database,schema,'base.sql')
142
- cm_file = File.join(config.sql_path,database,schema,'cm.sql')
143
-
144
- debug "restore:#{database}:#{schema}> #{base_file}"
145
- sh 'restore', "psql #{db(database).psql_args} #{database} < #{base_file}"
146
-
147
- next if File.size(cm_file) == 0
148
-
149
- debug "restore:#{database}:#{schema}> #{cm_file}"
150
- sh 'restore', "psql #{db(database).psql_args} #{database} < #{cm_file}"
151
- end
152
- end
153
- end
96
+ def ensure_schema_exists(database,schema)
97
+ begin
98
+ db(database).exec("CREATE SCHEMA #{schema};")
99
+ debug "create> #{database}.#{schema}"
100
+ rescue => error
101
+ raise error unless error.message =~ /already exists/
154
102
  end
155
- end # def restore!
156
-
157
- def change!
158
- puts "TODO: allow change string and/or file to be specified and add to the
159
- specified database scema control table"
160
103
  end
161
104
 
162
- def run!(action = config.action, parent_id = config.parent_id)
163
- case action
164
- when "console"
165
- ::PSQLCM.debug "Starting Console"
166
- require 'psql-cm/cli'
167
- ::PSQLCM::Console.run!
168
- when "dump"
169
- dump!
170
- when "restore"
171
- restore!
172
- when "setup"
173
- setup!
174
- when "change"
175
- change!
176
- else
177
- halt! "Action '#{action}' is not handled."
178
- end
105
+ def ensure_cm_table_exists(database,schema)
106
+ sql = <<-SQL
107
+ SET search_path = #{schema};
108
+ SET client_min_messages = warning;
109
+ CREATE TABLE IF NOT EXISTS #{schema}.#{config.cm_table}
110
+ (
111
+ id bigserial NOT NULL PRIMARY KEY ,
112
+ is_base boolean NOT NULL,
113
+ created_at timestamp with time zone DEFAULT now(),
114
+ implementer text NOT NULL,
115
+ content text NOT NULL
116
+ );
117
+ SQL
118
+ debug "create> #{database}.#{schema}.#{config.cm_table}"
119
+ db(database).exec(sql)
179
120
  end
180
121
 
181
- def sh(tag, command)
182
- debug "sh:#{tag}> #{command}"
183
- %x[#{command}]
122
+ def sql_path
123
+ return config.sql_path unless config.sql_path.to_s.empty?
124
+ $stdout.puts "NOTICE: sql_path is not set, defaulting to #{ENV["PWD"]}/sql"
125
+ config.sql_path = "#{ENV["PWD"]}/sql"
184
126
  end
185
127
 
186
128
  end # class << self
187
129
  end
188
130
 
189
131
  ::PSQLCM.config.debug = !!ENV['DEBUG']
132
+ ::PSQLCM.config.cm_table = 'pg_psql_cm' # Default --cm-table name.
190
133
 
data/lib/psql-cm/cli.rb CHANGED
@@ -6,36 +6,40 @@ module PSQLCM
6
6
  class << self
7
7
  def parse!(arguments)
8
8
  ::OptionParser.new do |options|
9
- options.banner = "Usage: psql-cm [options]"
10
- options.separator ""
11
- options.separator "Specific options:"
9
+ options.banner = 'Usage: psql-cm [options]'
10
+ options.separator ''
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('-s', '--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|
17
+ options.on('-a', '--databases=NAMES', 'A comma separated list of databases to cm.') do |names|
18
18
  ::PSQLCM.config.databases = names.split(',')
19
19
  end
20
20
 
21
- options.on("-u", "--uri URI", "Path to the sink database connection file.") do |uri|
21
+ options.on('-u', '--uri=URI', 'Path to the sink database connection file.') do |uri|
22
22
  ::PSQLCM.config.uri = uri
23
23
  end
24
24
 
25
- options.on("-D", "--[no-]debug", "Output debugging information.") do |debug|
25
+ options.on('-D', '--[no-]debug', 'Output debugging information.') do |debug|
26
26
  ::PSQLCM.config.debug = debug.nil? ? false : true
27
27
  end
28
28
 
29
- options.on("-v", "--[no-]verbose", "Output verbosley.") do |verbose|
29
+ options.on('-v', '--[no-]verbose', 'Output verbosley.') do |verbose|
30
30
  ::PSQLCM.config.verbose = verbose
31
31
  end
32
32
 
33
- options.on_tail("-h", "--help", "Print help and exit.") do
33
+ options.on('-c', '--cm-table=TABLE') do |cm_table|
34
+ ::PSQLCM.config.cm_table = cm_table
35
+ end
36
+
37
+ options.on_tail('-h', '--help', 'Print help and exit.') do
34
38
  puts options
35
39
  exit 0
36
40
  end
37
41
 
38
- options.on_tail("--version", "Print version and exit.") do
42
+ options.on_tail('--version', 'Print version and exit.') do
39
43
  require 'psql-cm/version'
40
44
  puts ::PSQLCM::Version
41
45
  exit 0
@@ -16,7 +16,7 @@ module PSQLCM
16
16
 
17
17
  def db
18
18
  unless @config[:dbname] == 'postgres'
19
- ::PSQLCM.sh 'createdb', "createdb #{psql_args} #{@config[:dbname]}"
19
+ ::PSQLCM.sh "createdb #{psql_args} #{@config[:dbname]}"
20
20
  end
21
21
 
22
22
  @db || connect!
@@ -69,9 +69,12 @@ module PSQLCM
69
69
  @db[name] = Connection.new(:dbname => name)
70
70
  end
71
71
 
72
- # "postgres://{user}:{password}@{host}:{port}/{database}"
73
72
  def configure!
74
- uri = URI.parse(::PSQLCM.config.uri)
73
+ begin
74
+ uri = URI.parse(::PSQLCM.uri)
75
+ rescue => error
76
+ halt! "PostgreSQL URI was incorrectly specified, format is:\n --uri=postgres://{user}:{password}@{host}:{port}/{database}\nwhere user, password, port and database are optional."
77
+ end
75
78
 
76
79
  query = uri.query.to_s.split('&')
77
80
 
@@ -0,0 +1,30 @@
1
+ module PSQLCM
2
+ class << self
3
+ def dump!
4
+ debug "dump> sql_path: #{sql_path}"
5
+ FileUtils.mkdir(sql_path) unless File.directory?(sql_path)
6
+ Dir.chdir(sql_path) do
7
+ debug "tree> #{tree}"
8
+ tree.each_pair do |database, database_schemas|
9
+ debug "dump> database: #{database}"
10
+ FileUtils.mkdir_p(File.join(sql_path,database))
11
+ database_schemas.each do |schema|
12
+ debug "dump> schema: #{schema}"
13
+ FileUtils.mkdir_p(File.join(sql_path,database))
14
+
15
+ cm_file = File.join(sql_path,database,"#{schema}.sql")
16
+
17
+ sh %W[ pg_dump #{db(database).psql_args}
18
+ --no-owner --schema=#{schema} --file=#{cm_file} --table=#{config.cm_table}
19
+ #{database} ].join(' ')
20
+ end
21
+ end
22
+
23
+ sh "git init; git add ." unless File.exists?('.git') && File.directory?('.git')
24
+
25
+ sh "git commit -a -m 'PostgreSQL Change Management (psql-cm).\nDatabases: #{databases.join(', ')}\nTree: #{tree}'"
26
+ end
27
+ end # def dump!
28
+
29
+ end
30
+ end
@@ -0,0 +1,49 @@
1
+ module PSQLCM
2
+ class << self
3
+ def restore!
4
+ File.directory?(sql_path) or
5
+ halt! "Cannot restore from sql-path (#{sql_path}), it does not exist!"
6
+
7
+ Dir.chdir(sql_path) do
8
+
9
+ Dir['*'].each do |database|
10
+ next unless File.directory? database
11
+
12
+ Dir.chdir(database) do
13
+ ensure_database_exists(database)
14
+
15
+ debug "restore> #{database}"
16
+ Dir['*.sql'].each do |cm_file|
17
+ next if File.size(cm_file) == 0
18
+
19
+ schema = cm_file.sub(".sql",'')
20
+ ensure_schema_exists(database,schema)
21
+
22
+ debug "restore> #{database}:#{schema} < #{cm_file}"
23
+ sh "psql #{db(database).psql_args} #{database} < #{cm_file}"
24
+
25
+ ensure_cm_table_exists(database,schema)
26
+ row = db(database).exec("SELECT content from #{schema}.#{config.cm_table}
27
+ WHERE is_base IS true ORDER BY created_at
28
+ DESC LIMIT 1;")
29
+ Tempfile.open('base.sql') do |temp_file|
30
+ temp_file.write(row)
31
+ sh "psql #{db(database).psql_args} #{database} < #{temp_file.path}"
32
+ end
33
+
34
+ sql = "SELECT content from #{schema}.#{config.cm_table} where is_base IS false ORDER BY created_at ASC;"
35
+ db(database).exec(sql).each do |row|
36
+ debug "restoring cm row: #{row}"
37
+ Tempfile.open('base.sql') do |temp_file|
38
+ temp_file.write(row)
39
+ sh "psql #{db(database).psql_args} #{database} < #{temp_file.path}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end # def restore!
47
+
48
+ end
49
+ end
@@ -0,0 +1,27 @@
1
+ module PSQLCM
2
+ class << self
3
+ def setup!
4
+ tree.each_pair do |database, schemas|
5
+ ensure_database_exists(database)
6
+ schemas(database).each do |schema|
7
+ ensure_schema_exists(database,schema)
8
+ ensure_cm_table_exists(database,schema)
9
+
10
+ Tempfile.open('base.sql') do |temp_file|
11
+ sh " pg_dump #{db(database).psql_args} --schema-only --no-owner --schema=#{schema} --file=#{temp_file.path} #{database}"
12
+
13
+ contents = %x{cat #{temp_file.path}}
14
+ implementer = %Q|#{%x[git config user.name].strip} <#{%x[git config user.email].strip}>|
15
+ db(database).exec(
16
+ "INSERT INTO #{schema}.#{config.cm_table} (is_base, implementer, content) VALUES (true, $1, $2);",
17
+ [implementer, contents]
18
+ )
19
+ end
20
+
21
+ end
22
+ end
23
+
24
+ dump!
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ module PSQLCM
2
+ class << self
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"
6
+
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
11
+ end # def submit!
12
+ end
13
+ end
14
+
@@ -1,4 +1,4 @@
1
1
  module PSQLCM
2
- Version = '0.0.5'
2
+ Version = '0.0.6'
3
3
  end
4
4
 
data/lib/psql-cm.rb CHANGED
@@ -3,7 +3,12 @@ require 'fileutils'
3
3
  require 'ostruct'
4
4
  require 'uri'
5
5
  require 'delegate'
6
+ require 'tempfile'
6
7
 
7
8
  require_relative 'psql-cm/base'
8
9
  require_relative 'psql-cm/database'
10
+ require_relative 'psql-cm/setup'
11
+ require_relative 'psql-cm/dump'
12
+ require_relative 'psql-cm/restore'
13
+ require_relative 'psql-cm/submit'
9
14
 
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.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-19 00:00:00.000000000 Z
12
+ date: 2012-04-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pg
@@ -39,6 +39,10 @@ files:
39
39
  - lib/psql-cm/base.rb
40
40
  - lib/psql-cm/cli.rb
41
41
  - lib/psql-cm/database.rb
42
+ - lib/psql-cm/dump.rb
43
+ - lib/psql-cm/restore.rb
44
+ - lib/psql-cm/setup.rb
45
+ - lib/psql-cm/submit.rb
42
46
  - lib/psql-cm/version.rb
43
47
  - lib/psql-cm.rb
44
48
  - LICENCE