prick 0.18.0 → 0.20.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +10 -4
- data/README.md +7 -7
- data/Rakefile +3 -1
- data/TODO +13 -11
- data/bin/console +2 -1
- data/doc/build-yml.txt +14 -0
- data/exe/prick +264 -28
- data/lib/builder/batch.rb +147 -0
- data/lib/builder/builder.rb +122 -0
- data/lib/builder/node.rb +189 -0
- data/lib/builder/node_pool.rb +105 -0
- data/lib/builder/parser.rb +120 -0
- data/lib/local/command.rb +193 -0
- data/lib/{prick → local}/git.rb +148 -22
- data/lib/local/timer.rb +98 -0
- data/lib/prick/constants.rb +54 -66
- data/lib/prick/diff.rb +28 -18
- data/lib/prick/prick_version.rb +161 -0
- data/lib/prick/state.rb +80 -165
- data/lib/prick/version.rb +2 -163
- data/lib/prick.rb +43 -27
- data/lib/share/init/.gitignore +10 -0
- data/lib/share/init/.prick-context +2 -0
- data/lib/share/init/.rspec +3 -0
- data/{share/schema/schema/public → lib/share/init/migration}/.keep +0 -0
- data/lib/share/init/prick.yml +6 -0
- data/lib/share/init/schema/.keep +0 -0
- data/lib/share/init/schema/build.yml +2 -0
- data/lib/share/init/schema/prick/.keep +0 -0
- data/lib/share/init/schema/prick/build.yml +5 -0
- data/lib/share/init/schema/prick/data.sql +6 -0
- data/{share/schema → lib/share/init}/schema/prick/tables.sql +2 -3
- data/lib/share/init/schema/public/.keep +0 -0
- data/lib/share/init/spec/prick_helper.rb +1 -0
- data/lib/share/init/spec/prick_spec.rb +6 -0
- data/lib/share/init/spec/spec_helper.rb +50 -0
- data/lib/share/migrate/migration/build.yml +4 -0
- data/lib/share/migrate/migration/diff.after-tables.sql +0 -0
- data/lib/share/migrate/migration/diff.before-tables.sql +0 -0
- data/lib/share/migrate/migration/diff.tables.sql +0 -0
- data/lib/subcommand/prick-build.rb +55 -0
- data/lib/subcommand/prick-create.rb +78 -0
- data/lib/subcommand/prick-drop.rb +25 -0
- data/lib/subcommand/prick-fox.rb +62 -0
- data/lib/subcommand/prick-init.rb +46 -0
- data/lib/subcommand/prick-make.rb +202 -0
- data/lib/subcommand/prick-migrate.rb +37 -0
- data/lib/subcommand/prick-release.rb +23 -0
- data/lib/subcommand/prick-setup.rb +20 -0
- data/lib/subcommand/prick-teardown.rb +18 -0
- data/prick.gemspec +43 -16
- metadata +161 -72
- data/.gitignore +0 -29
- data/.travis.yml +0 -7
- data/doc/create_release.txt +0 -17
- data/doc/flow.txt +0 -98
- data/doc/migra +0 -1
- data/doc/migrations.txt +0 -172
- data/doc/notes.txt +0 -116
- data/doc/prick.txt +0 -114
- data/doc/sh.prick +0 -316
- data/lib/ext/algorithm.rb +0 -14
- data/lib/ext/fileutils.rb +0 -26
- data/lib/ext/forward_method.rb +0 -18
- data/lib/ext/pg.rb +0 -18
- data/lib/ext/shortest_path.rb +0 -44
- data/lib/prick/archive.rb +0 -124
- data/lib/prick/branch.rb +0 -254
- data/lib/prick/builder.rb +0 -205
- data/lib/prick/cache.rb +0 -34
- data/lib/prick/command.rb +0 -102
- data/lib/prick/database.rb +0 -82
- data/lib/prick/dsort.rb +0 -151
- data/lib/prick/ensure.rb +0 -119
- data/lib/prick/exceptions.rb +0 -25
- data/lib/prick/head.rb +0 -183
- data/lib/prick/migration.rb +0 -70
- data/lib/prick/program.rb +0 -506
- data/lib/prick/project.rb +0 -626
- data/lib/prick/rdbms.rb +0 -137
- data/lib/prick/schema.rb +0 -27
- data/lib/prick/share.rb +0 -64
- data/libexec/strip-comments +0 -33
- data/make_releases +0 -72
- data/make_schema +0 -10
- data/share/diff/diff.after-tables.sql +0 -4
- data/share/diff/diff.before-tables.sql +0 -4
- data/share/diff/diff.tables.sql +0 -8
- data/share/features/diff.sql +0 -2
- data/share/features/feature/diff.sql +0 -2
- data/share/features/feature/migrate.sql +0 -2
- data/share/features/features.sql +0 -2
- data/share/features/features.yml +0 -2
- data/share/features/migrations.sql +0 -4
- data/share/gitignore +0 -2
- data/share/migration/diff.tables.sql +0 -8
- data/share/migration/features.yml +0 -6
- data/share/migration/migrate.sql +0 -3
- data/share/migration/migrate.yml +0 -8
- data/share/migration/tables.sql +0 -3
- data/share/schema/build.yml +0 -14
- data/share/schema/schema/build.yml +0 -3
- data/share/schema/schema/prick/build.yml +0 -14
- data/share/schema/schema/prick/data.sql +0 -7
- data/share/schema/schema/prick/schema.sql +0 -3
- data/share/schema/schema/public/build.yml +0 -13
- data/share/schema/schema.sql +0 -3
- data/test_assorted +0 -192
- data/test_feature +0 -112
- data/test_refactor +0 -34
- data/test_single_dev +0 -83
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2e1267bf396eabebb1624b55e9e56c187aa687cd8946a5b40a2ab131a1325ab
|
4
|
+
data.tar.gz: 574a439204413e074b1a21e4458d097e44d6f4a9cacb225942dea0bd9e6c2150
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf5bef7facd1ea27f82ec70b458db18ed09025b21482ba3271f209387e2b4ff656ece67679748f98a9c86dd2633f8e66a94dbbcb28917595781ccd6a5ff1b700
|
7
|
+
data.tar.gz: 437a136ec48f2e952a76b723529e121a13bebde0879fa4743c1f776680b5fcf5d12d12d09e516e062642089efbe3ddadcc5f9cf36de4aa05969a004f13f6f8b5
|
data/Gemfile
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source "https://rubygems.org"
|
4
4
|
|
5
|
-
# Specify your gem's dependencies in
|
5
|
+
# Specify your gem's dependencies in prick_build.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "rake", "~>
|
8
|
+
gem "rake", "~> 13.0"
|
9
9
|
gem "rspec", "~> 3.0"
|
10
|
+
|
11
|
+
gem 'shellopts', :github => 'clrgit/shellopts', branch: "master"
|
12
|
+
gem 'pg_graph', :github => 'clrgit/pg_graph', branch: "master"
|
13
|
+
gem 'pg_meta', :github => 'clrgit/pg_meta', branch: "master"
|
14
|
+
gem 'pg_conn', :github => 'clrgit/pg_conn', branch: "master"
|
15
|
+
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# PrickBuild
|
2
2
|
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/prick_build`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
4
|
|
5
5
|
TODO: Delete this and the text above, and describe your gem
|
6
6
|
|
@@ -9,16 +9,16 @@ TODO: Delete this and the text above, and describe your gem
|
|
9
9
|
Add this line to your application's Gemfile:
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
gem '
|
12
|
+
gem 'prick_build'
|
13
13
|
```
|
14
14
|
|
15
15
|
And then execute:
|
16
16
|
|
17
|
-
$ bundle
|
17
|
+
$ bundle install
|
18
18
|
|
19
19
|
Or install it yourself as:
|
20
20
|
|
21
|
-
$ gem install
|
21
|
+
$ gem install prick_build
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
@@ -28,8 +28,8 @@ TODO: Write usage instructions here
|
|
28
28
|
|
29
29
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
30
|
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
32
|
|
33
33
|
## Contributing
|
34
34
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/prick_build.
|
data/Rakefile
CHANGED
data/TODO
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
|
2
|
-
o
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
o
|
8
|
-
|
9
|
-
o
|
10
|
-
|
11
|
-
|
12
|
-
|
2
|
+
o Store fox.state, reflections, and reflections in the database so third-party
|
3
|
+
programs can use them when testing
|
4
|
+
o 'prick make <resource>' should build everything up the resource, then commit
|
5
|
+
before trying to build the resource upon the database. Then it is easy to
|
6
|
+
re-run the failed (sql-)script in psql to see why it failed
|
7
|
+
o 'prick make' should build everything up a touched file, then commit before
|
8
|
+
proceeding
|
9
|
+
o Build functions after schema so that there are no order dependencies on
|
10
|
+
functions. Problem is to detect function files
|
11
|
+
o Build views after schema so that there are no order dependencies on
|
12
|
+
views. Problem is to detect view files
|
13
13
|
|
14
|
+
+ prick release major|minor|patch
|
15
|
+
+ Check modification time of build.yml files too
|
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require "bundler/setup"
|
4
|
-
require "
|
5
|
+
require "prick_build"
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
data/doc/build-yml.txt
ADDED
data/exe/prick
CHANGED
@@ -1,38 +1,250 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require 'prick/program.rb'
|
3
|
+
#$LOAD_PATH.unshift "/home/clr/prj/shellopts/lib"
|
5
4
|
|
6
|
-
require '
|
5
|
+
require 'bootsnap'
|
6
|
+
begin
|
7
|
+
cache_dir = "/run/user/" + `id -u`.chomp
|
8
|
+
Bootsnap.setup(
|
9
|
+
cache_dir: cache_dir, # Path to your cache
|
10
|
+
development_mode: true, # Current working environment, e.g. RACK_ENV, RAILS_ENV, etc
|
11
|
+
load_path_cache: true, # Optimize the LOAD_PATH with a cache
|
12
|
+
compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
|
13
|
+
compile_cache_yaml: true # Compile YAML into a cache
|
14
|
+
)
|
15
|
+
Bootsnap.instrumentation = ->(event, path) { puts "#{event} #{path}" }
|
16
|
+
end
|
7
17
|
|
8
|
-
require '
|
18
|
+
require 'prick.rb'
|
19
|
+
require 'shellopts'
|
9
20
|
|
10
21
|
include ShellOpts
|
11
22
|
include Prick
|
12
23
|
|
13
|
-
|
14
|
-
-n,name=NAME
|
15
|
-
Name of project. Defauls to the environment variable `PRICK_PROJECT` if
|
16
|
-
set and else the name of the current directory
|
17
|
-
|
18
|
-
-C,directory=DIR
|
19
|
-
Change to directory DIR before doing anything else
|
24
|
+
TIME = false
|
20
25
|
|
21
|
-
|
22
|
-
|
26
|
+
SPEC = %(
|
27
|
+
@ Prick project command
|
23
28
|
|
24
29
|
+v,verbose
|
25
|
-
Be verbose. Repeated
|
30
|
+
Be verbose. Repeated -v options increase the verbosity level
|
26
31
|
|
27
32
|
-q,quiet
|
28
33
|
Be quiet
|
29
34
|
|
30
|
-
|
31
|
-
|
35
|
+
-C,directory=EDIR
|
36
|
+
Change to directory DIR before doing anything else
|
37
|
+
|
38
|
+
-d,database=DATABASE
|
39
|
+
Override database name from prick.yml
|
40
|
+
|
41
|
+
-U,username=USERNAME
|
42
|
+
Override username from from prick.yml
|
43
|
+
|
44
|
+
version!
|
45
|
+
Print project version
|
46
|
+
|
47
|
+
init! -n,name=NAME -t,title=TITLE [DIRECTORY]
|
48
|
+
Initializes a prick project
|
49
|
+
|
50
|
+
setup!
|
51
|
+
Create the database user (if necessary) and an empty database
|
52
|
+
|
53
|
+
teardown!
|
54
|
+
Drop the database and the database user. TODO: Also run teardown scripts
|
55
|
+
|
56
|
+
create.data!
|
57
|
+
create.schema!
|
58
|
+
create.database!
|
59
|
+
create.users!
|
60
|
+
create.all!
|
61
|
+
Create an object. Fails if migration exist unless the --force flag is given
|
62
|
+
|
63
|
+
create.migration! -f,force -o,file=FILE -- VERSION
|
64
|
+
Create a migration from VERSION to the current and write it to
|
65
|
+
migration/VERSION. Fails if migration exist unless the --force flag is
|
66
|
+
given. If --file is given, the migration is written to FILE instead of
|
67
|
+
the migration directory. This doesn't require you to be on a release
|
68
|
+
branch and can be used to create ad-hoc migration scripts
|
69
|
+
|
70
|
+
drop! -- [KIND]
|
71
|
+
@ Drop objects
|
72
|
+
|
73
|
+
Kind can be 'users', 'data', 'schema', 'database' (the default), or 'all'. It is
|
74
|
+
not an error if the object doesn't exist. TODO Only 'users' is currently defined
|
75
|
+
|
76
|
+
build! -t,time --dump=KIND? -- [SCHEMA]
|
77
|
+
Build the project. If SCHEMA is defined, later schemas are excluded.
|
78
|
+
KIND can be 'nodes', 'allnodes' or 'batches' (the default)
|
79
|
+
|
80
|
+
make! -t,time --dump=KIND? -- [SCHEMA]
|
81
|
+
@ Only rebuild changed files
|
82
|
+
|
83
|
+
Checks file timestamps against the time of the last build and only
|
84
|
+
rebuild affected parts of the project. KIND can be 'nodes', 'allnodes' or
|
85
|
+
'batches' (the default)
|
86
|
+
|
87
|
+
fox! -- FILE...
|
88
|
+
Load fox file data. Data are reset to their initial state after build
|
89
|
+
before the fox data are loaded
|
90
|
+
|
91
|
+
release! -- KIND
|
92
|
+
Create a release of the given kind. KIND can be 'major', 'minor', or
|
93
|
+
'patch'. Release checks that the current repo is clean and up to date
|
94
|
+
with the origin
|
95
|
+
|
96
|
+
migrate! -f,file=FILE
|
97
|
+
Execute a migration
|
98
|
+
|
99
|
+
dump.type!
|
100
|
+
dump.data!
|
101
|
+
dump.schema!
|
102
|
+
dump.database!
|
103
|
+
TODO
|
104
|
+
|
105
|
+
dump.migration! --force -- VERSION
|
106
|
+
)
|
107
|
+
|
108
|
+
opts, args = ShellOpts.process(SPEC, ARGV, exception: true)
|
109
|
+
|
110
|
+
begin
|
111
|
+
# Handle verbose and quiet
|
112
|
+
$verbose = opts.verbose
|
113
|
+
$quiet = opts.quiet?
|
114
|
+
|
115
|
+
# Honor -C option
|
116
|
+
if opts.directory?
|
117
|
+
if File.exist?(opts.directory)
|
118
|
+
begin
|
119
|
+
Dir.chdir(opts.directory)
|
120
|
+
rescue Errno::ENOENT
|
121
|
+
raise Prick::Error, "Can't cd to '#{opts.directory}'"
|
122
|
+
end
|
123
|
+
else
|
124
|
+
raise Prick::Error, "Can't find directory: #{opts.directory}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Get subcommand
|
129
|
+
cmd = opts.subcommand!
|
130
|
+
|
131
|
+
# Process init command
|
132
|
+
if opts.subcommand == :init
|
133
|
+
dir, state = Prick::SubCommand.init(args.expect(0..1), cmd.name, cmd.title, opts.database, opts.username)
|
134
|
+
puts "Initialized prick project '#{state.name}' in #{dir}"
|
135
|
+
if opts.database.nil? || opts.username.nil?
|
136
|
+
puts
|
137
|
+
puts "Please check database/username in #{PRICK_CONTEXT_FILE}"
|
138
|
+
end
|
139
|
+
exit
|
140
|
+
end
|
141
|
+
|
142
|
+
# Check state
|
143
|
+
File.exist?(PRICK_PROJECT_FILE) or raise Prick::Error, "Not in a prick project directory"
|
144
|
+
|
145
|
+
# Load state
|
146
|
+
Prick.state = State.load
|
147
|
+
|
148
|
+
# Handle -d and -U options
|
149
|
+
database = opts.database || Prick.state.database
|
150
|
+
username = opts.username || Prick.state.username
|
151
|
+
|
152
|
+
# Expect a sub-command
|
153
|
+
cmd = opts.subcommand! or raise Prick::Error, "Subcomand expected"
|
154
|
+
|
155
|
+
# Process subcommands
|
156
|
+
case opts.subcommand
|
157
|
+
when :version!
|
158
|
+
puts "#{Prick.state.name}-#{Prick.state.version}"
|
159
|
+
|
160
|
+
when :setup!
|
161
|
+
Prick::SubCommand.setup(database, username)
|
162
|
+
|
163
|
+
when :teardown!
|
164
|
+
Prick::SubCommand.teardown(database, username)
|
165
|
+
|
166
|
+
when :create!
|
167
|
+
create_command = opts.create!
|
168
|
+
case create_command.subcommand
|
169
|
+
when :migration
|
170
|
+
arg = args.expect(1)
|
171
|
+
version = PrickVersion.try(arg) or raise Prick::Error, "Illegal version: #{arg}"
|
172
|
+
Prick::SubCommand.create_migration(
|
173
|
+
username, version,
|
174
|
+
force: create_command.subcommand!.force?,
|
175
|
+
file: create_command.subcommand!.file)
|
176
|
+
else
|
177
|
+
raise NotImplementedError
|
178
|
+
end
|
179
|
+
|
180
|
+
when :build!
|
181
|
+
dump = cmd.dump? ? cmd.dump("batches").to_sym : nil
|
182
|
+
Prick::SubCommand.build(database, username, args.expect(0..1), timer: cmd.time?, dump: dump)
|
183
|
+
|
184
|
+
when :make!
|
185
|
+
dump = cmd.dump? ? cmd.dump("batches").to_sym : nil
|
186
|
+
Prick::SubCommand.make(database, username, args.expect(0..1), timer: cmd.time?, dump: dump)
|
187
|
+
|
188
|
+
when :fox!
|
189
|
+
Prick::SubCommand.fox(database, username, args)
|
190
|
+
|
191
|
+
when :drop!
|
192
|
+
case subject = args.expect(1).to_sym
|
193
|
+
when :all
|
194
|
+
Prick::SubCommand.drop_all(database)
|
195
|
+
when :users
|
196
|
+
Prick::SubCommand.drop_users(database)
|
197
|
+
when :database
|
198
|
+
Prick::SubCommand.drop_database(database)
|
199
|
+
when :data, :schema, :database, :all
|
200
|
+
raise NotImplementedError
|
201
|
+
else
|
202
|
+
raise Prick::Error, "Unknown subject: #{subject}"
|
203
|
+
end
|
204
|
+
|
205
|
+
when :release!
|
206
|
+
kind = args.expect(1).to_sym
|
207
|
+
constrain? kind, :major, :minor, :patch or
|
208
|
+
raise Prick::Fail, "Expected 'major', 'minor', or 'patch' argument, got '#{kind}'"
|
209
|
+
Prick::SubCommand.release(kind)
|
210
|
+
|
211
|
+
when :migrate!
|
212
|
+
args.expect(0)
|
213
|
+
Prick::SubCommand.migrate(database, username, file: cmd.file)
|
214
|
+
|
215
|
+
when :dump!
|
216
|
+
subject = cmd.subcommand!
|
217
|
+
case cmd.subcommand
|
218
|
+
when :migration
|
219
|
+
arg = args.expect(1)
|
220
|
+
version = PrickVersion.try(arg) or raise "Illegal version number: #{arg}"
|
221
|
+
Prick::SubCommand.create_migration(username, version, force: subject.force?, file: "/dev/stdout")
|
222
|
+
when :data, :schema, :database
|
223
|
+
raise NotImplementedError
|
224
|
+
else
|
225
|
+
raise Prick::Error, "Unknown subject: #{subject.inspect}"
|
226
|
+
end
|
227
|
+
|
228
|
+
else
|
229
|
+
raise Prick::Fail, "Internal error: Unhandled command - #{opts.subcommand.inspect}"
|
230
|
+
end
|
231
|
+
|
232
|
+
rescue ShellOpts::Failure, Prick::Fail, Prick::Build::PostgresError => ex
|
233
|
+
ShellOpts.failure(ex.message)
|
234
|
+
|
235
|
+
rescue ShellOpts::Error, Prick::Error => ex
|
236
|
+
ShellOpts.error(ex.message)
|
237
|
+
end
|
238
|
+
|
239
|
+
__END__
|
240
|
+
|
241
|
+
-n,name=NAME
|
242
|
+
Name of project. Defauls to the environment variable `PRICK_PROJECT` if
|
243
|
+
set and else the name of the current directory
|
32
244
|
|
33
|
-
init! -u,user=USER [
|
34
|
-
Initialize a project in the given directory.
|
35
|
-
|
245
|
+
init! -u,user=USER [NAME]
|
246
|
+
Initialize a project in the given directory. The USER is the postgres
|
247
|
+
user and defaults to the project name
|
36
248
|
|
37
249
|
info!
|
38
250
|
Print project information
|
@@ -51,11 +263,13 @@ SPEC = %(
|
|
51
263
|
list.cache!
|
52
264
|
List cache files
|
53
265
|
|
54
|
-
build! -d,database=DATABASE -C,no-cache [TAG]
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
option overrides the
|
266
|
+
build! -d,database=DATABASE -s,state=FILE -C,no-cache [TAG]
|
267
|
+
Drop all users associated with the database before building the current
|
268
|
+
database from the content in the schemas/ directory. With a tag the
|
269
|
+
version is built into the associated versioned database and the result is
|
270
|
+
saved to cache unless the -C option is given. The -d option overrides the
|
271
|
+
default database and the -s option overrides the default state file
|
272
|
+
(fox.state)
|
59
273
|
|
60
274
|
make! -d,database=DATABASE -C,no-cache [TAG]
|
61
275
|
Build the current database from the content in the schemas/ directory.
|
@@ -77,8 +291,12 @@ SPEC = %(
|
|
77
291
|
given file
|
78
292
|
|
79
293
|
drop! -a,all [DATABASE]
|
80
|
-
Drop the given database or all versioned databases.
|
81
|
-
|
294
|
+
Drop the given database or all versioned databases. Users with a username
|
295
|
+
on the form <database>__<username> are also dropped. The --all option
|
296
|
+
also drops the project database
|
297
|
+
|
298
|
+
drop.users! [DATABASE]
|
299
|
+
Drop users with a username on the form <database>__<username>
|
82
300
|
|
83
301
|
diff! -m,mark -t,tables -T,notables
|
84
302
|
diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
|
@@ -153,8 +371,15 @@ SPEC = %(
|
|
153
371
|
in the var/spool directory
|
154
372
|
)
|
155
373
|
|
374
|
+
__END__
|
375
|
+
|
376
|
+
|
377
|
+
|
156
378
|
|
157
379
|
|
380
|
+
|
381
|
+
DEFAULT_STATE_FILE = "fox.state"
|
382
|
+
|
158
383
|
opts, args = ShellOpts.process(SPEC, ARGV)
|
159
384
|
|
160
385
|
# Handle --help
|
@@ -185,6 +410,7 @@ begin
|
|
185
410
|
|
186
411
|
# Create program object
|
187
412
|
program = Program.new(quiet: opts.quiet?, verbose: opts.verbose?)
|
413
|
+
$verbose = opts.verbose? ? opts.verbose : nil
|
188
414
|
|
189
415
|
# Handle init command
|
190
416
|
if opts.subcommand == :init
|
@@ -236,7 +462,9 @@ begin
|
|
236
462
|
|
237
463
|
when :build
|
238
464
|
version = args.expect(0..1)
|
239
|
-
|
465
|
+
state_file = File.expand_path(opts.build!.state || DEFAULT_STATE_FILE)
|
466
|
+
FileUtils.rm_f(state_file)
|
467
|
+
program.build(opts.build!.database, version, state_file, opts.build!.no_cache?)
|
240
468
|
|
241
469
|
when :make
|
242
470
|
command = opts.make!
|
@@ -258,7 +486,15 @@ begin
|
|
258
486
|
program.save(version, file)
|
259
487
|
|
260
488
|
when :drop
|
261
|
-
|
489
|
+
command = opts.drop!
|
490
|
+
case command.subcommand
|
491
|
+
when :users
|
492
|
+
database = args.extract(0..1) || program.project.database.name
|
493
|
+
args.expect(0)
|
494
|
+
program.drop_users(database)
|
495
|
+
else
|
496
|
+
program.drop(args.expect(0..1), opts.drop!.all?)
|
497
|
+
end
|
262
498
|
|
263
499
|
when :diff
|
264
500
|
mark = opts.diff!.mark
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Prick
|
2
|
+
module Build
|
3
|
+
class BuildBatch
|
4
|
+
include Timer
|
5
|
+
|
6
|
+
attr_reader :builder
|
7
|
+
forward_to :builder, :conn
|
8
|
+
|
9
|
+
def kind() @nodes.first&.kind end
|
10
|
+
attr_reader :nodes
|
11
|
+
|
12
|
+
def initialize(builder)
|
13
|
+
@builder = builder
|
14
|
+
@nodes = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute(&block)
|
18
|
+
name = self.class.to_s.sub(/.*::/, "").split(/(?=[A-Z])/).map(&:downcase).join(" ")
|
19
|
+
time "Execute #{name} (nodes: #{nodes.size})" do
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def dump
|
25
|
+
puts kind.upcase
|
26
|
+
indent { nodes.each(&:dump) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class SqlBatch < BuildBatch
|
31
|
+
def execute
|
32
|
+
super {
|
33
|
+
begin
|
34
|
+
sql = []
|
35
|
+
if nodes.first.is_a?(ExeNode)
|
36
|
+
time "Execute script" do
|
37
|
+
sql = [nodes.first.source]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
conn.execute sql + nodes[sql.size..-1].map(&:source)
|
41
|
+
|
42
|
+
rescue PG::SyntaxError, PG::Error => ex
|
43
|
+
error, line, pos = parse_pg_message(ex.message)
|
44
|
+
if line
|
45
|
+
if line < nodes.first.lines
|
46
|
+
node = nodes.first;
|
47
|
+
else
|
48
|
+
line -= nodes.first.lines
|
49
|
+
node = nodes[1..-1].find { |node|
|
50
|
+
line -= 1
|
51
|
+
if line < node.lines
|
52
|
+
line -= 2
|
53
|
+
true
|
54
|
+
else
|
55
|
+
line -= node.lines
|
56
|
+
false
|
57
|
+
end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
if node.is_a?(SqlNode)
|
62
|
+
message = ["prick: #{error} in #{node.path}", line, pos].compact.join(":")
|
63
|
+
else
|
64
|
+
message = "prick: #{error} from #{node.path}"
|
65
|
+
end
|
66
|
+
else
|
67
|
+
raise
|
68
|
+
end
|
69
|
+
raise PostgresError.new(message)
|
70
|
+
end
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
# Returns [error, line, pos] tuple
|
76
|
+
def parse_pg_message(message)
|
77
|
+
message =~ /ERROR:\s*(.*?)\n(LINE (\d+): ).*?\n(\s*\^)/m or return nil
|
78
|
+
[$1, $3.to_i, $4.size - $2.size]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class ModuleBatch < BuildBatch
|
83
|
+
def execute
|
84
|
+
super {
|
85
|
+
nodes.each { |node|
|
86
|
+
sql = node&.call
|
87
|
+
conn.execute sql if sql
|
88
|
+
}
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class FoxBatch < BuildBatch
|
94
|
+
# Inlining Fox instead of using command line program as it saves some deciseconds
|
95
|
+
def execute
|
96
|
+
t_type = t_fox = t_exe = nil
|
97
|
+
|
98
|
+
super {
|
99
|
+
timer = Timer.new "Execute fox batch (nodes: #{nodes.size}, clean: #{builder.clean})"
|
100
|
+
t_type = Timer.new " Load data model"
|
101
|
+
|
102
|
+
files = nodes.map(&:path)
|
103
|
+
|
104
|
+
# Load meta object
|
105
|
+
meta = PgMeta.new(conn)
|
106
|
+
|
107
|
+
# Create type object
|
108
|
+
type = PgGraph::Type.new(meta, builder.reflections_file)
|
109
|
+
|
110
|
+
t_type.stop
|
111
|
+
t_fox = Timer.new " Parse files"
|
112
|
+
|
113
|
+
# Create fox object
|
114
|
+
fox = FixtureFox::Fox.new(type)
|
115
|
+
|
116
|
+
# Parse files
|
117
|
+
for file in files
|
118
|
+
source, lines = fox.tokenize(file)
|
119
|
+
fox.parse(source, lines)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Analyze
|
123
|
+
fox.assign_types
|
124
|
+
fox.generate
|
125
|
+
|
126
|
+
# Dump state file
|
127
|
+
fox.write_state(FOX_STATE_PATH)
|
128
|
+
|
129
|
+
t_fox.stop
|
130
|
+
t_exe = Timer.new " Execute SQL"
|
131
|
+
|
132
|
+
delete = builder.clean ? :none : :touched
|
133
|
+
begin
|
134
|
+
conn.execute fox.to_sql(format: :exec, delete: delete)
|
135
|
+
conn.execute "update prick.versions set built_at = now() at time zone 'UTC'"
|
136
|
+
rescue PG::SyntaxError, PG::Error => ex
|
137
|
+
raise PostgresError, "prick: #{error} from #{node.path}"
|
138
|
+
end
|
139
|
+
}
|
140
|
+
t_type.emit
|
141
|
+
t_fox.emit
|
142
|
+
t_exe.emit
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|