# Copyright (C) 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA

## Translator that translates from mysqldump output to ANSI SQL or to
## some db close to the ANSI specification.
## Non-ANSI features are implemented in subclasses.

## This module will wrok for output from mysqldump, not for any freely
## formattted DDL for MySQL.

package GenTest::Translator::Mysqldump2ANSI;

@ISA = qw(GenTest::Translator GenTest);

use strict;

use GenTest;

sub auto_increment {
    ## ANSI compliant translation of AUTO_INCREMENT. Different start
    ## values and increment values is not implemented yet
    my $line = $_[1];
    $line =~ s/\bauto_increment\b/GENERATED BY DEFAULT AS IDENTITY/i;
    return $line;
}

sub fix_auto_increment_start {
    my ($self, $start, $line) = @_;
    $line =~ s/IDENTITY/IDENTITY (START WITH $start)/si;
    return $line;
}

sub create_index {
    ## Indices does not exist in the standard
    return "/* Indices is not ANSI: Ignored index $_[1] ON $_[2] $_[3] */";
}

sub translate {
    my $self = $_[0];

    my $quoting=0;

    my @file = split(/\n/,$_[1]);
    my @result;

    my $tablename;
    my %indices;

    my $lineno = 0;

    my $auto_increment_line = -1;

    foreach (@file) {
        my $ignore=0;

        # Some datatypes just can't be translated
        if (m/\s*(\btimestamp\b|\byear\(2\))\s*/) {
            say("MySQL \"$1\" is not translatable to ANSI");
            return 0;
        }
        
        ## Change to ANSI quoting or no quoting
        s/`/"/g if $quoting == 1;
        s/`//g if $quoting == 0;

        # Remove some MYSQL-specific table attributes.  We assume all
        # table defintions ends with an ENGINE= and marks that as the
        # end for later use.
        s/\bengine\s*=\s*[a-z]*/\/*END OF CREATE TABLE*\//i; 
        if (m/\bauto_increment\s*=(\d+)/i) {
            $result[$auto_increment_line]
                = $self->fix_auto_increment_start($1,$result[$auto_increment_line])
                if  $auto_increment_line >= 0;
            s/\bauto_increment\s*=\s*\d+//i; 
        }
        s/\bdefault\scharset\s*=\s*[a-z0-9]*//io; 
        

        ## Change some datatypes
        s/\bint\(11\)/INTEGER/ig;
        s/\bdatetime\b/TIMESTAMP/ig;

        ## Autoincrement
        if (m/auto_increment\s*[^=]/io) {
            $_ = $self->auto_increment($_);
            $auto_increment_line = $lineno;
        }
        
        
        if (m/\bCREATE\sTABLE\s([^\s]+)/i) {
            ### A new table definition, start collecting index
            ### information
            $tablename = $1;
            %indices = ();
        }
        if (not m/\bPRIMARY\s+KEY\b/i) {
            if (m/\bKEY\s*([^\s]*)\s*(\(.*\))/i) {
                ## We have an index, store it, and ignore it in the
                ## translated CREATE TABLE-statement
                $indices{$1}=$2;
                $ignore=1;
            }
        }

        my $output_indices=0;
        if (m/\/\*END OF CREATE TABLE\*\//) {
            # It's time to output the indices after the CREATE TABLE
            # statement.  Also remove any trailing comma in the last
            # line
            $result[$lineno-1] =~ s/,\s*$//;
            $output_indices=1;
        }

        ## Add the current line to the result.
        if (not $ignore) {
            $result[$lineno]=$_;
            $lineno++;
        }

        ## Output any indices
        if ($output_indices) {
            foreach my $index (keys %indices) {
                $tablename =~ s/"//g;
                my $index2=$index;
                $index2 =~ s/"//g;
                if ($quoting) {
                    $result[$lineno] = $self->create_index('"'.$tablename.'_'.$index2.'"',
                                                           '"'.$tablename.'"',
                                                           $indices{$index});
                } else {
                    $result[$lineno] = $self->create_index($tablename.'_'.$index2,
                                                           $tablename,
                                                           $indices{$index});
                }
                $lineno++;
            }
        }
    }

    ## Collect the resulting array into a string
    my $resultstring = "";
    foreach(@result) {
        $resultstring .= $_ . "\n";
    }
    return $resultstring;
}

1;
