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