Improve config example in dbicdump
[dbsrgits/DBIx-Class-Schema-Loader.git] / script / dbicdump
CommitLineData
ff746964 1#!/usr/bin/perl
2
3=head1 NAME
4
5dbicdump - Dump a schema using DBIx::Class::Schema::Loader
6
7=head1 SYNOPSIS
8
07f39b47 9 dbicdump <configuration_file>
112415f1 10 dbicdump [-I <lib-path>] [-o <loader_option>=<value> ] \
11 <schema_class> <connect_info>
ff746964 12
667f1a0b 13Examples:
14
07f39b47 15 $ dbicdump schema.conf
16
667f1a0b 17 $ dbicdump -o dump_directory=./lib \
18 -o components='["InflateColumn::DateTime"]' \
c4a69b87 19 MyApp::Schema dbi:SQLite:./foo.db
20
21 $ dbicdump -o dump_directory=./lib \
22 -o components='["InflateColumn::DateTime"]' \
667f1a0b 23 MyApp::Schema dbi:SQLite:./foo.db '{ quote_char => "\"" }'
24
112415f1 25 $ dbicdump -Ilib -o dump_directory=./lib \
667f1a0b 26 -o components='["InflateColumn::DateTime"]' \
27 -o preserve_case=1 \
28 MyApp::Schema dbi:mysql:database=foo user pass '{ quote_char => "`" }'
29
eb40e254 30 $ dbicdump -o dump_directory=./lib \
31 -o components='["InflateColumn::DateTime"]' \
32 MyApp::Schema 'dbi:mysql:database=foo;host=domain.tld;port=3306' user pass
33
93acebe1 34On Windows that would be:
35
36 $ dbicdump -o dump_directory=.\lib ^
37 -o components="[q{InflateColumn::DateTime}]" ^
38 -o preserve_case=1 ^
39 MyApp::Schema dbi:mysql:database=foo user pass "{ quote_char => q{`} }"
07f39b47 40
0322c5b3 41Configuration files must have schema_class and connect_info sections,
07f39b47 42an example of a general config file is as follows:
43
44 schema_class MyApp::Schema
112415f1 45
46 lib /extra/perl/libs
07f39b47 47
48 # connection string
49 <connect_info>
50 dsn dbi:mysql:example
51 user root
52 pass secret
53 </connect_info>
54
55 # dbic loader options
56 <loader_options>
e946f659 57 dump_directory ./lib
58 components InflateColumn::DateTime
59 components TimeStamp
07f39b47 60 </loader_options>
93acebe1 61
0322c5b3 62Using a config file requires L<Config::Any> installed.
63
112415f1 64The optional C<lib> key is equivalent to the C<-I> option.
65
ff746964 66=head1 DESCRIPTION
67
68Dbicdump generates a L<DBIx::Class> schema using
69L<DBIx::Class::Schema::Loader/make_schema_at> and dumps it to disk.
70
e83cb149 71You can pass any L<DBIx::Class::Schema::Loader::Base> constructor option using
ff746964 72C<< -o <option>=<value> >>. For convenience, option names will have C<->
73replaced with C<_> and values that look like references or quote-like
74operators will be C<eval>-ed before being passed to the constructor.
75
76The C<dump_directory> option defaults to the current directory if not
77specified.
78
79=head1 SEE ALSO
80
81L<DBIx::Class::Schema::Loader>, L<DBIx::Class>.
82
83=head1 AUTHOR
84
c4a69b87 85Dagfinn Ilmari Manns?ker C<< <ilmari@ilmari.org> >>
ff746964 86
667f1a0b 87=head1 CONTRIBUTORS
88
89Caelum: Rafael Kitover <rkitover@cpan.org>
90
112415f1 91alnewkirk: Al Newkirk <awncorp@cpan.org>
92
ff746964 93=head1 LICENSE
94
95This program is free software; you can redistribute it and/or modify it
96under the same terms as Perl itself.
97
98=cut
99
100use strict;
101use warnings;
102use Getopt::Long;
707fb247 103use Pod::Usage;
0322c5b3 104use DBIx::Class::Schema::Loader 'make_schema_at';
112415f1 105use namespace::clean;
0322c5b3 106use DBIx::Class::Schema::Loader::Base ();
107use DBIx::Class::Schema::Loader::Optional::Dependencies ();
112415f1 108require lib;
ff746964 109
110my $loader_options;
111
112415f1 112Getopt::Long::Configure('gnu_getopt');
113
114GetOptions(
115 'I=s' => sub { shift; lib->import(shift) },
116 'loader-option|o=s%' => \&handle_option,
117);
118
ff746964 119$loader_options->{dump_directory} ||= '.';
120
07f39b47 121if (@ARGV == 1) {
0322c5b3 122 if (not DBIx::Class::Schema::Loader::Optional::Dependencies->req_ok_for('dbicdump_config')) {
123 die sprintf "You must install the following CPAN modules to use a config file with dbicdump: %s.\n",
124 DBIx::Class::Schema::Loader::Optional::Dependencies->req_missing_for('dbicdump_config');
125 }
126
07f39b47 127 my $configuration_file = shift @ARGV;
0322c5b3 128
07f39b47 129 my $configurations =
130 Config::Any->load_files( {
131 use_ext => 1,
132 flatten_to_hash => 1,
133 files => [$configuration_file] } );
134
135 my $c = (values %$configurations)[0];
136
137 unless (keys %{$c->{connect_info}} && $c->{schema_class}) {
138 pod2usage(1);
139 }
112415f1 140
141 my @libs;
142
143 if ($c->{lib}) {
144 if (ref $c->{lib}) {
145 @libs = @{ $c->{lib} };
146 }
147
148 @libs = ($c->{lib});
149 }
150
151 lib->import($_) for @libs;
07f39b47 152
153 my ($dsn, $user, $pass, $options) =
154 map { $c->{connect_info}->{$_} } qw/dsn user pass options/;
155 $options ||= {};
156 $c->{loader_options}->{dump_directory} ||=
157 $loader_options->{dump_directory};
158
159 make_schema_at(
160 $c->{schema_class},
161 $c->{loader_options} || {},
162 [ $dsn, $user, $pass, %{$options} ],
163 );
164}
165else {
166 my ($schema_class, @loader_connect_info) = @ARGV
167 or pod2usage(1);
168
169 my $dsn = shift @loader_connect_info;
170
171 my ($user, $pass) = $dsn =~ /sqlite/i ? ('', '')
172 : splice @loader_connect_info, 0, 2;
173
174 my @extra_connect_info_opts = map parse_value($_), @loader_connect_info;
175
176 make_schema_at(
177 $schema_class,
178 $loader_options,
179 [ $dsn, $user, $pass, @extra_connect_info_opts ],
180 );
181}
667f1a0b 182
183exit 0;
184
185sub parse_value {
186 my $value = shift;
187
188 $value = eval $value if $value =~ /^\s*(?:sub\s*\{|q\w?\s*[^\w\s]|[[{])/;
189
190 return $value;
191}
192
ff746964 193sub handle_option {
194 my ($self, $key, $value) = @_;
195
196 $key =~ tr/-/_/;
197 die "Unknown option: $key\n"
198 unless DBIx::Class::Schema::Loader::Base->can($key);
199
667f1a0b 200 $value = parse_value $value;
ff746964 201
202 $loader_options->{$key} = $value;
203}
204
667f1a0b 2051;
206
207__END__