Subversion Repositories phpLibraryV2

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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