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