update indices for better tax report performance
[freeside.git] / FS / FS / Schema.pm
1 package FS::Schema;
2
3 use vars qw(@ISA @EXPORT_OK $DEBUG $setup_hack %dbdef_cache);
4 use subs qw(reload_dbdef);
5 use Exporter;
6 use DBIx::DBSchema 0.25;
7 use DBIx::DBSchema::Table;
8 use DBIx::DBSchema::Column;
9 use DBIx::DBSchema::ColGroup::Unique;
10 use DBIx::DBSchema::ColGroup::Index;
11 use FS::UID qw(datasrc);
12
13 @ISA = qw(Exporter);
14 @EXPORT_OK = qw( dbdef dbdef_dist reload_dbdef );
15
16 $DEBUG = 0;
17 $me = '[FS::Schema]';
18
19 #ask FS::UID to run this stuff for us later
20 FS::UID->install_callback( sub {
21   #$conf = new FS::Conf; 
22   &reload_dbdef("/usr/local/etc/freeside/dbdef.". datasrc)
23     unless $setup_hack; #$setup_hack needed now?
24 } );
25
26 =head1 NAME
27
28 FS::Schema - Freeside database schema
29
30 =head1 SYNOPSYS
31
32     use FS::Schema qw(dbdef dbdef_dist reload_dbdef);
33
34     $dbdef = reload_dbdef;
35     $dbdef = reload_dbdef "/non/standard/filename";
36     $dbdef = dbdef;
37     $dbdef_dist = dbdef_dist;
38
39 =head1 DESCRIPTION
40
41 This class represents the database schema.
42
43 =head1 METHODS
44
45 =over 4
46
47 =item reload_dbdef([FILENAME])
48
49 Load a database definition (see L<DBIx::DBSchema>), optionally from a
50 non-default filename.  This command is executed at startup unless
51 I<$FS::Schema::setup_hack> is true.  Returns a DBIx::DBSchema object.
52
53 =cut
54
55 sub reload_dbdef {
56   my $file = shift;
57
58   unless ( exists $dbdef_cache{$file} ) {
59     warn "[debug]$me loading dbdef for $file\n" if $DEBUG;
60     $dbdef_cache{$file} = DBIx::DBSchema->load( $file )
61                             or die "can't load database schema from $file";
62   } else {
63     warn "[debug]$me re-using cached dbdef for $file\n" if $DEBUG;
64   }
65   $dbdef = $dbdef_cache{$file};
66 }
67
68 =item dbdef
69
70 Returns the current database definition (represents the current database,
71 assuming it is up-to-date).  See L<DBIx::DBSchema>.
72
73 =cut
74
75 sub dbdef { $dbdef; }
76
77 =item dbdef_dist [ OPTION => VALUE ... ]
78
79 Returns the current canoical database definition as defined in this file.
80
81 =cut
82
83 sub dbdef_dist {
84
85   ###
86   # create a dbdef object from the old data structure
87   ###
88
89   my $tables_hashref = tables_hashref();
90
91   #turn it into objects
92   my $dbdef = new DBIx::DBSchema map {  
93     my @columns;
94     while (@{$tables_hashref->{$_}{'columns'}}) {
95       my($name, $type, $null, $length) =
96         splice @{$tables_hashref->{$_}{'columns'}}, 0, 4;
97       push @columns, new DBIx::DBSchema::Column ( $name,$type,$null,$length );
98     }
99     DBIx::DBSchema::Table->new(
100       $_,
101       $tables_hashref->{$_}{'primary_key'},
102       DBIx::DBSchema::ColGroup::Unique->new($tables_hashref->{$_}{'unique'}),
103       DBIx::DBSchema::ColGroup::Index->new($tables_hashref->{$_}{'index'}),
104       @columns,
105     );
106   } keys %$tables_hashref;
107
108   if ( $DEBUG ) {
109     warn "[debug]$me initial dbdef_dist created ($dbdef) with tables:\n";
110     warn "[debug]$me   $_\n" foreach $dbdef->tables;
111   }
112   
113   my $cust_main = $dbdef->table('cust_main');
114   #unless ($ship) { #remove ship_ from cust_main
115   #  $cust_main->delcolumn($_) foreach ( grep /^ship_/, $cust_main->columns );
116   #} else { #add indices
117     push @{$cust_main->index->lol_ref},
118       map { [ "ship_$_" ] } qw( last company daytime night fax );
119   #}
120   
121   #add radius attributes to svc_acct
122   #
123   #my($svc_acct)=$dbdef->table('svc_acct');
124   # 
125   #my($attribute);
126   #foreach $attribute (@attributes) {
127   #  $svc_acct->addcolumn ( new DBIx::DBSchema::Column (
128   #    'radius_'. $attribute,
129   #    'varchar',
130   #    'NULL',
131   #    $char_d,
132   #  ));
133   #}
134   # 
135   #foreach $attribute (@check_attributes) {
136   #  $svc_acct->addcolumn( new DBIx::DBSchema::Column (
137   #    'rc_'. $attribute,
138   #    'varchar',
139   #    'NULL',
140   #    $char_d,
141   #  ));
142   #}
143
144   #create history tables (false laziness w/create-history-tables)
145   foreach my $table (
146     grep { ! /^clientapi_session/ }
147     grep { ! /^h_/ }
148     $dbdef->tables
149   ) {
150     my $tableobj = $dbdef->table($table)
151       or die "unknown table $table";
152   
153     die "unique->lol_ref undefined for $table"
154       unless defined $tableobj->unique->lol_ref;
155     die "index->lol_ref undefined for $table"
156       unless defined $tableobj->index->lol_ref;
157   
158     my $h_tableobj = DBIx::DBSchema::Table->new( {
159       name        => "h_$table",
160       primary_key => 'historynum',
161       unique      => DBIx::DBSchema::ColGroup::Unique->new( [] ),
162       'index'     => DBIx::DBSchema::ColGroup::Index->new( [
163                        @{$tableobj->unique->lol_ref},
164                        @{$tableobj->index->lol_ref}
165                      ] ),
166       columns     => [
167                        DBIx::DBSchema::Column->new( {
168                          'name'    => 'historynum',
169                          'type'    => 'serial',
170                          'null'    => 'NOT NULL',
171                          'length'  => '',
172                          'default' => '',
173                          'local'   => '',
174                        } ),
175                        DBIx::DBSchema::Column->new( {
176                          'name'    => 'history_date',
177                          'type'    => 'int',
178                          'null'    => 'NULL',
179                          'length'  => '',
180                          'default' => '',
181                          'local'   => '',
182                        } ),
183                        DBIx::DBSchema::Column->new( {
184                          'name'    => 'history_user',
185                          'type'    => 'varchar',
186                          'null'    => 'NOT NULL',
187                          'length'  => '80',
188                          'default' => '',
189                          'local'   => '',
190                        } ),
191                        DBIx::DBSchema::Column->new( {
192                          'name'    => 'history_action',
193                          'type'    => 'varchar',
194                          'null'    => 'NOT NULL',
195                          'length'  => '80',
196                          'default' => '',
197                          'local'   => '',
198                        } ),
199                        map {
200                          my $column = $tableobj->column($_);
201   
202                          #clone so as to not disturb the original
203                          $column = DBIx::DBSchema::Column->new( {
204                            map { $_ => $column->$_() }
205                              qw( name type null length default local )
206                          } );
207   
208                          if ( $column->type eq 'serial' ) {
209                            $column->type('int');
210                            $column->null('NULL');
211                          }
212                          #$column->default('')
213                          #  if $column->default =~ /^nextval\(/i;
214                          #( my $local = $column->local ) =~ s/AUTO_INCREMENT//i;
215                          #$column->local($local);
216                          $column;
217                        } $tableobj->columns
218                      ],
219     } );
220     $dbdef->addtable($h_tableobj);
221   }
222
223   $dbdef;
224
225 }
226
227 sub tables_hashref {
228
229   my $char_d = 80; #default maxlength for text fields
230
231   #my(@date_type)  = ( 'timestamp', '', ''     );
232   my @date_type  = ( 'int', 'NULL', ''     );
233   my @perl_type = ( 'text', 'NULL', ''  ); 
234   my @money_type = ( 'decimal',   '', '10,2' );
235
236   my $username_len = 32; #usernamemax config file
237
238   return {
239
240     'agent' => {
241       'columns' => [
242         'agentnum', 'serial',            '',     '',
243         'agent',    'varchar',           '',     $char_d,
244         'typenum',  'int',            '',     '',
245         'freq',     'int',       'NULL', '',
246         'prog',     @perl_type,
247         'disabled',     'char', 'NULL', 1,
248         'username', 'varchar',       'NULL',     $char_d,
249         '_password','varchar',       'NULL',     $char_d,
250         'ticketing_queueid', 'int', 'NULL', '',
251       ],
252       'primary_key' => 'agentnum',
253       'unique' => [],
254       'index' => [ ['typenum'], ['disabled'] ],
255     },
256
257     'agent_type' => {
258       'columns' => [
259         'typenum',   'serial',  '', '',
260         'atype',     'varchar', '', $char_d,
261       ],
262       'primary_key' => 'typenum',
263       'unique' => [],
264       'index' => [],
265     },
266
267     'type_pkgs' => {
268       'columns' => [
269         'typepkgnum', 'serial', '', '',
270         'typenum',   'int',  '', '',
271         'pkgpart',   'int',  '', '',
272       ],
273       'primary_key' => 'typepkgnum',
274       'unique' => [ ['typenum', 'pkgpart'] ],
275       'index' => [ ['typenum'] ],
276     },
277
278     'cust_bill' => {
279       'columns' => [
280         'invnum',    'serial',  '', '',
281         'custnum',   'int',  '', '',
282         '_date',     @date_type,
283         'charged',   @money_type,
284         'printed',   'int',  '', '',
285         'closed',    'char', 'NULL', 1,
286       ],
287       'primary_key' => 'invnum',
288       'unique' => [],
289       'index' => [ ['custnum'], ['_date'] ],
290     },
291
292     'cust_bill_event' => {
293       'columns' => [
294         'eventnum',    'serial',  '', '',
295         'invnum',   'int',  '', '',
296         'eventpart',   'int',  '', '',
297         '_date',     @date_type,
298         'status', 'varchar', '', $char_d,
299         'statustext', 'text', 'NULL', '',
300       ],
301       'primary_key' => 'eventnum',
302       #no... there are retries now #'unique' => [ [ 'eventpart', 'invnum' ] ],
303       'unique' => [],
304       'index' => [ ['invnum'], ['status'] ],
305     },
306
307     'part_bill_event' => {
308       'columns' => [
309         'eventpart',    'serial',  '', '',
310         'payby',       'char',  '', 4,
311         'event',       'varchar',           '',     $char_d,
312         'eventcode',    @perl_type,
313         'seconds',     'int', 'NULL', '',
314         'weight',      'int', '', '',
315         'plan',       'varchar', 'NULL', $char_d,
316         'plandata',   'text', 'NULL', '',
317         'disabled',     'char', 'NULL', 1,
318       ],
319       'primary_key' => 'eventpart',
320       'unique' => [],
321       'index' => [ ['payby'], ['disabled'], ],
322     },
323
324     'cust_bill_pkg' => {
325       'columns' => [
326         'billpkgnum', 'serial', '', '',
327         'pkgnum',  'int', '', '',
328         'invnum',  'int', '', '',
329         'setup',   @money_type,
330         'recur',   @money_type,
331         'sdate',   @date_type,
332         'edate',   @date_type,
333         'itemdesc', 'varchar', 'NULL', $char_d,
334       ],
335       'primary_key' => 'billpkgnum',
336       'unique' => [],
337       'index' => [ ['invnum'], [ 'pkgnum' ] ],
338     },
339
340     'cust_bill_pkg_detail' => {
341       'columns' => [
342         'detailnum', 'serial', '', '',
343         'pkgnum',  'int', '', '',
344         'invnum',  'int', '', '',
345         'detail',  'varchar', '', $char_d,
346       ],
347       'primary_key' => 'detailnum',
348       'unique' => [],
349       'index' => [ [ 'pkgnum', 'invnum' ] ],
350     },
351
352     'cust_credit' => {
353       'columns' => [
354         'crednum',  'serial', '', '',
355         'custnum',  'int', '', '',
356         '_date',    @date_type,
357         'amount',   @money_type,
358         'otaker',   'varchar', '', 32,
359         'reason',   'text', 'NULL', '',
360         'closed',    'char', 'NULL', 1,
361       ],
362       'primary_key' => 'crednum',
363       'unique' => [],
364       'index' => [ ['custnum'] ],
365     },
366
367     'cust_credit_bill' => {
368       'columns' => [
369         'creditbillnum', 'serial', '', '',
370         'crednum',  'int', '', '',
371         'invnum',  'int', '', '',
372         '_date',    @date_type,
373         'amount',   @money_type,
374       ],
375       'primary_key' => 'creditbillnum',
376       'unique' => [],
377       'index' => [ ['crednum'], ['invnum'] ],
378     },
379
380     'cust_main' => {
381       'columns' => [
382         'custnum',  'serial',  '',     '',
383         'agentnum', 'int',  '',     '',
384 #        'titlenum', 'int',  'NULL',   '',
385         'last',     'varchar', '',     $char_d,
386 #        'middle',   'varchar', 'NULL', $char_d,
387         'first',    'varchar', '',     $char_d,
388         'ss',       'varchar', 'NULL', 11,
389         'company',  'varchar', 'NULL', $char_d,
390         'address1', 'varchar', '',     $char_d,
391         'address2', 'varchar', 'NULL', $char_d,
392         'city',     'varchar', '',     $char_d,
393         'county',   'varchar', 'NULL', $char_d,
394         'state',    'varchar', 'NULL', $char_d,
395         'zip',      'varchar', 'NULL', 10,
396         'country',  'char', '',     2,
397         'daytime',  'varchar', 'NULL', 20,
398         'night',    'varchar', 'NULL', 20,
399         'fax',      'varchar', 'NULL', 12,
400         'ship_last',     'varchar', 'NULL', $char_d,
401 #        'ship_middle',   'varchar', 'NULL', $char_d,
402         'ship_first',    'varchar', 'NULL', $char_d,
403         'ship_company',  'varchar', 'NULL', $char_d,
404         'ship_address1', 'varchar', 'NULL', $char_d,
405         'ship_address2', 'varchar', 'NULL', $char_d,
406         'ship_city',     'varchar', 'NULL', $char_d,
407         'ship_county',   'varchar', 'NULL', $char_d,
408         'ship_state',    'varchar', 'NULL', $char_d,
409         'ship_zip',      'varchar', 'NULL', 10,
410         'ship_country',  'char', 'NULL', 2,
411         'ship_daytime',  'varchar', 'NULL', 20,
412         'ship_night',    'varchar', 'NULL', 20,
413         'ship_fax',      'varchar', 'NULL', 12,
414         'payby',    'char', '',     4,
415         'payinfo',  'varchar', 'NULL', 512,
416         'paycvv',   'varchar', 'NULL', 512,
417         'paymask', 'varchar', 'NULL', $char_d,
418         #'paydate',  @date_type,
419         'paydate',  'varchar', 'NULL', 10,
420         'paystart_month', 'int', 'NULL', '',
421         'paystart_year',  'int', 'NULL', '',
422         'payissue', 'varchar', 'NULL', 2,
423         'payname',  'varchar', 'NULL', $char_d,
424         'payip',    'varchar', 'NULL', 15,
425         'tax',      'char', 'NULL', 1,
426         'otaker',   'varchar', '',    32,
427         'refnum',   'int',  '',     '',
428         'referral_custnum', 'int',  'NULL', '',
429         'comments', 'text', 'NULL', '',
430       ],
431       'primary_key' => 'custnum',
432       'unique' => [],
433       #'index' => [ ['last'], ['company'] ],
434       'index' => [ ['last'], [ 'company' ], [ 'referral_custnum' ],
435                    [ 'daytime' ], [ 'night' ], [ 'fax' ], [ 'refnum' ],
436                    [ 'ship_last' ], [ 'ship_company' ],
437                    [ 'county' ], [ 'state' ], [ 'country' ]
438                  ],
439     },
440
441     'cust_main_invoice' => {
442       'columns' => [
443         'destnum',  'serial',  '',     '',
444         'custnum',  'int',  '',     '',
445         'dest',     'varchar', '',  $char_d,
446       ],
447       'primary_key' => 'destnum',
448       'unique' => [],
449       'index' => [ ['custnum'], ],
450     },
451
452     'cust_main_county' => { #county+state+country are checked off the
453                             #cust_main_county for validation and to provide
454                             # a tax rate.
455       'columns' => [
456         'taxnum',   'serial',   '',    '',
457         'state',    'varchar',  'NULL',    $char_d,
458         'county',   'varchar',  'NULL',    $char_d,
459         'country',  'char',  '', 2, 
460         'taxclass',   'varchar', 'NULL', $char_d,
461         'exempt_amount', @money_type,
462         'tax',      'real',  '',    '', #tax %
463         'taxname',  'varchar',  'NULL',    $char_d,
464         'setuptax',  'char', 'NULL', 1, # Y = setup tax exempt
465         'recurtax',  'char', 'NULL', 1, # Y = recur tax exempt
466       ],
467       'primary_key' => 'taxnum',
468       'unique' => [],
469   #    'unique' => [ ['taxnum'], ['state', 'county'] ],
470       'index' => [ [ 'county' ], [ 'state' ], [ 'country' ] ],
471     },
472
473     'cust_pay' => {
474       'columns' => [
475         'paynum',   'serial',    '',   '',
476         #now cust_bill_pay #'invnum',   'int',    '',   '',
477         'custnum',  'int',    '',   '',
478         'paid',     @money_type,
479         '_date',    @date_type,
480         'payby',    'char',   '',     4, # CARD/BILL/COMP, should be index into
481                                          # payment type table.
482         'payinfo',  'varchar',   'NULL', $char_d,  #see cust_main above
483         'paybatch', 'varchar',   'NULL', $char_d, #for auditing purposes.
484         'closed',    'char', 'NULL', 1,
485       ],
486       'primary_key' => 'paynum',
487       'unique' => [],
488       'index' => [ [ 'custnum' ], [ 'paybatch' ], [ 'payby' ], [ '_date' ] ],
489     },
490
491     'cust_pay_void' => {
492       'columns' => [
493         'paynum',    'int',    '',   '',
494         'custnum',   'int',    '',   '',
495         'paid',      @money_type,
496         '_date',     @date_type,
497         'payby',     'char',   '',     4, # CARD/BILL/COMP, should be index into
498                                           # payment type table.
499         'payinfo',   'varchar',   'NULL', $char_d,  #see cust_main above
500         'paybatch',  'varchar',   'NULL', $char_d, #for auditing purposes.
501         'closed',    'char', 'NULL', 1,
502         'void_date', @date_type,
503         'reason',    'varchar',   'NULL', $char_d,
504         'otaker',   'varchar', '', 32,
505       ],
506       'primary_key' => 'paynum',
507       'unique' => [],
508       'index' => [ [ 'custnum' ] ],
509     },
510
511     'cust_bill_pay' => {
512       'columns' => [
513         'billpaynum', 'serial',     '',   '',
514         'invnum',  'int',     '',   '',
515         'paynum',  'int',     '',   '',
516         'amount',  @money_type,
517         '_date',   @date_type
518       ],
519       'primary_key' => 'billpaynum',
520       'unique' => [],
521       'index' => [ [ 'paynum' ], [ 'invnum' ] ],
522     },
523
524     'cust_pay_batch' => { #what's this used for again?  list of customers
525                           #in current CARD batch? (necessarily CARD?)
526       'columns' => [
527         'paybatchnum',   'serial',    '',   '',
528         'invnum',   'int',    '',   '',
529         'custnum',   'int',    '',   '',
530         'last',     'varchar', '',     $char_d,
531         'first',    'varchar', '',     $char_d,
532         'address1', 'varchar', '',     $char_d,
533         'address2', 'varchar', 'NULL', $char_d,
534         'city',     'varchar', '',     $char_d,
535         'state',    'varchar', 'NULL', $char_d,
536         'zip',      'varchar', 'NULL', 10,
537         'country',  'char', '',     2,
538 #        'trancode', 'int', '', '',
539         'cardnum',  'varchar', '',     16,
540         #'exp',      @date_type,
541         'exp',      'varchar', '',     11,
542         'payname',  'varchar', 'NULL', $char_d,
543         'amount',   @money_type,
544       ],
545       'primary_key' => 'paybatchnum',
546       'unique' => [],
547       'index' => [ ['invnum'], ['custnum'] ],
548     },
549
550     'cust_pkg' => {
551       'columns' => [
552         'pkgnum',    'serial',    '',   '',
553         'custnum',   'int',    '',   '',
554         'pkgpart',   'int',    '',   '',
555         'otaker',    'varchar', '', 32,
556         'setup',     @date_type,
557         'bill',      @date_type,
558         'last_bill', @date_type,
559         'susp',      @date_type,
560         'cancel',    @date_type,
561         'expire',    @date_type,
562         'manual_flag', 'char', 'NULL', 1,
563       ],
564       'primary_key' => 'pkgnum',
565       'unique' => [],
566       'index' => [ ['custnum'], ['pkgpart'] ],
567     },
568
569     'cust_refund' => {
570       'columns' => [
571         'refundnum',    'serial',    '',   '',
572         #now cust_credit_refund #'crednum',      'int',    '',   '',
573         'custnum',  'int',    '',   '',
574         '_date',        @date_type,
575         'refund',       @money_type,
576         'otaker',       'varchar',   '',   32,
577         'reason',       'varchar',   '',   $char_d,
578         'payby',        'char',   '',     4, # CARD/BILL/COMP, should be index
579                                              # into payment type table.
580         'payinfo',      'varchar',   'NULL', $char_d,  #see cust_main above
581         'paybatch',     'varchar',   'NULL', $char_d,
582         'closed',    'char', 'NULL', 1,
583       ],
584       'primary_key' => 'refundnum',
585       'unique' => [],
586       'index' => [],
587     },
588
589     'cust_credit_refund' => {
590       'columns' => [
591         'creditrefundnum', 'serial',     '',   '',
592         'crednum',  'int',     '',   '',
593         'refundnum',  'int',     '',   '',
594         'amount',  @money_type,
595         '_date',   @date_type
596       ],
597       'primary_key' => 'creditrefundnum',
598       'unique' => [],
599       'index' => [ [ 'crednum', 'refundnum' ] ],
600     },
601
602
603     'cust_svc' => {
604       'columns' => [
605         'svcnum',    'serial',    '',   '',
606         'pkgnum',    'int',    'NULL',   '',
607         'svcpart',   'int',    '',   '',
608       ],
609       'primary_key' => 'svcnum',
610       'unique' => [],
611       'index' => [ ['svcnum'], ['pkgnum'], ['svcpart'] ],
612     },
613
614     'part_pkg' => {
615       'columns' => [
616         'pkgpart',    'serial',    '',   '',
617         'pkg',        'varchar',   '',   $char_d,
618         'comment',    'varchar',   '',   $char_d,
619         'promo_code', 'varchar', 'NULL', $char_d,
620         'setup',      @perl_type,
621         'freq',       'varchar',   '',   $char_d,  #billing frequency
622         'recur',      @perl_type,
623         'setuptax',  'char', 'NULL', 1,
624         'recurtax',  'char', 'NULL', 1,
625         'plan',       'varchar', 'NULL', $char_d,
626         'plandata',   'text', 'NULL', '',
627         'disabled',   'char', 'NULL', 1,
628         'taxclass',   'varchar', 'NULL', $char_d,
629       ],
630       'primary_key' => 'pkgpart',
631       'unique' => [],
632       'index' => [ [ 'promo_code' ], [ 'disabled' ] ],
633     },
634
635 #    'part_title' => {
636 #      'columns' => [
637 #        'titlenum',   'int',    '',   '',
638 #        'title',      'varchar',   '',   $char_d,
639 #      ],
640 #      'primary_key' => 'titlenum',
641 #      'unique' => [ [] ],
642 #      'index' => [ [] ],
643 #    },
644
645     'pkg_svc' => {
646       'columns' => [
647         'pkgsvcnum',  'serial', '',  '',
648         'pkgpart',    'int',    '',   '',
649         'svcpart',    'int',    '',   '',
650         'quantity',   'int',    '',   '',
651         'primary_svc','char', 'NULL',  1,
652       ],
653       'primary_key' => 'pkgsvcnum',
654       'unique' => [ ['pkgpart', 'svcpart'] ],
655       'index' => [ ['pkgpart'] ],
656     },
657
658     'part_referral' => {
659       'columns' => [
660         'refnum',   'serial',    '',   '',
661         'referral', 'varchar',   '',   $char_d,
662         'disabled',     'char', 'NULL', 1,
663       ],
664       'primary_key' => 'refnum',
665       'unique' => [],
666       'index' => [ ['disabled'] ],
667     },
668
669     'part_svc' => {
670       'columns' => [
671         'svcpart',    'serial',    '',   '',
672         'svc',        'varchar',   '',   $char_d,
673         'svcdb',      'varchar',   '',   $char_d,
674         'disabled',   'char',  'NULL',   1,
675       ],
676       'primary_key' => 'svcpart',
677       'unique' => [],
678       'index' => [ [ 'disabled' ] ],
679     },
680
681     'part_svc_column' => {
682       'columns' => [
683         'columnnum',   'serial',         '', '',
684         'svcpart',     'int',         '', '',
685         'columnname',  'varchar',     '', 64,
686         'columnvalue', 'varchar', 'NULL', $char_d,
687         'columnflag',  'char',    'NULL', 1, 
688       ],
689       'primary_key' => 'columnnum',
690       'unique' => [ [ 'svcpart', 'columnname' ] ],
691       'index' => [ [ 'svcpart' ] ],
692     },
693
694     #(this should be renamed to part_pop)
695     'svc_acct_pop' => {
696       'columns' => [
697         'popnum',    'serial',    '',   '',
698         'city',      'varchar',   '',   $char_d,
699         'state',     'varchar',   '',   $char_d,
700         'ac',        'char',   '',   3,
701         'exch',      'char',   '',   3,
702         'loc',       'char',   'NULL',   4, #NULL for legacy purposes
703       ],
704       'primary_key' => 'popnum',
705       'unique' => [],
706       'index' => [ [ 'state' ] ],
707     },
708
709     'part_pop_local' => {
710       'columns' => [
711         'localnum',  'serial',     '',     '',
712         'popnum',    'int',     '',     '',
713         'city',      'varchar', 'NULL', $char_d,
714         'state',     'char',    'NULL', 2,
715         'npa',       'char',    '',     3,
716         'nxx',       'char',    '',     3,
717       ],
718       'primary_key' => 'localnum',
719       'unique' => [],
720       'index' => [ [ 'npa', 'nxx' ], [ 'popnum' ] ],
721     },
722
723     'svc_acct' => {
724       'columns' => [
725         'svcnum',    'int',    '',   '',
726         'username',  'varchar',   '',   $username_len, #unique (& remove dup code)
727         '_password', 'varchar',   '',   72, #13 for encryped pw's plus ' *SUSPENDED* (md5 passwords can be 34, blowfish 60)
728         'sec_phrase', 'varchar',  'NULL',   $char_d,
729         'popnum',    'int',    'NULL',   '',
730         'uid',       'int', 'NULL',   '',
731         'gid',       'int', 'NULL',   '',
732         'finger',    'varchar',   'NULL',   $char_d,
733         'dir',       'varchar',   'NULL',   $char_d,
734         'shell',     'varchar',   'NULL',   $char_d,
735         'quota',     'varchar',   'NULL',   $char_d,
736         'slipip',    'varchar',   'NULL',   15, #four TINYINTs, bah.
737         'seconds',   'int', 'NULL',   '', #uhhhh
738         'domsvc',    'int', '',   '',
739       ],
740       'primary_key' => 'svcnum',
741       #'unique' => [ [ 'username', 'domsvc' ] ],
742       'unique' => [],
743       'index' => [ ['username'], ['domsvc'] ],
744     },
745
746     #'svc_charge' => {
747     #  'columns' => [
748     #    'svcnum',    'int',    '',   '',
749     #    'amount',    @money_type,
750     #  ],
751     #  'primary_key' => 'svcnum',
752     #  'unique' => [ [] ],
753     #  'index' => [ [] ],
754     #},
755
756     'svc_domain' => {
757       'columns' => [
758         'svcnum',    'int',    '',   '',
759         'domain',    'varchar',    '',   $char_d,
760         'catchall',  'int', 'NULL',    '',
761       ],
762       'primary_key' => 'svcnum',
763       'unique' => [ ['domain'] ],
764       'index' => [],
765     },
766
767     'domain_record' => {
768       'columns' => [
769         'recnum',    'serial',     '',  '',
770         'svcnum',    'int',     '',  '',
771         #'reczone',   'varchar', '',  $char_d,
772         'reczone',   'varchar', '',  255,
773         'recaf',     'char',    '',  2,
774         'rectype',   'varchar',    '',  5,
775         #'recdata',   'varchar', '',  $char_d,
776         'recdata',   'varchar', '',  255,
777       ],
778       'primary_key' => 'recnum',
779       'unique'      => [],
780       'index'       => [ ['svcnum'] ],
781     },
782
783     'svc_forward' => {
784       'columns' => [
785         'svcnum',   'int',            '',   '',
786         'srcsvc',   'int',        'NULL',   '',
787         'src',      'varchar',    'NULL',  255,
788         'dstsvc',   'int',        'NULL',   '',
789         'dst',      'varchar',    'NULL',  255,
790       ],
791       'primary_key' => 'svcnum',
792       'unique'      => [],
793       'index'       => [ ['srcsvc'], ['dstsvc'] ],
794     },
795
796     'svc_www' => {
797       'columns' => [
798         'svcnum',   'int',    '',  '',
799         'recnum',   'int',    '',  '',
800         'usersvc',  'int',    '',  '',
801       ],
802       'primary_key' => 'svcnum',
803       'unique'      => [],
804       'index'       => [],
805     },
806
807     #'svc_wo' => {
808     #  'columns' => [
809     #    'svcnum',    'int',    '',   '',
810     #    'svcnum',    'int',    '',   '',
811     #    'svcnum',    'int',    '',   '',
812     #    'worker',    'varchar',   '',   $char_d,
813     #    '_date',     @date_type,
814     #  ],
815     #  'primary_key' => 'svcnum',
816     #  'unique' => [ [] ],
817     #  'index' => [ [] ],
818     #},
819
820     'prepay_credit' => {
821       'columns' => [
822         'prepaynum',   'serial',     '',   '',
823         'identifier',  'varchar', '', $char_d,
824         'amount',      @money_type,
825         'seconds',     'int',     'NULL', '',
826         'agentnum',    'int',     'NULL', '',
827       ],
828       'primary_key' => 'prepaynum',
829       'unique'      => [ ['identifier'] ],
830       'index'       => [],
831     },
832
833     'port' => {
834       'columns' => [
835         'portnum',  'serial',     '',   '',
836         'ip',       'varchar', 'NULL', 15,
837         'nasport',  'int',     'NULL', '',
838         'nasnum',   'int',     '',   '',
839       ],
840       'primary_key' => 'portnum',
841       'unique'      => [],
842       'index'       => [],
843     },
844
845     'nas' => {
846       'columns' => [
847         'nasnum',   'serial',     '',    '',
848         'nas',      'varchar', '',    $char_d,
849         'nasip',    'varchar', '',    15,
850         'nasfqdn',  'varchar', '',    $char_d,
851         'last',     'int',     '',    '',
852       ],
853       'primary_key' => 'nasnum',
854       'unique'      => [ [ 'nas' ], [ 'nasip' ] ],
855       'index'       => [ [ 'last' ] ],
856     },
857
858     'session' => {
859       'columns' => [
860         'sessionnum', 'serial',       '',   '',
861         'portnum',    'int',       '',   '',
862         'svcnum',     'int',       '',   '',
863         'login',      @date_type,
864         'logout',     @date_type,
865       ],
866       'primary_key' => 'sessionnum',
867       'unique'      => [],
868       'index'       => [ [ 'portnum' ] ],
869     },
870
871     'queue' => {
872       'columns' => [
873         'jobnum', 'serial', '', '',
874         'job', 'text', '', '',
875         '_date', 'int', '', '',
876         'status', 'varchar', '', $char_d,
877         'statustext', 'text', 'NULL', '',
878         'svcnum', 'int', 'NULL', '',
879       ],
880       'primary_key' => 'jobnum',
881       'unique'      => [],
882       'index'       => [ [ 'svcnum' ], [ 'status' ] ],
883     },
884
885     'queue_arg' => {
886       'columns' => [
887         'argnum', 'serial', '', '',
888         'jobnum', 'int', '', '',
889         'arg', 'text', 'NULL', '',
890       ],
891       'primary_key' => 'argnum',
892       'unique'      => [],
893       'index'       => [ [ 'jobnum' ] ],
894     },
895
896     'queue_depend' => {
897       'columns' => [
898         'dependnum', 'serial', '', '',
899         'jobnum', 'int', '', '',
900         'depend_jobnum', 'int', '', '',
901       ],
902       'primary_key' => 'dependnum',
903       'unique'      => [],
904       'index'       => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
905     },
906
907     'export_svc' => {
908       'columns' => [
909         'exportsvcnum' => 'serial', '', '',
910         'exportnum'    => 'int', '', '',
911         'svcpart'      => 'int', '', '',
912       ],
913       'primary_key' => 'exportsvcnum',
914       'unique'      => [ [ 'exportnum', 'svcpart' ] ],
915       'index'       => [ [ 'exportnum' ], [ 'svcpart' ] ],
916     },
917
918     'part_export' => {
919       'columns' => [
920         'exportnum', 'serial', '', '',
921         #'svcpart',   'int', '', '',
922         'machine', 'varchar', '', $char_d,
923         'exporttype', 'varchar', '', $char_d,
924         'nodomain',     'char', 'NULL', 1,
925       ],
926       'primary_key' => 'exportnum',
927       'unique'      => [],
928       'index'       => [ [ 'machine' ], [ 'exporttype' ] ],
929     },
930
931     'part_export_option' => {
932       'columns' => [
933         'optionnum', 'serial', '', '',
934         'exportnum', 'int', '', '',
935         'optionname', 'varchar', '', $char_d,
936         'optionvalue', 'text', 'NULL', '',
937       ],
938       'primary_key' => 'optionnum',
939       'unique'      => [],
940       'index'       => [ [ 'exportnum' ], [ 'optionname' ] ],
941     },
942
943     'radius_usergroup' => {
944       'columns' => [
945         'usergroupnum', 'serial', '', '',
946         'svcnum',       'int', '', '',
947         'groupname',    'varchar', '', $char_d,
948       ],
949       'primary_key' => 'usergroupnum',
950       'unique'      => [],
951       'index'       => [ [ 'svcnum' ], [ 'groupname' ] ],
952     },
953
954     'msgcat' => {
955       'columns' => [
956         'msgnum', 'serial', '', '',
957         'msgcode', 'varchar', '', $char_d,
958         'locale', 'varchar', '', 16,
959         'msg', 'text', '', '',
960       ],
961       'primary_key' => 'msgnum',
962       'unique'      => [ [ 'msgcode', 'locale' ] ],
963       'index'       => [],
964     },
965
966     'cust_tax_exempt' => {
967       'columns' => [
968         'exemptnum', 'serial', '', '',
969         'custnum',   'int', '', '',
970         'taxnum',    'int', '', '',
971         'year',      'int', '', '',
972         'month',     'int', '', '',
973         'amount',   @money_type,
974       ],
975       'primary_key' => 'exemptnum',
976       'unique'      => [ [ 'custnum', 'taxnum', 'year', 'month' ] ],
977       'index'       => [],
978     },
979
980     'router' => {
981       'columns' => [
982         'routernum', 'serial', '', '',
983         'routername', 'varchar', '', $char_d,
984         'svcnum', 'int', 'NULL', '',
985       ],
986       'primary_key' => 'routernum',
987       'unique'      => [],
988       'index'       => [],
989     },
990
991     'part_svc_router' => {
992       'columns' => [
993         'svcrouternum', 'serial', '', '',
994         'svcpart', 'int', '', '',
995         'routernum', 'int', '', '',
996       ],
997       'primary_key' => 'svcrouternum',
998       'unique'      => [],
999       'index'       => [],
1000     },
1001
1002     'addr_block' => {
1003       'columns' => [
1004         'blocknum', 'serial', '', '',
1005         'routernum', 'int', '', '',
1006         'ip_gateway', 'varchar', '', 15,
1007         'ip_netmask', 'int', '', '',
1008       ],
1009       'primary_key' => 'blocknum',
1010       'unique'      => [ [ 'blocknum', 'routernum' ] ],
1011       'index'       => [],
1012     },
1013
1014     'svc_broadband' => {
1015       'columns' => [
1016         'svcnum', 'int', '', '',
1017         'blocknum', 'int', '', '',
1018         'speed_up', 'int', '', '',
1019         'speed_down', 'int', '', '',
1020         'ip_addr', 'varchar', '', 15,
1021       ],
1022       'primary_key' => 'svcnum',
1023       'unique'      => [],
1024       'index'       => [],
1025     },
1026
1027     'part_virtual_field' => {
1028       'columns' => [
1029         'vfieldpart', 'int', '', '',
1030         'dbtable', 'varchar', '', 32,
1031         'name', 'varchar', '', 32,
1032         'check_block', 'text', 'NULL', '',
1033         'length', 'int', 'NULL', '',
1034         'list_source', 'text', 'NULL', '',
1035         'label', 'varchar', 'NULL', 80,
1036       ],
1037       'primary_key' => 'vfieldpart',
1038       'unique' => [],
1039       'index' => [],
1040     },
1041
1042     'virtual_field' => {
1043       'columns' => [
1044         'vfieldnum', 'serial', '', '',
1045         'recnum', 'int', '', '',
1046         'vfieldpart', 'int', '', '',
1047         'value', 'varchar', '', 128,
1048       ],
1049       'primary_key' => 'vfieldnum',
1050       'unique' => [ [ 'vfieldpart', 'recnum' ] ],
1051       'index' => [],
1052     },
1053
1054     'acct_snarf' => {
1055       'columns' => [
1056         'snarfnum',  'int', '', '',
1057         'svcnum',    'int', '', '',
1058         'machine',   'varchar', '', 255,
1059         'protocol',  'varchar', '', $char_d,
1060         'username',  'varchar', '', $char_d,
1061         '_password', 'varchar', '', $char_d,
1062       ],
1063       'primary_key' => 'snarfnum',
1064       'unique' => [],
1065       'index'  => [ [ 'svcnum' ] ],
1066     },
1067
1068     'svc_external' => {
1069       'columns' => [
1070         'svcnum', 'int', '', '',
1071         'id',     'int', 'NULL', '',
1072         'title',  'varchar', 'NULL', $char_d,
1073       ],
1074       'primary_key' => 'svcnum',
1075       'unique'      => [],
1076       'index'       => [],
1077     },
1078
1079     'cust_pay_refund' => {
1080       'columns' => [
1081         'payrefundnum', 'serial', '', '',
1082         'paynum',  'int', '', '',
1083         'refundnum',  'int', '', '',
1084         '_date',    @date_type,
1085         'amount',   @money_type,
1086       ],
1087       'primary_key' => 'payrefundnum',
1088       'unique' => [],
1089       'index' => [ ['paynum'], ['refundnum'] ],
1090     },
1091
1092     'part_pkg_option' => {
1093       'columns' => [
1094         'optionnum', 'serial', '', '',
1095         'pkgpart', 'int', '', '',
1096         'optionname', 'varchar', '', $char_d,
1097         'optionvalue', 'text', 'NULL', '',
1098       ],
1099       'primary_key' => 'optionnum',
1100       'unique'      => [],
1101       'index'       => [ [ 'pkgpart' ], [ 'optionname' ] ],
1102     },
1103
1104     'rate' => {
1105       'columns' => [
1106         'ratenum',  'serial', '', '',
1107         'ratename', 'varchar', '', $char_d,
1108       ],
1109       'primary_key' => 'ratenum',
1110       'unique'      => [],
1111       'index'       => [],
1112     },
1113
1114     'rate_detail' => {
1115       'columns' => [
1116         'ratedetailnum',   'serial', '', '',
1117         'ratenum',         'int',     '', '',
1118         'orig_regionnum',  'int', 'NULL', '',
1119         'dest_regionnum',  'int',     '', '',
1120         'min_included',    'int',     '', '',
1121         'min_charge',      @money_type,
1122         'sec_granularity', 'int',     '', '',
1123         #time period (link to table of periods)?
1124       ],
1125       'primary_key' => 'ratedetailnum',
1126       'unique'      => [ [ 'ratenum', 'orig_regionnum', 'dest_regionnum' ] ],
1127       'index'       => [ [ 'ratenum', 'dest_regionnum' ] ],
1128     },
1129
1130     'rate_region' => {
1131       'columns' => [
1132         'regionnum',   'serial',      '', '',
1133         'regionname',  'varchar',     '', $char_d,
1134       ],
1135       'primary_key' => 'regionnum',
1136       'unique'      => [],
1137       'index'       => [],
1138     },
1139
1140     'rate_prefix' => {
1141       'columns' => [
1142         'prefixnum',   'serial',    '', '',
1143         'regionnum',   'int',       '', '',,
1144         'countrycode', 'varchar',     '', 3,
1145         'npa',         'varchar', 'NULL', 6,
1146         'nxx',         'varchar', 'NULL', 3,
1147       ],
1148       'primary_key' => 'prefixnum',
1149       'unique'      => [],
1150       'index'       => [ [ 'countrycode' ], [ 'regionnum' ] ],
1151     },
1152
1153     'reg_code' => {
1154       'columns' => [
1155         'codenum',   'serial',    '', '',
1156         'code',      'varchar',   '', $char_d,
1157         'agentnum',  'int',       '', '',
1158       ],
1159       'primary_key' => 'codenum',
1160       'unique'      => [ [ 'agentnum', 'code' ] ],
1161       'index'       => [ [ 'agentnum' ] ],
1162     },
1163
1164     'reg_code_pkg' => {
1165       'columns' => [
1166         'codepkgnum', 'serial', '', '',
1167         'codenum',   'int',    '', '',
1168         'pkgpart',   'int',    '', '',
1169       ],
1170       'primary_key' => 'codepkgnum',
1171       'unique'      => [ [ 'codenum', 'pkgpart' ] ],
1172       'index'       => [ [ 'codenum' ] ],
1173     },
1174
1175     'clientapi_session' => {
1176       'columns' => [
1177         'sessionnum',  'serial',  '', '',
1178         'sessionid',  'varchar',  '', $char_d,
1179         'namespace',  'varchar',  '', $char_d,
1180       ],
1181       'primary_key' => 'sessionnum',
1182       'unique'      => [ [ 'sessionid', 'namespace' ] ],
1183       'index'       => [],
1184     },
1185
1186     'clientapi_session_field' => {
1187       'columns' => [
1188         'fieldnum',    'serial',     '', '',
1189         'sessionnum',     'int',     '', '',
1190         'fieldname',  'varchar',     '', $char_d,
1191         'fieldvalue',    'text', 'NULL', '',
1192       ],
1193       'primary_key' => 'fieldnum',
1194       'unique'      => [ [ 'sessionnum', 'fieldname' ] ],
1195       'index'       => [],
1196     },
1197
1198     'payment_gateway' => {
1199       'columns' => [
1200         'gatewaynum',       'serial',   '',     '',
1201         'gateway_module',   'varchar',  '',     $char_d,
1202         'gateway_username', 'varchar',  'NULL', $char_d,
1203         'gateway_password', 'varchar',  'NULL', $char_d,
1204         'gateway_action',   'varchar',  'NULL', $char_d,
1205         'disabled',   'char',  'NULL',   1,
1206       ],
1207       'primary_key' => 'gatewaynum',
1208       'unique' => [],
1209       'index'  => [ [ 'disabled' ] ],
1210     },
1211
1212     'payment_gateway_option' => {
1213       'columns' => [
1214         'optionnum',   'serial',  '',     '',
1215         'gatewaynum',  'int',     '',     '',
1216         'optionname',  'varchar', '',     $char_d,
1217         'optionvalue', 'text',    'NULL', '',
1218       ],
1219       'primary_key' => 'optionnum',
1220       'unique'      => [],
1221       'index'       => [ [ 'gatewaynum' ], [ 'optionname' ] ],
1222     },
1223
1224     'agent_payment_gateway' => {
1225       'columns' => [
1226         'agentgatewaynum', 'serial', '', '',
1227         'agentnum',        'int', '', '',
1228         'gatewaynum',      'int', '', '',
1229         'cardtype',        'varchar', 'NULL', $char_d,
1230         'taxclass',        'varchar', 'NULL', $char_d,
1231       ],
1232       'primary_key' => 'agentgatewaynum',
1233       'unique'      => [],
1234       'index'       => [ [ 'agentnum', 'cardtype' ], ],
1235     },
1236
1237     'banned_pay' => {
1238       'columns' => [
1239         'bannum',  'serial',   '',     '',
1240         'payby',   'char',     '',       4,
1241         'payinfo', 'varchar',  '',     128, #say, a 512-big digest _hex encoded
1242         #'paymask', 'varchar',  'NULL', $char_d,
1243         '_date',   @date_type,
1244         'otaker',  'varchar',  '',     32,
1245         'reason',  'varchar',  'NULL', $char_d,
1246       ],
1247       'primary_key' => 'bannum',
1248       'unique'      => [ [ 'payby', 'payinfo' ] ],
1249       'index'       => [],
1250     },
1251
1252     'cancel_reason' => {
1253       'columns' => [
1254         'reasonnum', 'serial',  '',     '',
1255         'reason',    'varchar', '',     $char_d,
1256         'disabled',  'char',    'NULL', 1,
1257       ],
1258       'primary_key' => 'reasonnum',
1259       'unique' => [],
1260       'index'  => [ [ 'disabled' ] ],
1261     },
1262
1263   };
1264
1265 }
1266
1267 =back
1268
1269 =head1 BUGS
1270
1271 =head1 SEE ALSO
1272
1273 L<DBIx::DBSchema>
1274
1275 =cut
1276
1277 1;
1278