[freeside-commits] branch master updated. f1e4e2c83b33a2c6280073ced388a91742a3bb46

Mark Wells mark at 420.am
Fri Jun 13 12:40:42 PDT 2014


The branch, master has been updated
       via  f1e4e2c83b33a2c6280073ced388a91742a3bb46 (commit)
       via  979d73df228b7c22f72f7b93d90d23f695f8586b (commit)
      from  a55ce3e56422a6dbcd0f20a94c151a69fb41c02e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f1e4e2c83b33a2c6280073ced388a91742a3bb46
Author: Mark Wells <mark at freeside.biz>
Date:   Fri Jun 13 12:40:35 2014 -0700

    rudimentary cursors for mysql, #28895

diff --git a/FS/FS/Cursor.pm b/FS/FS/Cursor.pm
index d94151f..3af3c1b 100644
--- a/FS/FS/Cursor.pm
+++ b/FS/FS/Cursor.pm
@@ -3,7 +3,7 @@ package FS::Cursor;
 use strict;
 use vars qw($DEBUG $buffer);
 use FS::Record;
-use FS::UID qw(myconnect);
+use FS::UID qw(myconnect driver_name);
 use Scalar::Util qw(refaddr);
 
 $DEBUG = 2;
@@ -46,6 +46,7 @@ sub new {
     class => 'FS::' . ($q->{table} || 'Record'),
     buffer => [],
     dbh   => $dbh,
+    position => 0, # for mysql
   };
   bless $self, $class;
 
@@ -56,7 +57,16 @@ sub new {
   $self->{pid} = $$;
 
   $self->{id} = sprintf('cursor%08x', refaddr($self));
-  my $statement = "DECLARE ".$self->{id}." CURSOR FOR ".$q->{statement};
+
+  my $statement;
+  if ( driver_name() eq 'Pg' ) {
+    $statement = "DECLARE ".$self->{id}." CURSOR FOR ".$q->{statement};
+  } elsif ( driver_name() eq 'mysql' ) {
+    # build a cursor from scratch
+    $statement = "CREATE TEMPORARY TABLE $self->{id} 
+      (rownum INT AUTO_INCREMENT, PRIMARY KEY (rownum))
+      $q->{statement}";
+  }
 
   my $sth = $dbh->prepare($statement)
     or die $dbh->errstr;
@@ -67,8 +77,15 @@ sub new {
   }
 
   $sth->execute or die $sth->errstr;
-
-  $self->{fetch} = $dbh->prepare("FETCH FORWARD $buffer FROM ".$self->{id});
+  # in mysql, make sure we're not holding any locks on the tables mentioned
+  # in the query; in Pg this will do nothing.
+  $dbh->commit;
+
+  if ( driver_name() eq 'Pg' ) {
+    $self->{fetch} = $dbh->prepare("FETCH FORWARD $buffer FROM ".$self->{id});
+  } elsif ( driver_name() eq 'mysql' ) {
+    $self->{fetch} = $dbh->prepare("SELECT * FROM $self->{id} ORDER BY rownum LIMIT ?, $buffer");
+  }
 
   $self;
 }
@@ -99,17 +116,24 @@ sub fetch {
 sub refill {
   my $self = shift;
   my $sth = $self->{fetch};
+  $sth->bind_param(1, $self->{position}) if driver_name() eq 'mysql';
   $sth->execute or die $sth->errstr;
   my $result = $self->{fetch}->fetchall_arrayref( {} );
   $self->{buffer} = $result;
+  $self->{position} += $sth->rows;
   scalar @$result;
 }
 
 sub DESTROY {
   my $self = shift;
   return unless $self->{pid} eq $$;
-  $self->{dbh}->do('CLOSE '. $self->{id})
-    or die $self->{dbh}->errstr; # clean-up the cursor in Pg
+  if ( driver_name() eq 'Pg' ) {
+    $self->{dbh}->do('CLOSE '. $self->{id})
+      or die $self->{dbh}->errstr; # clean-up the cursor in Pg
+  } elsif ( driver_name() eq 'mysql' ) {
+    # nothing; the temporary table will evaporate when the 
+    # session closes.
+  }
   $self->{dbh}->rollback;
   $self->{dbh}->disconnect;
 }
@@ -122,7 +146,8 @@ Replace all uses of qsearch with this.
 
 =head1 BUGS
 
-Doesn't support MySQL.
+MySQL doesn't support cursors in interactive sessions, only in stored 
+procedures, so we implement our own.  This has not been extensively tested.
 
 The cursor will close prematurely if any code issues a rollback/commit. If
 you need protection against this use qsearch or fork and get a new dbh

commit 979d73df228b7c22f72f7b93d90d23f695f8586b
Author: Mark Wells <mark at freeside.biz>
Date:   Fri Jun 13 12:40:33 2014 -0700

    DBSchema 0.41 and case sensitivity fixes for RT upgrade, #28895

diff --git a/FS/FS/TicketSystem.pm b/FS/FS/TicketSystem.pm
index 7339d74..e81d893 100644
--- a/FS/FS/TicketSystem.pm
+++ b/FS/FS/TicketSystem.pm
@@ -61,7 +61,11 @@ sub _upgrade_schema {
             %{ $columns{$tablename}->{$colname} }
           };
         $col->table_obj($table);
-        push @sql, $col->sql_add_column($dbh);
+        my ($alter, $postalter) = $col->sql_add_column($dbh);
+        foreach (@$alter) {
+          push @sql, "ALTER TABLE $tablename $_;";
+        }
+        push @sql, @$postalter;
       }
     } #foreach $colname
   } #foreach $tablename
@@ -355,12 +359,14 @@ sub _upgrade_data {
   for my $table (keys %target_pkey) {
     my $pkey = $target_pkey{$table};
     my $rows = $dbh->do(
-      "DELETE FROM links WHERE id IN(".
-        "SELECT links.id FROM links LEFT JOIN $table ON (links.target = ".
-        "'freeside://freeside/$table/' || $table.$pkey) ".
-        "WHERE links.target like 'freeside://freeside/$table/%' ".
-        "AND $table.$pkey IS NULL".
-      ")"
+      "DELETE FROM Links WHERE id IN(
+        SELECT id FROM (
+          SELECT Links.id FROM Links LEFT JOIN $table ON (Links.Target = 
+          'freeside://freeside/$table/' || $table.$pkey)
+          WHERE Links.Target like 'freeside://freeside/$table/%'
+          AND $table.$pkey IS NULL
+        ) AS x
+      )"
     ) or die $dbh->errstr;
     warn "Removed $rows dangling ticket-$table links\n" if $rows > 0;
   }
@@ -369,8 +375,8 @@ sub _upgrade_data {
   # OldValue, though this is not known to happen) is an empty string
   foreach (qw(newvalue oldvalue)) {
     my $rows = $dbh->do(
-      "UPDATE transactions SET $_ = '0' WHERE objecttype='RT::Ticket' AND ".
-      "field IN ('TimeWorked', 'TimeEstimated', 'TimeLeft') AND $_ = ''"
+      "UPDATE Transactions SET $_ = '0' WHERE ObjectType='RT::Ticket' AND ".
+      "Field IN ('TimeWorked', 'TimeEstimated', 'TimeLeft') AND $_ = ''"
     ) or die $dbh->errstr;
     warn "Fixed $rows transactions with empty time values\n" if $rows > 0;
   }

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Cursor.pm       |   39 ++++++++++++++++++++++++++++++++-------
 FS/FS/TicketSystem.pm |   24 +++++++++++++++---------
 2 files changed, 47 insertions(+), 16 deletions(-)




More information about the freeside-commits mailing list