[Jifty-commit] r2277 - in jifty/branches/template-declare: . lib/Jifty/Manual

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sun Dec 3 00:03:30 EST 2006


Author: audreyt
Date: Sun Dec  3 00:03:30 2006
New Revision: 2277

Modified:
   jifty/branches/template-declare/   (props changed)
   jifty/branches/template-declare/lib/Jifty/Manual/Upgrading.pod
   jifty/branches/template-declare/lib/Jifty/Upgrade.pm

Log:
* Merge down into template-declare branch.

Modified: jifty/branches/template-declare/lib/Jifty/Manual/Upgrading.pod
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Manual/Upgrading.pod	(original)
+++ jifty/branches/template-declare/lib/Jifty/Manual/Upgrading.pod	Sun Dec  3 00:03:30 2006
@@ -58,17 +58,16 @@
 
 =head3 Renaming a column
 
-To rename a column use C<rename> inside your C<since>.  You will also
-have to use the model class at the top of Upgrade.pm so Jifty can
-access it's schema definition.
+To rename a column, simply call C<rename> inside your C<since> code block:
 
-use MyApp::Model::User;
+    use MyApp::Model::User;
 
-since '0.61' => sub {
-  rename (table => 'MyApp::Model::User', 
-	  column => 'zip', 
-	  to => 'postcode'
-	 );
-};
+    since '0.6.1' => sub {
+        rename(
+            table   => 'MyApp::Model::User', 
+            column  => 'zip', 
+            to      => 'postcode'
+        );
+    };
 
 =head3 Migrating data

Modified: jifty/branches/template-declare/lib/Jifty/Upgrade.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Upgrade.pm	(original)
+++ jifty/branches/template-declare/lib/Jifty/Upgrade.pm	Sun Dec  3 00:03:30 2006
@@ -29,11 +29,13 @@
 =cut
 
 sub since {
-    my ($version, $sub) = @_;
+    my ( $version, $sub ) = @_;
     my $package = (caller)[0];
-    if (exists $UPGRADES{$package}{$version}) {
-        $UPGRADES{$package}{$version} = sub { $UPGRADES{$package}{$version}->(); $sub->(); }
-    } else {
+    if ( exists $UPGRADES{$package}{$version} ) {
+        $UPGRADES{$package}{$version} =
+          sub { $UPGRADES{$package}{$version}->(); $sub->(); }
+    }
+    else {
         $UPGRADES{$package}{$version} = $sub;
     }
 }
@@ -48,7 +50,7 @@
 
 sub versions {
     my $class = shift;
-    return sort keys %{$UPGRADES{$class} || {}};
+    return sort keys %{ $UPGRADES{$class} || {} };
 }
 
 =head2 upgrade_to I<VERSION>
@@ -59,9 +61,9 @@
 =cut
 
 sub upgrade_to {
-    my $class = shift;
+    my $class   = shift;
     my $version = shift;
-    return $UPGRADES{$class}{$version} || sub {};
+    return $UPGRADES{$class}{$version} || sub { };
 }
 
 =head2 rename table => CLASS, [column => COLUMN,] to => NAME
@@ -77,25 +79,60 @@
     $args{table} ||= $args{in};
     die "Must provide a table to rename" unless $args{table};
 
-    Jifty::Util->require($args{table});
-    $args{table} = $args{table}->table;
+    Jifty::Util->require( $args{table} );
+    my $table_name = $args{table}->table;
 
-    if ($args{column}) {
+    if ( $args{column} ) {
         my $driver = Jifty->config->framework('Database')->{'Driver'};
-        if ($driver eq "SQLite") {
-            # It's possible to work around this, but it's a PITA that
-            # I haven't figured out all of the details of.  It
-            # involves creating a temporary table that's a duplicate
-            # of the current table, copying the data over, dropping
-            # the original table, recreating it with the column
-            # renamed, transferring the data back, and then dropping
-            # the temporary table.  Painful enough for ya?
-            die "SQLite does not support renaming columns in tables.  We are sad!";
-        } else {
-            Jifty->handle->simple_query("ALTER TABLE $args{table} RENAME $args{column} TO $args{to}");
+        if ( $driver eq "SQLite" ) {
+
+            # Convert columns
+            my ($schema) = Jifty->handle->fetch_result("SELECT sql FROM sqlite_master WHERE tbl_name = '$table_name' AND type = 'table'");
+
+            $schema =~ s/(.*create\s+table\s+)\S+(.*?\(\s*)//i;
+
+            my $new_table_name    = join( '_', $table_name, 'new', $$ );
+            my $new_create_clause = "$1$new_table_name$2";
+
+            my @column_info = ( split /,/, $schema );
+            my @column_names = map { /^\s*(\S+)/ ? $1 : () } @column_info;
+
+            s/^(\s*)\Q$args{column}\E/$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 = Jifty->handle->simple_query("SELECT sql FROM sqlite_master WHERE tbl_name = '$table_name' AND type = '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
+            Jifty->handle->begin_transaction;
+            Jifty->handle->simple_query($new_schema);
+            Jifty->handle->simple_query("INSERT INTO $new_table_name SELECT $copy_columns FROM $table_name");
+            Jifty->handle->simple_query("DROP TABLE $table_name");
+            Jifty->handle->simple_query("ALTER TABLE $new_table_name RENAME TO $table_name");
+            Jifty->handle->simple_query($_) for @indice_sql;
+            Jifty->handle->commit;
+        }
+        else {
+            Jifty->handle->simple_query("ALTER TABLE $table_name RENAME $args{column} TO $args{to}");
         }
-    } else {
-        Jifty->handle->simple_query("ALTER TABLE $args{table} RENAME TO $args{to}");
+    }
+    else {
+        Jifty->handle->simple_query("ALTER TABLE $table_name RENAME TO $args{to}");
     }
 }
 


More information about the Jifty-commit mailing list