3 |
rodolico |
1 |
#! /usr/bin/env perl
|
2 |
rodolico |
2 |
|
3 |
rodolico |
3 |
# sql2admin_hash.pl
|
|
|
4 |
#
|
|
|
5 |
# Converts a standard MySQL dump file to a PHP file ready to be used by
|
|
|
6 |
# DBDatabase.class.php
|
2 |
rodolico |
7 |
# NOTE: don't use comma's or parentheses in your comments
|
3 |
rodolico |
8 |
#
|
|
|
9 |
# v1.1 RWR 20170728
|
|
|
10 |
# modified to use env and strict/warnings.
|
2 |
rodolico |
11 |
|
3 |
rodolico |
12 |
use strict;
|
|
|
13 |
use warnings;
|
2 |
rodolico |
14 |
|
3 |
rodolico |
15 |
|
2 |
rodolico |
16 |
#use Data::Dumper;
|
3 |
rodolico |
17 |
my $version = '1.1';
|
2 |
rodolico |
18 |
my $secondary = 0;
|
|
|
19 |
my $indentationChar = ' ';
|
|
|
20 |
my $inputFileName = '';
|
3 |
rodolico |
21 |
my $localOverrideFile = 'DatabaseDefinition.local.php';
|
2 |
rodolico |
22 |
|
3 |
rodolico |
23 |
# converts a field or table name to a display value by separating
|
|
|
24 |
# words, based on underscores, then doing a camel case on each
|
|
|
25 |
# word.
|
2 |
rodolico |
26 |
sub camelCase {
|
|
|
27 |
my $name = shift;
|
3 |
rodolico |
28 |
$name =~ s/_/ /gi; # convert underscore to spaces
|
|
|
29 |
$name =~ s/^ //gi; # remove leading spaces
|
|
|
30 |
$name =~ s{ \b(\w+) }{\u\L$1}gx; # Each "word" capitalized
|
2 |
rodolico |
31 |
return $name;
|
|
|
32 |
}
|
|
|
33 |
|
|
|
34 |
sub getFieldInfo {
|
|
|
35 |
my $fieldName = shift;
|
|
|
36 |
my $fieldInfo = shift;
|
|
|
37 |
# $original = $fieldInfo;
|
|
|
38 |
my $primary_key = shift;
|
|
|
39 |
my @keys;
|
|
|
40 |
my @output;
|
3 |
rodolico |
41 |
|
|
|
42 |
my $default;
|
|
|
43 |
my $type;
|
|
|
44 |
my $size;
|
|
|
45 |
|
2 |
rodolico |
46 |
push @output, "'display name' => '" . &camelCase($fieldName) . "'";
|
|
|
47 |
# For a lookup table, we will just build it
|
|
|
48 |
if ( $fieldInfo =~ m/references\s+([a-z0-9-_]+)\s*\(\s*([a-z0-9-_]+)\s*\)/i ) { # create a lookup
|
|
|
49 |
push @output, "'type' => 'lookup'";
|
|
|
50 |
push @output, "'table' => '$1'";
|
|
|
51 |
push @output, "'keyfield' => '$2'";
|
|
|
52 |
push @output, "'display_field' => 'name'";
|
|
|
53 |
$fieldInfo =~ s/references\s+([a-z0-9-_]+)\s*\(\s*([a-z0-9-_]+)\s*\)//i
|
|
|
54 |
} else {
|
|
|
55 |
push @output, "'keyfield' => true" if ( $primary_key);
|
|
|
56 |
if ( $fieldInfo =~ m/unique/ ) { # this field must be unique
|
|
|
57 |
push @output, "'unique' => true";
|
|
|
58 |
push @keys, $fieldName;
|
|
|
59 |
$fieldInfo =~ s/unique//;
|
|
|
60 |
}
|
|
|
61 |
if ($fieldInfo =~ m/comment *\'([^']+)\'/i ) {
|
|
|
62 |
push @output, "'comment' => '$1'";
|
|
|
63 |
$fieldInfo =~ s/comment *\'([^']+)\'//i;
|
|
|
64 |
}
|
|
|
65 |
|
|
|
66 |
if ($fieldInfo =~ m/not\s+null/i ) {
|
|
|
67 |
push @output, "'required' => true";
|
|
|
68 |
$fieldInfo =~ s/not\s+null//i; # remove the not null from the string
|
|
|
69 |
}
|
|
|
70 |
if ($fieldInfo =~ m/null/i ) {
|
|
|
71 |
push @output, "'required' => false";
|
|
|
72 |
$fieldInfo =~ s/null//i; # remove the not null from the string
|
|
|
73 |
}
|
|
|
74 |
|
|
|
75 |
if ($fieldInfo =~ m/default +(\'.*\')/i ) {
|
|
|
76 |
$default = $1;
|
|
|
77 |
$fieldInfo =~ s/default +(\'.*\')//i;
|
|
|
78 |
push @output, "'default' => $default";
|
|
|
79 |
} elsif ($fieldInfo =~ /default +([^ ]+)/i ) {
|
|
|
80 |
$default = $1;
|
|
|
81 |
$fieldInfo =~ s/default +([^ ]+)//;
|
|
|
82 |
push @output, "'default' => $default";
|
|
|
83 |
}
|
|
|
84 |
if ($fieldInfo =~ m/auto_increment/i ) {
|
|
|
85 |
push @output, "'readonly' => true";
|
|
|
86 |
push @output, "'autoincrement' => true";
|
|
|
87 |
$fieldInfo =~ s/auto_increment//i;
|
|
|
88 |
}
|
|
|
89 |
# at this point, we should only have the data type left
|
|
|
90 |
if ( $fieldInfo =~ m/ *([a-z]+)( *\(\d+\))?/i ) {
|
|
|
91 |
$type = $1;
|
|
|
92 |
$size = $2 ? $2 : 0;
|
|
|
93 |
$type =~ s/(varchar)|(char)/string/i;
|
|
|
94 |
$type = 'string' unless $type;
|
|
|
95 |
push @output, "'type' => '$type'";
|
|
|
96 |
$size =~ s/[^0-9]//gi;
|
|
|
97 |
$size = 0 unless $size;
|
|
|
98 |
push @output, "'width' => $size";
|
|
|
99 |
}
|
|
|
100 |
}
|
|
|
101 |
# if ( $fieldName eq 'username' ) {
|
|
|
102 |
# die "$original\n" . join(" , ", @output) . "\n";
|
|
|
103 |
# }
|
|
|
104 |
|
|
|
105 |
#return "\n//$original\n\n" . join(" , ", @output);
|
|
|
106 |
return ( "\n\t\t\t" . join(" ,\n\t\t\t", @output) . "\n\t\t");
|
|
|
107 |
}
|
|
|
108 |
|
|
|
109 |
|
|
|
110 |
|
|
|
111 |
sub getTableDef {
|
|
|
112 |
my $table = shift;
|
|
|
113 |
# print "[$table]\n";
|
|
|
114 |
my $unique_key_regex = 'unique key [a-z0-9]* *\(([^)]+)\),?';
|
|
|
115 |
my $primary_key_regex = 'primary key \(([^)]+)\),?';
|
|
|
116 |
my $comment_regex = "comment *'([^']+)'";
|
|
|
117 |
my %tableInformation;
|
|
|
118 |
$table =~ s/ +/ /gi; # remove duplicate spaces
|
|
|
119 |
$table =~ s/ ,/,/gi; # remove all spaces before comma's
|
|
|
120 |
#print "[$table]\n\n";
|
|
|
121 |
$table =~ m/create table ([a-z0-9_]+) *\((.+)\)([^\(\)]*)$/i; #
|
|
|
122 |
$tableInformation{'table name'} = $1;
|
|
|
123 |
print STDERR "[$tableInformation{'table name'}]\n";
|
|
|
124 |
$table = $2;
|
3 |
rodolico |
125 |
my $tableCommentStuff = $3;
|
2 |
rodolico |
126 |
if ( $tableCommentStuff and $tableCommentStuff =~ m/comment.*\'(.*)\'/i ) {
|
|
|
127 |
$tableInformation{'comment'} = $1;
|
|
|
128 |
}
|
|
|
129 |
if ( $table =~ m/$primary_key_regex/i ) {
|
|
|
130 |
$tableInformation{'primary keys'} = $1;
|
|
|
131 |
$table =~ s/$primary_key_regex//i;
|
|
|
132 |
}
|
|
|
133 |
if ( $table =~ m/$unique_key_regex/i ) {
|
|
|
134 |
$tableInformation{'unique keys'} .= $1;
|
|
|
135 |
$table =~ s/$unique_key_regex//i;
|
|
|
136 |
}
|
|
|
137 |
my @columnInformation = split(',',$table);
|
|
|
138 |
my %fieldInfo;
|
|
|
139 |
my @fieldOrder; # I use an array here so we can do display, etc... in original order
|
3 |
rodolico |
140 |
for ( my $i = 0; $i < @columnInformation; $i++) {
|
2 |
rodolico |
141 |
$columnInformation[$i] =~ s/^ +//;
|
|
|
142 |
if ( $columnInformation[$i] =~ m/ *([a-z0-9_]+) +(.*)/i ) {
|
3 |
rodolico |
143 |
my $fieldName = $1;
|
2 |
rodolico |
144 |
push @fieldOrder, $fieldName;
|
3 |
rodolico |
145 |
my $fieldDef = $2;
|
2 |
rodolico |
146 |
$fieldInfo{$fieldName}{'data'} =
|
|
|
147 |
&getFieldInfo($fieldName, $fieldDef, $tableInformation{'primary keys'}
|
|
|
148 |
? ($tableInformation{'primary keys'} =~ m/$fieldName/)
|
|
|
149 |
: 0
|
|
|
150 |
);
|
|
|
151 |
}
|
|
|
152 |
} # for
|
|
|
153 |
#$tableInformation{'fields'} = \%fieldInfo;
|
|
|
154 |
#print Dumper(\%fieldInfo );
|
|
|
155 |
|
|
|
156 |
# create the output
|
|
|
157 |
my $output = '';
|
|
|
158 |
if ( $secondary ) {
|
|
|
159 |
$output = "\$DATABASE_DEFINITION['" . $tableInformation{'table name'} . "'] = array(\n";
|
|
|
160 |
} else {
|
|
|
161 |
$output .= "'" . $tableInformation{'table name'} . "' => array( \n";
|
|
|
162 |
}
|
|
|
163 |
$output .= "\t'table name' => '" . $tableInformation{'table name'} . "',\n";
|
|
|
164 |
$output .= "\t'display name' => '" . &camelCase($tableInformation{'table name'}) . "',\n";
|
|
|
165 |
if ( $tableInformation{'comment'} ) {
|
|
|
166 |
$output .= "\t'comment' => '$tableInformation{'comment'}',\n";
|
|
|
167 |
}
|
|
|
168 |
if ($tableInformation{'primary keys'}) {
|
|
|
169 |
if ( $tableInformation{'primary keys'} =~ m/,/ ) {
|
|
|
170 |
#following line takes all items in a comma delimited list and quotes them
|
|
|
171 |
$output .= "\t'key field' => array('" . join("','", split( ',',$tableInformation{'primary keys'})) . "'),\n";
|
|
|
172 |
} else {
|
|
|
173 |
$output .= "\t'key field' => '" . $tableInformation{'primary keys'} . "',\n";
|
|
|
174 |
}
|
|
|
175 |
}
|
|
|
176 |
if ($tableInformation{'unique keys'}) {
|
|
|
177 |
if ( $tableInformation{'unique keys'} =~ m/,/ ) {
|
|
|
178 |
#following line takes all items in a comma delimited list and quotes them
|
|
|
179 |
$output .= "\t'unique fieldss' => array('" . join("','", split( ',',$tableInformation{'unique keys'})) . "'),\n";
|
|
|
180 |
} else {
|
|
|
181 |
$output .= "\t'unique fields' => '" . $tableInformation{'unique keys'} . "',\n";
|
|
|
182 |
}
|
|
|
183 |
}
|
|
|
184 |
|
|
|
185 |
# do the display columns, basically all columns
|
|
|
186 |
#@fields = keys %fieldInfo;
|
|
|
187 |
#$fieldNames = join( ',',@fields );
|
|
|
188 |
$output .= "\t'display columns' => array(\n\t\t'" . join( "',\n\t\t'",@fieldOrder ) . "'\n\t),\n";
|
|
|
189 |
$output .= "\t'display query' => 'select " . join( ',',@fieldOrder ) . " from " . $tableInformation{'table name'} . "',\n";
|
|
|
190 |
my @fieldInfo;
|
3 |
rodolico |
191 |
foreach my $thisField ( @fieldOrder ) {
|
2 |
rodolico |
192 |
push @fieldInfo, ($fieldInfo{$thisField}{'comment'} ? "\t\t/* " . $fieldInfo{$thisField}{'comment'} . " */\n" : '') .
|
|
|
193 |
"\t\t'$thisField' => array(" . $fieldInfo{$thisField}{'data'} . ")";
|
|
|
194 |
}
|
|
|
195 |
$output .= "\t'field info' => array(\n" . join( ",\n", @fieldInfo) . "\n\t)\n)";
|
|
|
196 |
|
|
|
197 |
return $output;
|
|
|
198 |
}
|
|
|
199 |
|
|
|
200 |
sub processCommandLine {
|
3 |
rodolico |
201 |
while ( my $parameter = shift ) {
|
2 |
rodolico |
202 |
if ($parameter =~ m/-f(.*)/i) {
|
|
|
203 |
$inputFileName = $1;
|
|
|
204 |
} elsif ( $parameter =~ m/-s/i) {
|
|
|
205 |
$secondary = 1;
|
|
|
206 |
}
|
|
|
207 |
}
|
|
|
208 |
}
|
|
|
209 |
|
|
|
210 |
&processCommandLine( @ARGV );
|
|
|
211 |
|
|
|
212 |
# die "Input Filename == $inputFileName, secondary = $secondary\n";
|
|
|
213 |
|
3 |
rodolico |
214 |
my @input;
|
|
|
215 |
|
2 |
rodolico |
216 |
if ($inputFileName) { # they want us to read from this file
|
|
|
217 |
open DATA, "$inputFileName" or die "could not open $inputFileName";
|
|
|
218 |
@input = <DATA>;
|
|
|
219 |
close DATA;
|
|
|
220 |
} else { # no filename entered, so read STDIN
|
|
|
221 |
@input = <STDIN>;
|
|
|
222 |
}
|
|
|
223 |
@input = grep( !/^(--)|(\/\*\!)/, @input ); # remove all comments
|
|
|
224 |
chomp @input; # get rid of all line endings
|
|
|
225 |
|
|
|
226 |
# next line read all input, joins it with null,then splits it based on a semi-colon
|
|
|
227 |
# this places all sql statements into one array entry
|
|
|
228 |
# It then filters for only those statements that start with create table
|
|
|
229 |
my @tables = grep(/^create table/i, split( ';', join( '', @input) ));
|
|
|
230 |
#foreach my $thisTable (@tables) {
|
|
|
231 |
# print "$thisTable\n";
|
|
|
232 |
#}
|
|
|
233 |
#exit 1;
|
|
|
234 |
|
|
|
235 |
my @results;
|
|
|
236 |
#push @results, &getTableDef( shift @tables );
|
3 |
rodolico |
237 |
foreach my $thisTable( @tables ) {
|
2 |
rodolico |
238 |
$thisTable =~ s/\`//gi;
|
|
|
239 |
push @results, &getTableDef( $thisTable ) if $thisTable;
|
|
|
240 |
}
|
|
|
241 |
|
|
|
242 |
# apply proper indentation. The code inserts a tab char and does a decent job of indenting
|
|
|
243 |
# we now replace the tab chars with $indentationChar, and add one more to the beginning
|
|
|
244 |
for (my $line = 0; $line < @results; $line++ ) {
|
|
|
245 |
$results[$line] = "\t" . $results[$line];
|
|
|
246 |
$results[$line] =~ s/\n/\n\t/g;
|
|
|
247 |
$results[$line] =~ s/\t/$indentationChar/g;
|
|
|
248 |
}
|
|
|
249 |
|
|
|
250 |
# now, actually print out the results
|
|
|
251 |
print "<?php
|
|
|
252 |
|
|
|
253 |
/*
|
|
|
254 |
Auto generated from SQL script by $0 version $version.
|
3 |
rodolico |
255 |
do not edit this file. Edit $localOverrideFile as changes
|
2 |
rodolico |
256 |
to that file will not be overwritten by subsequent runs of this
|
|
|
257 |
script.
|
|
|
258 |
*/
|
|
|
259 |
|
|
|
260 |
global \$DATABASE_DEFINITION; // make variable available to all scripts
|
|
|
261 |
";
|
|
|
262 |
if ( $secondary ) { # this is an auxilary file
|
|
|
263 |
print join( ";\n", @results) ;
|
|
|
264 |
} else { # this is the main, or only database.php file
|
|
|
265 |
print "
|
|
|
266 |
define ( 'MAX_INPUT_FIELD_DISPLAY', 40 ); // this is the maximum input field size
|
|
|
267 |
define ( 'FILES_DIRECTORY', '/files/' ); // relative URL where pictures are stored
|
|
|
268 |
define ( 'EDIT_IMAGE_HEIGHT', 100 ); // height for thumbnail of picturse
|
|
|
269 |
define ( 'MAX_UPLOAD_FILE_SIZE', 1024*1024*10 ); // 10 meg
|
|
|
270 |
define ( 'DEFAULT_TEXTAREA_HEIGHT', 5 );
|
|
|
271 |
define ( 'DEFAULT_TABLE', 'FILL ME IN');
|
|
|
272 |
|
|
|
273 |
";
|
|
|
274 |
print "\$DATABASE_DEFINITION = array(\n";
|
|
|
275 |
print join( ",\n", @results) ;
|
|
|
276 |
print "\n);";
|
|
|
277 |
|
|
|
278 |
}
|
|
|
279 |
|
3 |
rodolico |
280 |
print "\ninclude('$localOverrideFile');\n?>\n";
|
2 |
rodolico |
281 |
|
|
|
282 |
1;
|
|
|
283 |
|
|
|
284 |
|
|
|
285 |
|
|
|
286 |
|