Work on supporting 'bucardo update customcode'
authorGreg Sabino Mullane <greg@endpoint.com>
Mon, 5 Nov 2012 17:40:53 +0000 (12:40 -0500)
committerGreg Sabino Mullane <greg@endpoint.com>
Mon, 5 Nov 2012 17:40:53 +0000 (12:40 -0500)
Still needs to possibly support more attributes.
Also may remove the priority, if it makes more sense just in the customcode_map

Bucardo.pm
bucardo
bucardo.schema
t/40-customcode-exception.t

index a2528e1b1dca908456a7bad5cf3e4e6b87c114bf..99350b9de8f238462cce26f1a5b22cb84e50b0ad 100644 (file)
@@ -5621,7 +5621,7 @@ sub validate_sync {
             FROM customcode c, customcode_map m
             WHERE c.id=m.code AND m.active IS TRUE
             AND (m.sync = ? $goatclause)
-            ORDER BY priority ASC
+            ORDER BY m.priority ASC
         };
     $sth = $self->{masterdbh}->prepare($SQL);
     $sth->execute($syncname);
diff --git a/bucardo b/bucardo
index db70bb946b8837de7b86481764509bdf9838f33f..93ba9af4b98f3bd2f02f8ab459765eec26dadaea 100755 (executable)
--- a/bucardo
+++ b/bucardo
@@ -5444,10 +5444,11 @@ sub list_customcodes {
 
     for my $row (@$info) {
         my $name = $row->{name};
-        printf "Code: %-*s  When run: %-*s  Get dbh: %s  Get rows: %s\n",
+        printf "Code: %-*s  When run: %-*s  Get dbh: %s  Status: %s\n",
             $maxname, $name,
             $maxwhen, $row->{whenrun},
-            $row->{getdbh};
+            $row->{getdbh},
+            $row->{status};
         if (defined $row->{about} and $VERBOSE) {
             (my $about = $row->{about}) =~ s/(.)^/$1    /gsm;
             print "  About: $about\n";
@@ -5459,9 +5460,102 @@ sub list_customcodes {
 
 } ## end of list_customcodes
 
+
 sub update_customcode {
 
-    die 'Write me';
+    ## Update one or more customcodes
+    ## Arguments: none (reads nouns for a list of customcodes)
+    ## Returns: never, exits
+
+    my @actions = @_;
+
+    my $doc_section = 'update/update customcode';
+    usage_exit($doc_section) unless @actions;
+
+    my $name = shift @actions;
+
+    ## Recursively call ourselves for wildcards and 'all'
+    exit 0 if ! check_recurse($SYNC, $name, @actions);
+
+    ## Make sure this customcode exists!
+    if (! exists $CUSTOMCODE->{$name}) {
+        die qq{Could not find a customcode named "$name"\nUse 'list customcodes' to see all available.\n};
+    }
+
+    my $cc = $CUSTOMCODE->{$name};
+
+    my $changes = 0;
+
+    for my $action (@actions) {
+        ## Look for a standard foo=bar or foo:bar format
+        if ($action =~ /(.+?)\s*[=:]\s*(.+)/) {
+            my ($setting,$value) = (lc $1,$2);
+
+            ## No funny characters please, just boring column names
+            $setting =~ /^[a-z_]+$/ or die "Invalid setting: $setting\n";
+
+            ## We only allow changing a strict subset of all the columns
+
+            if ($setting eq 'status') {
+                if ($value ne $cc->{status}) {
+                    $SQL = 'UPDATE customcode SET status=? WHERE name = ?';
+                    $sth = $dbh->prepare($SQL);
+                    $sth->execute($value, $name);
+                    $changes++;
+                    print "Changed customcode $name status from '$cc->{status}' to '$value'\n";
+                }
+            }
+
+            elsif ($setting eq 'name') {
+                if ($value ne $name) {
+                    $SQL = 'UPDATE customcode SET name=? WHERE name = ?';
+                    $sth = $dbh->prepare($SQL);
+                    $sth->execute($value, $name);
+                    $changes++;
+                    print "Changed customcode $name to a new name: $value\n";
+                }
+            }
+
+            elsif ($setting eq 'getdbh') {
+                my $old = $cc->{getdbh}; ## 0 or 1
+                my $new = $value =~ /^[1tTyY]/ ? 1 : 0;
+                if ($old ne $new) {
+                    $SQL = 'UPDATE customcode SET getdbh=? WHERE name = ?';
+                    $sth = $dbh->prepare($SQL);
+                    $sth->execute($new, $name);
+                    $changes++;
+                    print "Changed customcode $name getdbh from $old to $new\n";
+                }
+            }
+
+            elsif ($setting eq 'priority') {
+                if ($value !~ /^\d+$/) {
+                    die qq{ Priority must be a number!\n};
+                }
+                if ($value ne $cc->{priority}) {
+                    $SQL = 'UPDATE customcode SET priority=? WHERE name = ?';
+                    $sth = $dbh->prepare($SQL);
+                    $sth->execute($value, $name);
+                    $changes++;
+                    print "Changed customcode $name priority from '$cc->{priority}' to '$value'\n";
+                }
+            }
+
+            else {
+                warn "Cannot change attribute '$setting'\n";
+                usage_exit($doc_section);
+            }
+
+            next;
+        }
+
+        warn "\nUnknown action: $action\n";
+        usage_exit($doc_section);
+    }
+
+    confirm_commit() if $changes;
+
+    return;
 
 } ## end of update_customcode
 
@@ -9603,13 +9697,14 @@ Name of the sync with which to associate the custom code.
 
 Name of the table or sequence with which to associate the custom code.
 
-=item C<active>
+=item C<status>
 
-Boolean indicating whether or not the custom code is active.
+The current status of this customcode. Anything other than 'active' means the 
+code is not run.
 
 =item C<priority>
 
-Number indicating the priority in which to execute custom codes. Lower numbers
+Number indicating the priority in which order to execute custom codes. Lower numbers
 are higher priority. Useful for subroutines that set C<lastcode> in order to
 cancel the execution of subsequent custom codes for the same C<when_run>.
 
@@ -9726,6 +9821,24 @@ for each type are the same as those for L</add>. The supported types are:
 
 =back
 
+=head3 update customcode
+
+  bucardo update customcode <name> setting=value
+
+Updates an existing customcode. Items that can be changed are:
+
+=over
+
+=item C<name>
+
+=item C<status>
+
+=item C<getdbh>
+
+=item C<priority>
+
+=back
+
 =head3 update db
 
   bucardo udpate db <name> port=xxx host=xxx user=xxx pass=xxx
index fdaa71275bff217ccafde7c5d4c7d43f425af02b..cb62c7e7d3c673f127ccb046e51f69ff2d8f58bf 100644 (file)
@@ -429,7 +429,8 @@ CREATE TABLE bucardo.customcode (
   whenrun   TEXT        NOT NULL,
   getdbh    BOOLEAN     NOT NULL DEFAULT 'true',
   src_code  TEXT        NOT NULL,
-  status    TEXT        NOT NULL DEFAULT 'true',    
+  status    TEXT        NOT NULL DEFAULT 'true',
+  priority  SMALLINT    NOT NULL DEFAULT 0,    
   cdate     TIMESTAMPTZ NOT NULL DEFAULT now()
 );
 COMMENT ON TABLE bucardo.customcode IS $$Holds Perl subroutines that run via hooks in the replication process$$;
index b088cd74284efc9cf4c19745ae515eade8201501..73cb519b4349efbc1ce9f79329800d09fa71ec7b 100644 (file)
@@ -134,6 +134,11 @@ $res = $bct->ctl('bucardo add customcode email_exception whenrun=exception src_c
 $t = q{Customcode exception handler was added for sync exabc};
 like ($res, qr{Added customcode "email_exception"}, $t);
 
+$res = $bct->ctl('update customcode email_exception status=inactive');
+diag Dumper $res;
+exit;
+
+
 ## Reload the sync and verify the exception handler allows the sync to continue
 $bct->ctl('bucardo reload exabc');
 
@@ -170,6 +175,8 @@ for my $db (qw/ C /) {
 }
 
 ## Test disabling the customcode
+$bct->ctl('update customcode email_exception status=inactive');
+
 
 ## Test goat-level customcode