[Jifty-commit] r6777 - Jifty-DBI/trunk/lib/Jifty/DBI/Handle

Jifty commits jifty-commit at lists.jifty.org
Wed Apr 15 13:01:07 EDT 2009


Author: ruz
Date: Wed Apr 15 13:01:07 2009
New Revision: 6777

Modified:
   Jifty-DBI/trunk/lib/Jifty/DBI/Handle/SQLite.pm
   Jifty-DBI/trunk/lib/Jifty/DBI/Handle/mysql.pm

Log:
* add special implementations of rename_column in SQLite and mysql
* weak and suckish in some corners, but work for 80% of cases

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Handle/SQLite.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Handle/SQLite.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Handle/SQLite.pm	Wed Apr 15 13:01:07 2009
@@ -98,6 +98,64 @@
     return("$column COLLATE NOCASE", $operator, $value);
 }
 
+sub rename_column {
+    my $self = shift;
+    my %args = (
+        table  => undef,
+        column => undef,
+        to     => undef,
+        @_
+    );
+
+    my $table   = $args{'table'};
+
+    # Convert columns
+    my ($schema) = $self->fetch_result(
+        "SELECT sql FROM sqlite_master WHERE tbl_name = ? AND type = ?",
+        $table, 'table',
+    );
+    $schema =~ s/(.*create\s+table\s+)\S+(.*?\(\s*)//i
+        or die "Cannot find 'CREATE TABLE' statement in schema for '$table': $schema";
+
+    my $new_table    = join( '_', $table, 'new', $$ );
+    my $new_create_clause = "$1$new_table$2";
+
+    my @column_info = ( split /,/, $schema );
+    my @column_names = map { /^\s*(\S+)/ ? $1 : () } @column_info;
+
+    s/^(\s*)\b\Q$args{column}\E\b/$1$args{to}/i for @column_info;
+
+    my $new_schema = $new_create_clause . join( ',', @column_info );
+    my $copy_columns = join(
+        ', ',
+        map {
+            ( lc($_) eq lc( $args{column} ) )
+              ? "$_ AS $args{to}"
+              : $_
+          } @column_names
+    );
+
+    # Convert indices
+    my $indice_sth = $self->simple_query(
+        "SELECT sql FROM sqlite_master WHERE tbl_name = ? AND type = ?",
+        $table, 'index'
+    );
+    my @indice_sql;
+    while ( my ($index) = $indice_sth->fetchrow_array ) {
+        $index =~ s/^(.*\(.*)\b\Q$args{column}\E\b/$1$args{to}/i;
+        push @indice_sql, $index;
+    }
+    $indice_sth->finish;
+
+    # Run the conversion SQLs
+    $self->begin_transaction;
+    $self->simple_query($new_schema);
+    $self->simple_query("INSERT INTO $new_table SELECT $copy_columns FROM $table");
+    $self->simple_query("DROP TABLE $table");
+    $self->simple_query("ALTER TABLE $new_table RENAME TO $table");
+    $self->simple_query($_) for @indice_sql;
+    $self->commit;
+}
 
 1;
 

Modified: Jifty-DBI/trunk/lib/Jifty/DBI/Handle/mysql.pm
==============================================================================
--- Jifty-DBI/trunk/lib/Jifty/DBI/Handle/mysql.pm	(original)
+++ Jifty-DBI/trunk/lib/Jifty/DBI/Handle/mysql.pm	Wed Apr 15 13:01:07 2009
@@ -81,6 +81,33 @@
     return;
 }
 
+sub rename_column {
+    my $self = shift;
+    my %args = (
+        table  => undef,
+        column => undef,
+        to     => undef,
+        @_
+    );
+
+    my ($table, $column, $to) = @args{'table', 'column', 'to'};
+
+    # XXX, FIXME, TODO: this is stupid parser of CREATE TABLE, this should be something based on
+    # column_info, schema tables and show fields. The closest thing is RT 3.8/etc/upgrade/upgrade-mysql-schema.pl
+
+    my $create_table = ($self->simple_query("SHOW CREATE TABLE $table")->fetchrow_array)[1];
+    $create_table =~ /create\s+table\s+\S+\s*\((.*)\)/ims
+        or die "Cannot find 'CREATE TABLE' statement in schema for '$table': $create_table";
+    $create_table = $1;
+
+    my ($column_info) = ($create_table =~ /`$column`(.*?)(?:,|$)/i)
+        or die "Cannot find column '$column' in $create_table";
+    my $sth = $self->simple_query("ALTER TABLE $table CHANGE $column $to $column_info");
+    die "Cannot rename column '$column' in table '$table' to '$to': ". $self->dbh->errstr
+        unless $sth;
+    return $sth;
+}
+
 1;
 
 __END__


More information about the Jifty-commit mailing list