From eb7c552dd8290d6b33a4e026c5dc21ebf01105cf Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 15 May 2002 13:24:26 +0000 Subject: [PATCH] queue dependancies --- ANNOUCE.1.4.0 | 38 ++++++------- FS/FS.pm | 4 +- FS/FS/part_export/sqlradius.pm | 34 ++++++------ FS/FS/queue.pm | 37 +++++++++++-- FS/FS/queue_depend.pm | 120 +++++++++++++++++++++++++++++++++++++++++ FS/MANIFEST | 1 + FS/bin/freeside-queued | 12 +++-- FS/t/queue_depend.t | 5 ++ Makefile | 2 - README.1.4.0pre13 | 27 ++++++++++ bin/fs-setup | 13 ++++- eg/export_template.pm | 11 ++-- httemplate/docs/install.html | 2 +- httemplate/docs/schema.dia | Bin 11176 -> 11452 bytes httemplate/docs/schema.html | 6 +++ httemplate/docs/schema.png | Bin 446146 -> 496268 bytes httemplate/docs/upgrade8.html | 8 +++ 17 files changed, 268 insertions(+), 52 deletions(-) create mode 100644 FS/FS/queue_depend.pm create mode 100644 FS/t/queue_depend.t create mode 100644 README.1.4.0pre13 diff --git a/ANNOUCE.1.4.0 b/ANNOUCE.1.4.0 index 63fd3fa95..a3d786508 100644 --- a/ANNOUCE.1.4.0 +++ b/ANNOUCE.1.4.0 @@ -107,22 +107,24 @@ and suspension/unsuspension. -- -added case-insensitive and substring to default search - -full history tables (notification for deleted payments) - -alternate templates (late invoices!) - -new export! (well, almost) - -icradius groups (usergroup table if not radgroupreply & radgroupcheck) - -message catalogs (infrastructure, anyway) & anything which gets sent to a -customer from the signup server should use message catalog - -multi-agent signup server - -signup_server-realtime to run cards immediately - -and signup-alternate.html for free/paid packages on same signup +- New export code! +- Name and company searches: + - now case-insensative + - pulldown for search type +- Email notification for deleted payments +- History tables - complete history of all database changes +- Alternate invoice templates for things like late noitces +- ICRADIUS groups (usergroup table if not radgroupreply & radgroupcheck) +- Signup server + - Error messages in message catalog + - Agent is now selectable (multiple signup servers for different agents + can now run on the same machine) + - signup_server-realtime configuration option to run cards immediately + - signup-alternate.html example for free and pay packages on the same + signup page +- Texas tax + +schema diagram + +-- diff --git a/FS/FS.pm b/FS/FS.pm index 3a9c9f336..963c73548 100644 --- a/FS/FS.pm +++ b/FS/FS.pm @@ -31,7 +31,7 @@ L - Non OO-subroutines for the web interface. L - Message catalog -L - Message catalog +L - Search cache L - RADIUS dictionary @@ -134,6 +134,8 @@ L - Job queue L - Job arguments +L - Job dependencies + L - Message catalogs =head1 Remote API modules diff --git a/FS/FS/part_export/sqlradius.pm b/FS/FS/part_export/sqlradius.pm index fc680d41b..51a828001 100644 --- a/FS/FS/part_export/sqlradius.pm +++ b/FS/FS/part_export/sqlradius.pm @@ -14,15 +14,16 @@ sub _export_insert { my $method = "radius_$table"; my %attrib = $svc_acct->$method; next unless keys %attrib; - my $error = $self->sqlradius_queue( $svc_acct->svcnum, 'insert', + my $err_or_queue = $self->sqlradius_queue( $svc_acct->svcnum, 'insert', $table, $svc_acct->username, %attrib ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } my @groups = $svc_acct->radius_groups; if ( @groups ) { - my $error = $self->sqlradius_queue( $svc_acct->svcnum, 'usergroup_insert', + my $err_or_queue = $self->sqlradius_queue( + $svc_acct->svcnum, 'usergroup_insert', $svc_acct->username, @groups ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } ''; } @@ -33,9 +34,9 @@ sub _export_replace { #return "can't (yet) change username with sqlradius" # if $old->username ne $new->username; if ( $old->username ne $new->username ) { - my $error = $self->sqlradius_queue( $new->svcnum, 'rename', + my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'rename', $new->username, $old->username ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } foreach my $table (qw(reply check)) { @@ -46,16 +47,16 @@ sub _export_replace { || $new{$_} ne $old{$_} #changed } keys %new ) { - my $error = $self->sqlradius_queue( $new->svcnum, 'insert', + my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'insert', $table, $new->username, %new ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } my @del = grep { !exists $new{$_} } keys %old; if ( @del ) { - my $error = $self->sqlradius_queue( $new->svcnum, 'attrib_delete', + my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'attrib_delete', $table, $new->username, @del ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } } @@ -72,15 +73,15 @@ sub _export_replace { } if ( @delgroups ) { - my $error = $self->sqlradius_queue( $new->svcnum, 'usergroup_delete', + my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'usergroup_delete', $new->username, @delgroups ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } if ( @newgroups ) { - my $error = $self->sqlradius_queue( $new->svcnum, 'usergroup_insert', + my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'usergroup_insert', $new->username, @newgroups ); - return $error if $error; + return $err_or_queue unless ref($err_or_queue); } ''; @@ -88,8 +89,9 @@ sub _export_replace { sub _export_delete { my( $self, $svc_acct ) = (shift, shift); - $self->sqlradius_queue( $svc_acct->svcnum, 'delete', + my $err_or_queue = $self->sqlradius_queue( $svc_acct->svcnum, 'delete', $svc_acct->username ); + ref($err_or_queue) ? '' : $err_or_queue; } sub sqlradius_queue { @@ -103,7 +105,7 @@ sub sqlradius_queue { $self->option('username'), $self->option('password'), @_, - ); + ) or $queue; } sub sqlradius_insert { #subroutine, not method diff --git a/FS/FS/queue.pm b/FS/FS/queue.pm index 5719eff70..c75f75874 100644 --- a/FS/FS/queue.pm +++ b/FS/FS/queue.pm @@ -8,6 +8,7 @@ use FS::Conf; use FS::Record qw( qsearch qsearchs dbh ); #use FS::queue; use FS::queue_arg; +use FS::queue_depend; use FS::cust_svc; @ISA = qw(FS::Record); @@ -144,7 +145,8 @@ sub delete { local $FS::UID::AutoCommit = 0; my $dbh = dbh; - my @args = qsearch( 'queue_arg', { 'jobnum' => $self->jobnum } ); + my @del = qsearch( 'queue_arg', { 'jobnum' => $self->jobnum } ); + push @del, qsearch( 'queue_depend', { 'depend_jobnum' => $self->jobnum } ); my $error = $self->SUPER::delete; if ( $error ) { @@ -152,8 +154,8 @@ sub delete { return $error; } - foreach my $arg ( @args ) { - $error = $arg->delete; + foreach my $del ( @del ) { + $error = $del->delete; if ( $error ) { $dbh->rollback if $oldAutoCommit; return $error; @@ -206,6 +208,8 @@ sub check { =item args +Returns a list of the arguments associated with this job. + =cut sub args { @@ -228,6 +232,31 @@ sub cust_svc { qsearchs('cust_svc', { 'svcnum' => $self->svcnum } ); } +=item depend_insert OTHER_JOBNUM + +Inserts a dependancy for this job. If there is an error, returns the error, +otherwise returns false. + +When using job dependancies, you should wrap the insertion of jobs in a +database transaction. + +=cut + +sub depend_insert { + my($self, $other_jobnum) = @_; + my $queue_depend = new FS::queue_depend ( + 'jobnum' => $self->jobnum, + 'depend_jobnum' => $other_jobnum, + ); + $queue_depend->insert; +} + +=back + +=head1 SUBROUTINES + +=over 4 + =item joblisting HASHREF NOACTIONS =cut @@ -331,7 +360,7 @@ END =head1 VERSION -$Id: queue.pm,v 1.11 2002-04-13 08:51:54 ivan Exp $ +$Id: queue.pm,v 1.12 2002-05-15 13:24:24 ivan Exp $ =head1 BUGS diff --git a/FS/FS/queue_depend.pm b/FS/FS/queue_depend.pm new file mode 100644 index 000000000..4a4e3c55c --- /dev/null +++ b/FS/FS/queue_depend.pm @@ -0,0 +1,120 @@ +package FS::queue_depend; + +use strict; +use vars qw( @ISA ); +use FS::Record qw( qsearch qsearchs ); +use FS::queue; + +@ISA = qw(FS::Record); + +=head1 NAME + +FS::queue_depend - Object methods for queue_depend records + +=head1 SYNOPSIS + + use FS::queue_depend; + + $record = new FS::queue_depend \%hash; + $record = new FS::queue_depend { 'column' => 'value' }; + + $error = $record->insert; + + $error = $new_record->replace($old_record); + + $error = $record->delete; + + $error = $record->check; + +=head1 DESCRIPTION + +An FS::queue_depend object represents an job dependancy. FS::queue_depend +inherits from FS::Record. The following fields are currently supported: + +=over 4 + +=item dependnum - primary key + +=item jobnum - source jobnum (see L). + +=item depend_jobnum - dependancy jobnum (see L) + +=back + +The job specified by B depends on the job specified B - +the B job will not be run until the B job has completed +sucessfully (or manually removed). + +=head1 METHODS + +=over 4 + +=item new HASHREF + +Creates a new dependancy. To add the dependancy to the database, see +L<"insert">. + +Note that this stores the hash reference, not a distinct copy of the hash it +points to. You can ask the object for a copy with the I method. + +=cut + +# the new method can be inherited from FS::Record, if a table method is defined + +sub table { 'queue_depend'; } + +=item insert + +Adds this record to the database. If there is an error, returns the error, +otherwise returns false. + +=cut + +# the insert method can be inherited from FS::Record + +=item delete + +Delete this record from the database. + +=cut + +# the delete method can be inherited from FS::Record + +=item replace OLD_RECORD + +Replaces the OLD_RECORD with this one in the database. If there is an error, +returns the error, otherwise returns false. + +=cut + +# the replace method can be inherited from FS::Record + +=item check + +Checks all fields to make sure this is a valid dependancy. If there is +an error, returns the error, otherwise returns false. Called by the insert +and replace methods. + +=cut + +sub check { + my $self = shift; + + $self->ut_numbern('dependnum') + || $self->ut_foreign_key('jobnum', 'queue', 'jobnum') + || $self->ut_foreign_key('depend_jobnum', 'queue', 'jobnum') + ; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L, L, schema.html from the base documentation. + +=cut + +1; + diff --git a/FS/MANIFEST b/FS/MANIFEST index 2e72d5af8..a95470bb4 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -78,6 +78,7 @@ FS/raddb.pm FS/radius_usergroup.pm FS/queue.pm FS/queue_arg.pm +FS/queue_depend.pm FS/msgcat.pm FS/cust_tax_exempt.pm t/agent.t diff --git a/FS/bin/freeside-queued b/FS/bin/freeside-queued index 49b532ec3..1539a48af 100644 --- a/FS/bin/freeside-queued +++ b/FS/bin/freeside-queued @@ -59,13 +59,16 @@ while (1) { } $warnkids=0; + my $nodepend = 'AND 0 = ( SELECT COUNT(*) FROM queue_depend'. + ' WHERE queue_depend.jobnum = queue.jobnum ) '; + my $job = qsearchs( 'queue', { 'status' => 'new' }, '', driver_name =~ /^mysql$/i - ? 'ORDER BY jobnum LIMIT 1 FOR UPDATE' - : 'ORDER BY jobnum FOR UPDATE LIMIT 1' + ? "$nodepend ORDER BY jobnum LIMIT 1 FOR UPDATE" + : "$nodepend ORDER BY jobnum FOR UPDATE LIMIT 1" ) or do { sleep 5; #connecting to db is expensive next; @@ -94,10 +97,9 @@ while (1) { $kids++; } else { #kid time - #get new db handles + #get new db handle $FS::UID::dbh->{InactiveDestroy} = 1; - $FS::svc_acct::icradius_dbh->{InactiveDestroy} = 1 - if $FS::svc_acct::icradius_dbh; + forksuidsetup($user); #auto-use export classes... diff --git a/FS/t/queue_depend.t b/FS/t/queue_depend.t new file mode 100644 index 000000000..8eaa2cdb3 --- /dev/null +++ b/FS/t/queue_depend.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::queue_depend; +$loaded=1; +print "ok 1\n"; diff --git a/Makefile b/Makefile index 68ef79464..be4e9db2a 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,6 @@ INSTALLGROUP = root #not changable yet FREESIDE_CONF = /usr/local/etc/freeside -#VERSION=1.4.0pre12 -#TAG=freeside_1_4_0_pre12 VERSION=1.4.0pre13 TAG=freeside_1_4_0_pre13 #VERSION=1.4.0beta1 diff --git a/README.1.4.0pre13 b/README.1.4.0pre13 new file mode 100644 index 000000000..bd9fb7387 --- /dev/null +++ b/README.1.4.0pre13 @@ -0,0 +1,27 @@ +the following is necessary to upgrade from 1.4.0pre12 to 1.4.0pre13 + +if you're upgrading from before 1.4.0pre13 see README.1.4.0pre12 first! + +if you're upgrading from 1.3.1 follow the instructions in +httemplate/docs/upgrade8.html instead + +---- + +install the FS perl modules and httemplate as per install.html or upgrade8.html + +CREATE TABLE queue_depend ( + dependnum int primary key, + jobnum int not null, + depend_jobnum int not null +); +CREATE INDEX queue_depend1 ON queue_depend ( jobnum ); +CREATE INDEX queue_depend2 ON queue_depend ( depend_jobnum ); + +Run bin/dbdef-create + +Run bin/create-history-tables [username] queue_depend + +Run bin/dbdef-create again + +Restart Apache and freeside-queued + diff --git a/bin/fs-setup b/bin/fs-setup index e05d44531..87921d74e 100755 --- a/bin/fs-setup +++ b/bin/fs-setup @@ -1,6 +1,6 @@ #!/usr/bin/perl -Tw # -# $Id: fs-setup,v 1.90 2002-05-04 15:00:18 ivan Exp $ +# $Id: fs-setup,v 1.91 2002-05-15 13:24:24 ivan Exp $ #to delay loading dbdef until we're ready BEGIN { $FS::Record::setup_hack = 1; } @@ -933,6 +933,17 @@ sub tables_hash_hack { 'index' => [ [ 'jobnum' ] ], }, + 'queue_depend' => { + 'columns' => [ + 'dependnum', 'int', '', '', + 'jobnum', 'int', '', '', + 'depend_jobnum', 'int', '', '', + ], + 'primary_key' => 'dependnum', + 'unique' => [], + 'index' => [ [ 'jobnum' ], [ 'depend_jobnum' ] ], + }, + 'export_svc' => { 'columns' => [ 'exportsvcnum' => 'int', '', '', diff --git a/eg/export_template.pm b/eg/export_template.pm index f2a5a19f7..1d441bda1 100644 --- a/eg/export_template.pm +++ b/eg/export_template.pm @@ -9,8 +9,9 @@ sub rebless { shift; } sub _export_insert { my($self, $svc_something) = (shift, shift); - $self->myexport_queue( $svc_acct->svcnum, 'insert', + $err_or_queue = $self->myexport_queue( $svc_acct->svcnum, 'insert', $svc_something->username, $svc_something->_password ); + ref($err_or_queue) ? '' : $err_or_queue; } sub _export_replace { @@ -18,14 +19,16 @@ sub _export_replace { #return "can't change username with myexport" # if $old->username ne $new->username; #return '' unless $old->_password ne $new->_password; - $self->myexport_queue( $new->svcnum, + $err_or_queue = $self->myexport_queue( $new->svcnum, 'replace', $new->username, $new->_password ); + ref($err_or_queue) ? '' : $err_or_queue; } sub _export_delete { my( $self, $svc_something ) = (shift, shift); - $self->myexport_queue( $svc_acct->svcnum, + $err_or_queue = $self->myexport_queue( $svc_acct->svcnum, 'delete', $svc_something->username ); + ref($err_or_queue) ? '' : $err_or_queue; } #a good idea to queue anything that could fail or take any time @@ -35,7 +38,7 @@ sub myexport_queue { 'svcnum' => $svcnum, 'job' => "FS::part_export::myexport::myexport_$method", }; - $queue->insert( @_ ); + $queue->insert( @_ ) or $queue; } sub myexport_insert { #subroutine, not method diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html index 5c13ac10d..26fa34dd1 100644 --- a/httemplate/docs/install.html +++ b/httemplate/docs/install.html @@ -186,7 +186,7 @@ $ bin/fs-setup username $ su freeside $ bin/populate-msgcat username -
  • freeside-queued was installed with the Perl modules. Start it now and ensure that is run upon system startup. +
  • freeside-queued was installed with the Perl modules. Start it now and ensure that is run upon system startup (Do this manually, or, edit the top-level Makefile, replacing INIT_FILE with the appropriate location on your system, and run make install-init.
  • Now proceed to the initial administration of your installation. diff --git a/httemplate/docs/schema.dia b/httemplate/docs/schema.dia index 148c1dfbcd89920b16ae652f157b61e1647cad33..c22a470e013e8251ffb3260f12fd3e256426bdee 100644 GIT binary patch delta 11291 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%0DN>HbjlR3JpJiM(fFHO0^%05%Hn7V~T9? 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 delta 11062 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 RdW>F$oBrjHyt=|c{U6gKVr2jT diff --git a/httemplate/docs/schema.html b/httemplate/docs/schema.html index 3f627448f..2b8b3a132 100644 --- a/httemplate/docs/schema.html +++ b/httemplate/docs/schema.html @@ -401,6 +401,12 @@
  • jobnum - job
  • arg - argument +
  • queue_depend - job dependancies +
      +
    • dependnum - primary key +
    • jobnum - source jobnum +
    • depend_jobnum - dependancy jobnum +
  • radius_usergroup - Link users to RADIUS groups.