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