Commit | Line | Data |
f54428ab |
1 | #!/usr/bin/env perl |
a705b175 |
2 | |
a94aa524 |
3 | use strict; |
4 | use warnings; |
5 | |
a4a02f15 |
6 | BEGIN { |
c9a26f74 |
7 | require DBIx::Class::Optional::Dependencies; |
8 | if (my $missing = DBIx::Class::Optional::Dependencies->req_missing_for ('admin_script') ) { |
9 | die "The following modules are required for the dbicadmin utility: $missing\n"; |
10 | } |
a4a02f15 |
11 | } |
12 | |
e5279977 |
13 | use DBIx::Class::Admin::Descriptive; |
14 | #use Getopt::Long::Descriptive; |
fd27648a |
15 | use DBIx::Class::Admin; |
16 | |
e5279977 |
17 | my $short_description = "utility for administrating DBIx::Class schemata"; |
82b08554 |
18 | my $synopsis_text =q| |
e5279977 |
19 | deploy a schema to a database |
20 | %c --schema=MyApp::Schema \ |
21 | --connect='["dbi:SQLite:my.db", "", ""]' \ |
22 | --deploy |
23 | |
24 | update an existing record |
25 | %c --schema=MyApp::Schema --class=Employee \ |
26 | --connect='["dbi:SQLite:my.db", "", ""]' \ |
27 | --op=update --set='{ "name": "New_Employee" }' |
82b08554 |
28 | |; |
e5279977 |
29 | |
fd27648a |
30 | my ($opts, $usage) = describe_options( |
e5279977 |
31 | "%c: %o", |
a705b175 |
32 | ( |
33 | ['Actions'], |
34 | ["action" => hidden => { one_of => [ |
50936381 |
35 | ['create' => 'Create version diffs needs preversion'], |
7e1ca6dd |
36 | ['upgrade' => 'Upgrade the database to the current schema'], |
50936381 |
37 | ['install' => 'Install the schema version tables to an existing database'], |
38 | ['deploy' => 'Deploy the schema to the database'], |
39 | ['select' => 'Select data from the schema'], |
40 | ['insert' => 'Insert data into the schema'], |
41 | ['update' => 'Update data in the schema'], |
42 | ['delete' => 'Delete data from the schema'], |
4a0eed52 |
43 | ['op:s' => 'compatibility option all of the above can be supplied as --op=<action>'], |
19a59b9e |
44 | ['help' => 'display this help', { implies => { schema_class => '__dummy__' } } ], |
e2633789 |
45 | ['documentation-as-pod:s' => 'hidden', { implies => { schema_class => '__dummy__' } } ], |
7b71391b |
46 | ], required => 1 }], |
d26b9726 |
47 | ['Arguments'], |
7b71391b |
48 | ["configuration" => hidden => { one_of => [ |
49 | ['config-file|config:s' => 'Supply the config file for parsing by Config::Any', { depends => 'config_stanza'} ], |
50 | ['connect-info:s%' => 'Supply the connect info as trailing options e.g. --connect-info dsn=<dsn> user=<user> password=<pass>' ], |
51 | ['connect:s' => 'Supply the connect info as a JSON-encoded structure, e.g. an --connect=["dsn","user","pass"]'], |
50936381 |
52 | ] }], |
19a59b9e |
53 | ['schema-class:s' => 'The class of the schema to load', { required => 1 } ], |
19a59b9e |
54 | ['config-stanza:s' => 'Where in the config to find the connection_info, supply in form MyApp::Model::DB',], |
7b71391b |
55 | ['resultset|resultset-class|class:s' => 'The resultset to operate on for data manipulation' ], |
19a59b9e |
56 | ['sql-dir:s' => 'The directory where sql diffs will be created'], |
57 | ['sql-type:s' => 'The RDBMs flavour you wish to use'], |
58 | ['version:i' => 'Supply a version install'], |
59 | ['preversion:s' => 'The previous version to diff against',], |
a705b175 |
60 | ['set:s' => 'JSON data used to perform data operations' ], |
a705b175 |
61 | ['attrs:s' => 'JSON string to be used for the second argument for search'], |
62 | ['where:s' => 'JSON string to be used for the where clause of search'], |
63 | ['force' => 'Be forceful with some operations'], |
64 | ['trace' => 'Turn on DBIx::Class trace output'], |
a705b175 |
65 | ['quiet' => 'Be less verbose'], |
099f10d1 |
66 | ['I:s@' => 'Same as perl\'s -I, prepended to current @INC'], |
a705b175 |
67 | ) |
2bbc85c9 |
68 | ); |
a94aa524 |
69 | |
e2633789 |
70 | if(defined (my $fn = $opts->{documentation_as_pod}) ) { |
71 | $usage->synopsis($synopsis_text); |
72 | $usage->short_description($short_description); |
73 | |
e48635f7 |
74 | my $fh; |
e2633789 |
75 | if ($fn) { |
e48635f7 |
76 | require DBIx::Class::_Util; |
77 | DBIx::Class::_Util::mkdir_p( DBIx::Class::_Util::parent_dir( $fn ) ); |
78 | open( $fh, '>', $fn ) or die "Unable to open $fn: $!\n"; |
79 | } |
80 | else { |
81 | $fh = \*STDOUT; |
e2633789 |
82 | } |
83 | |
e48635f7 |
84 | print $fh "\n"; |
85 | print $fh $usage->pod; |
86 | print $fh "\n"; |
e2633789 |
87 | |
e48635f7 |
88 | close $fh if $fn; |
e2633789 |
89 | exit 0; |
e5279977 |
90 | } |
91 | |
6875b150 |
92 | # FIXME - lowercasing will eventually go away when Getopt::Long::Descriptive is fixed |
4e2873b1 |
93 | if($opts->{i}) { |
1c4391f3 |
94 | require lib; |
95 | lib->import( @{delete $opts->{i}} ); |
b13aab4f |
96 | } |
97 | |
e5279977 |
98 | if($opts->{help}) { |
1c4391f3 |
99 | $usage->die(); |
e5279977 |
100 | } |
101 | |
4a0eed52 |
102 | # option compatibility mangle |
7b71391b |
103 | # (can not be joined in the spec, one is s% the other is s) |
fd27648a |
104 | if($opts->{connect}) { |
a705b175 |
105 | $opts->{connect_info} = delete $opts->{connect}; |
b04e5d3e |
106 | } |
7b71391b |
107 | |
fd27648a |
108 | my $admin = DBIx::Class::Admin->new( %$opts ); |
109 | |
fd27648a |
110 | my $action = $opts->{action}; |
c57f1cf7 |
111 | |
112 | $action = $opts->{op} if ($action eq 'op'); |
fd27648a |
113 | |
b13aab4f |
114 | print "Performing action $action...\n"; |
ad81fe7d |
115 | |
116 | my $res = $admin->$action(); |
fd27648a |
117 | if ($action eq 'select') { |
118 | |
a705b175 |
119 | my $format = $opts->{format} || 'tsv'; |
120 | die('Invalid format') if ($format!~/^tsv|csv$/s); |
a705b175 |
121 | |
ad81fe7d |
122 | require Text::CSV; |
123 | |
124 | my $csv = Text::CSV->new({ |
125 | sep_char => ( $format eq 'tsv' ? "\t" : ',' ), |
126 | }); |
127 | |
a705b175 |
128 | foreach my $row (@$res) { |
129 | $csv->combine( @$row ); |
130 | print $csv->string()."\n"; |
131 | } |
a94aa524 |
132 | } |
e5279977 |
133 | |
e2633789 |
134 | 1; |
e5279977 |
135 | |
7d6f6a6e |
136 | __END__ |