587 lines
29 KiB
Perl
587 lines
29 KiB
Perl
# ==================================================================
|
|
# Gossamer Links - enhanced directory management system
|
|
#
|
|
# Website : http://gossamer-threads.com/
|
|
# Support : http://gossamer-threads.com/scripts/support/
|
|
# CVS Info : 087,071,086,086,085
|
|
# Revision : $Id: SQL.pm,v 1.141 2007/11/16 07:15:00 brewt Exp $
|
|
#
|
|
# Copyright (c) 2001 Gossamer Threads Inc. All Rights Reserved.
|
|
# Redistribution in part or in whole strictly prohibited. Please
|
|
# see LICENSE file for full details.
|
|
# ==================================================================
|
|
|
|
# Contains the default table structure for Gossamer Links tables.
|
|
package Links::SQL;
|
|
|
|
use strict;
|
|
use vars qw/@TABLES/;
|
|
use Links qw/:payment $DB/;
|
|
|
|
@TABLES = qw(
|
|
Users Links Changes Category CatPrice Reviews CatLinks CatRelations
|
|
Editors Verify Sessions EmailTemplates EmailMailings MailingIndex
|
|
MailingList MailingListIndex ClickTrack Payments PaymentLogs
|
|
Bookmark_Folders Bookmark_Links SearchLogs NewsletterSubscription
|
|
);
|
|
|
|
sub tables {
|
|
# ------------------------------------------------------------------
|
|
# Defines the SQL tables.
|
|
#
|
|
my $action = shift || 'warn';
|
|
my $output = '';
|
|
|
|
my $ok = Links::language('dialog_ok');
|
|
|
|
# --------- Users Table ----------------
|
|
create_table(\$output, 'Users', $action,
|
|
cols => [
|
|
Username => { type => 'CHAR', size => 50, not_null => 1, form_display => Links::language('prompt_Username') },
|
|
Password => { type => 'CHAR', binary => 1, size => 25, not_null => 1, form_display => Links::language('prompt_Password') },
|
|
Email => { type => 'CHAR', size => 75, not_null => 1, regex => '^(?:.+\@.+\..+|\s*)$', form_display => Links::language('prompt_Email') },
|
|
Name => { type => 'CHAR', size => 75, form_display => Links::language('prompt_Name') },
|
|
Validation => { type => 'CHAR', size => 20, , form_display => Links::language('prompt_Validation') },
|
|
Status => { type => 'ENUM', values => ['Not Validated', 'Registered', 'Administrator'], not_null => 1, default => 'Registered', form_display => Links::language('prompt_Status') },
|
|
ReceiveMail => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'Yes', form_display => Links::language('prompt_ReceiveMail') },
|
|
SortField => { type => 'VARCHAR', size => 255, not_null => 1, regex => '^[\s\w]+$', default => 'Title', form_display => Links::language('prompt_SortField') },
|
|
SortOrd => { type => 'ENUM', values => ['ASC', 'DESC'], not_null => 1, default => 'ASC', form_display => Links::language('prompt_SortOrd') },
|
|
PerPage => { type => 'INT', not_null => 1, unsigned => 1, default => 15, form_display => Links::language('prompt_PerPage') },
|
|
Grouping => { type => 'TINYINT', not_null => 1, unsigned => 1, default => 0, form_display => Links::language('prompt_Grouping') },
|
|
],
|
|
index => {
|
|
emailndx => ['Email']
|
|
},
|
|
pk => 'Username',
|
|
subclass => {
|
|
table => { Users => 'Links::Table::Users' },
|
|
html => { Users => 'Links::HTML::Users' }
|
|
}
|
|
);
|
|
|
|
# --------- Links Table ----------------
|
|
create_table(\$output, 'Links', $action,
|
|
cols => [
|
|
ID => { type => 'INT', not_null => 1, unsigned => 1, regex => '^\d+$', form_display => Links::language('prompt_ID') },
|
|
Title => { type => 'CHAR', size => 100, not_null => 1, weight => 3, form_display => Links::language('prompt_Title') },
|
|
URL => { type => 'CHAR', size => 255, not_null => 1, weight => 1, default => 'http://', regex => '^\w+:', form_display => Links::language('prompt_URL') },
|
|
LinkOwner => { type => 'CHAR', size => 50, not_null => 1, default => 'admin', form_display => Links::language('prompt_LinkOwner') },
|
|
Add_Date => { type => 'DATE', not_null => 1, form_display => Links::language('prompt_Add_Date') },
|
|
Mod_Date => { type => 'DATE', not_null => 1, form_display => Links::language('prompt_Mod_Date') },
|
|
Description => { type => 'TEXT', weight => 1, form_display => Links::language('prompt_Description') },
|
|
Contact_Name => { type => 'CHAR', size => 255, form_display => Links::language('prompt_Contact_Name') },
|
|
Contact_Email => { type => 'CHAR', size => 255, form_display => Links::language('prompt_Contact_Email') },
|
|
Hits => { type => 'INT', not_null => 1, default => 0, regex => '^\d+$', form_display => Links::language('prompt_Hits') },
|
|
isNew => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No', form_display => Links::language('prompt_isNew') },
|
|
isChanged => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No', form_display => Links::language('prompt_isChanged') },
|
|
isPopular => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No', form_display => Links::language('prompt_isPopular') },
|
|
isValidated => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'Yes', form_display => Links::language('prompt_isValidated') },
|
|
Rating => { type => 'DECIMAL', precision => 4, scale => 2, not_null => 1, default => 0, regex => '^(?:10(?:\.0*)?|\d(?:\.\d*)?)$', form_display => Links::language('prompt_Rating') },
|
|
Votes => { type => 'SMALLINT', unsigned => 1, not_null => 1, default => 0, regex => '^\d+$', form_display => Links::language('prompt_Votes') },
|
|
Status => { type => 'SMALLINT', not_null => 1, default => 0, regex => '^-?\d+$', form_display => Links::language('prompt_Status') },
|
|
Date_Checked => { type => 'DATETIME', form_display => Links::language('prompt_Date_Checked') },
|
|
Timestmp => { type => 'TIMESTAMP', time_check => 1, form_display => Links::language('prompt_Timestmp') },
|
|
ExpiryDate => { type => 'INT', not_null => 1, default => FREE, form_display => Links::language('prompt_ExpiryDate'), form_size => 35 }, # See FREE, UNPAID & UNLIMITED constants in Links.pm
|
|
ExpiryCounted => { type => 'TINYINT', not_null => 1, default => 0, form_display => Links::language('prompt_ExpiryCounted'), form_type => 'hidden' },
|
|
ExpiryNotify => { type => 'TINYINT', not_null => 1, default => 0, form_display => Links::language('prompt_ExpiryNotify'), form_type => 'hidden' },
|
|
LinkExpired => { type => 'INT', form_display => Links::language('prompt_LinkExpired'), form_type => 'hidden' },
|
|
],
|
|
pk => 'ID',
|
|
ai => 'ID',
|
|
fk => {
|
|
Users => { LinkOwner => 'Username' }
|
|
},
|
|
index => {
|
|
urlndx => ['URL'],
|
|
stndx => ['Status'],
|
|
valexpndx => [qw/isValidated ExpiryDate/],
|
|
newndx => ['isNew'],
|
|
popndx => ['isPopular'],
|
|
userndx => ['LinkOwner'],
|
|
expiryndx => [qw/ExpiryDate ExpiryNotify/],
|
|
expcntndx => [qw/ExpiryCounted ExpiryDate/]
|
|
},
|
|
subclass => {
|
|
table => { Links => 'Links::Table::Links' },
|
|
html => { Links => 'Links::HTML::Links' }
|
|
}
|
|
);
|
|
|
|
# --------- Changes Table ----------------
|
|
create_table(\$output, 'Changes', $action,
|
|
cols => [
|
|
LinkID => { type => 'INT', not_null => 1, unsigned => 1, regex => '^\d+$' },
|
|
Username => { type => 'CHAR', size => 50, not_null => 1, default => 'admin' },
|
|
ChgRequest => { type => 'TEXT' },
|
|
Timestmp => { type => 'TIMESTAMP' }
|
|
],
|
|
fk => {
|
|
Links => { LinkID => 'ID' },
|
|
Users => { Username => 'Username' }
|
|
}
|
|
);
|
|
|
|
# --------- Category Table ----------------
|
|
my $new_category = create_table(\$output, 'Category', $action,
|
|
cols => [
|
|
ID => { type => 'INT', not_null => 1, unsigned => 1, form_display => Links::language('prompt_ID') },
|
|
Name => { type => 'CHAR', size => 255, not_null => 1, weight => 3, regex => '^[^/]+$', form_display => Links::language('prompt_Name') },
|
|
FatherID => { type => 'INT', not_null => 1, unsigned => 1, default => 0, form_size => 1, form_display => Links::language('prompt_FatherID') },
|
|
CatRoot => { type => 'INT', not_null => 1, unsigned => 1, default => 0, form_type => 'hidden' },
|
|
CatDepth => { type => 'INT', not_null => 1, unsigned => 1, default => 0, form_type => 'hidden' },
|
|
Full_Name => { type => 'CHAR', size => 255, form_display => Links::language('prompt_Full_Name') },
|
|
Description => { type => 'TEXT', weight => 1, form_display => Links::language('prompt_Description') },
|
|
Meta_Description => { type => 'TEXT', form_display => Links::language('prompt_Meta_Description') },
|
|
Meta_Keywords => { type => 'TEXT', form_display => Links::language('prompt_Meta_Keywords') },
|
|
Header => { type => 'TEXT', form_display => Links::language('prompt_Header') },
|
|
Footer => { type => 'TEXT', form_display => Links::language('prompt_Footer') },
|
|
Category_Template => { type => 'CHAR', size => 20, form_display => Links::language('prompt_Category_Template') },
|
|
Number_of_Links => { type => 'INT', not_null => 1, default => 0, form_display => Links::language('prompt_Number_of_Links') },
|
|
Direct_Links => { type => 'INT', not_null => 1, default => 0, form_display => Links::language('prompt_Direct_Links') },
|
|
Has_New_Links => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No', form_display => Links::language('prompt_Has_New_Links') },
|
|
Has_Changed_Links => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No', form_display => Links::language('prompt_Has_Changed_Links') },
|
|
Newest_Link => { type => 'DATE', form_display => Links::language('prompt_Newest_Link') },
|
|
Timestmp => { type => 'TIMESTAMP', time_check => 1, form_display => Links::language('prompt_Timestmp') },
|
|
Payment_Mode => { type => 'TINYINT', not_null => 1, default => 0, form_size => 1, form_names => [GLOBAL,NOT_ACCEPTED,OPTIONAL,REQUIRED], form_values => ['Use global settings','Not accepted','Optional','Required'], form_type => 'SELECT', form_display => Links::language('prompt_Payment_Mode') },
|
|
Payment_Description => { type => 'TEXT', form_display => Links::language('prompt_Payment_Description') },
|
|
],
|
|
subclass => {
|
|
table => { Category => 'Links::Table::Category' },
|
|
html => { Category => 'Links::HTML::Category' }
|
|
},
|
|
pk => 'ID',
|
|
ai => 'ID',
|
|
index => {
|
|
catndx => ['Name'],
|
|
namndx => ['Full_Name'],
|
|
fthrindex => ['FatherID'],
|
|
rootndx => ['CatRoot'],
|
|
c_p => ['Payment_Mode'],
|
|
}
|
|
);
|
|
|
|
# --------- Category Tree -------------------------
|
|
$output .= "Creating Category tree... ";
|
|
my $e = $DB->editor('Category');
|
|
if ($e->add_tree(father => "FatherID", root => "CatRoot", depth => "CatDepth", force => ($new_category ? 'force' : 'check'))) {
|
|
$output .= "okay\n";
|
|
}
|
|
else {
|
|
$output .= "failed ($GT::SQL::error)\n";
|
|
}
|
|
|
|
# --------- CatPrice Table ----------------
|
|
create_table(\$output, 'CatPrice', $action,
|
|
cols => [
|
|
cp_id => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
cp_cat_id_fk => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
cp_term => { type => 'CHAR', not_null => 1, size => 10 }, # e.g. 8d, 1m, 2y, 3w, unlimited, etc.
|
|
cp_cost => { type => 'DOUBLE', not_null => 1 },
|
|
cp_type => { type => 'TINYINT', not_null => 1, unsigned => 1 }, # 0 = signup, 1 = renewal, 2 = recurring
|
|
cp_description => { type => 'TEXT' }
|
|
],
|
|
pk => 'cp_id',
|
|
ai => 'cp_id',
|
|
fk => {
|
|
Category => { cp_cat_id_fk => 'ID' }
|
|
}
|
|
);
|
|
|
|
# --------- Reviews Table ----------------
|
|
create_table(\$output, 'Reviews', $action,
|
|
cols => [
|
|
ReviewID => { type => 'INT', not_null => 1, unsigned => 1, form_display => Links::language('prompt_ReviewID') },
|
|
Review_LinkID => { type => 'INT', not_null => 1, unsigned => 1, regex => '^\d+$', form_display => Links::language('prompt_Review_LinkID') },
|
|
Review_Owner => { type => 'CHAR', size => 50, not_null => 1, form_display => Links::language('prompt_Review_Owner') },
|
|
Review_Rating => { type => 'SMALLINT', unsigned => 1, not_null => 1, default => 0, regex => '^\d+$', form_display => Links::language('prompt_Review_Rating') },
|
|
Review_Date => { type => 'DATETIME', not_null => 1, form_display => Links::language('prompt_Review_Date') },
|
|
Review_ModifyDate => { type => 'DATETIME', not_null => 1, form_display => Links::language('prompt_Review_ModifyDate') },
|
|
Review_Subject => { type => 'CHAR', size => 100, not_null => 1, form_display => Links::language('prompt_Review_Subject') },
|
|
Review_Contents => { type => 'TEXT', not_null => 1, form_display => Links::language('prompt_Review_Contents') },
|
|
Review_ByLine => { type => 'CHAR', size => 50, form_display => Links::language('prompt_Review_ByLine') },
|
|
Review_WasHelpful => { type => 'INT', unsigned => 1, regex => '^\d+$', form_display => Links::language('prompt_Review_WasHelpful') },
|
|
Review_WasNotHelpful => { type => 'INT', unsigned => 1, regex => '^\d+$', form_display => Links::language('prompt_Review_WasNotHelpful') },
|
|
Review_Validated => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No', form_display => Links::language('prompt_Review_Validated') },
|
|
Review_GuestName => { type => 'CHAR', size => 75, form_display => Links::language('prompt_Review_GuestName') },
|
|
Review_GuestEmail => { type => 'CHAR', size => 75, regex => '^(?:(?:.+\@.+\..+)|\s*)$', form_display => Links::language('prompt_Review_GuestEmail') },
|
|
],
|
|
pk => 'ReviewID',
|
|
ai => 'ReviewID',
|
|
subclass => {
|
|
table => { Reviews => 'Links::Table::Reviews' }
|
|
},
|
|
index => {
|
|
rownerndx => ['Review_Owner'],
|
|
rdatendx => ['Review_Date'],
|
|
rlinkndx => ['Review_LinkID']
|
|
},
|
|
fk => {
|
|
Links => { Review_LinkID => 'ID' },
|
|
Users => { Review_Owner => 'Username' }
|
|
}
|
|
);
|
|
|
|
# --------- CatLinks Table ----------------
|
|
create_table(\$output, 'CatLinks', $action,
|
|
cols => [
|
|
LinkID => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
CategoryID => { type => 'INT', not_null => 1, unsigned => 1 }
|
|
],
|
|
subclass => {
|
|
table => { CatLinks => 'Links::Table::CatLinks' }
|
|
},
|
|
index => {
|
|
lndx => ['LinkID']
|
|
},
|
|
unique => {
|
|
cl_cl_q => [qw/CategoryID LinkID/]
|
|
},
|
|
fk => {
|
|
Links => { LinkID => 'ID' },
|
|
Category => { CategoryID => 'ID' }
|
|
}
|
|
);
|
|
|
|
# --------- CatRelations Table ----------------
|
|
create_table(\$output, 'CatRelations', $action,
|
|
cols => [
|
|
CategoryID => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
RelatedID => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
RelationName => { type => 'VARCHAR', size => 255 }
|
|
],
|
|
index => {
|
|
catid => ['CategoryID']
|
|
},
|
|
fk => {
|
|
Category => { CategoryID => 'ID', RelatedID => 'ID' }
|
|
}
|
|
);
|
|
|
|
# --------- User Editors Table ----------------
|
|
create_table(\$output, 'Editors', $action,
|
|
cols => [
|
|
Username => { type => 'CHAR', size => 50, not_null => 1 },
|
|
CategoryID => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
CanAddCat => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanModCat => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanDelCat => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanMoveCat => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanAddLink => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanDelLink => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanModLink => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanCopyLink => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanMoveLink => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanValLink => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanModReview => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanAddRel => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
CanAddEdit => { type => 'ENUM', values => ['No', 'Yes'], not_null => 1, default => 'No' },
|
|
],
|
|
unique => {
|
|
edituserndx => ['Username', 'CategoryID']
|
|
},
|
|
fk => {
|
|
Users => { Username => 'Username' },
|
|
Category => { CategoryID => 'ID' }
|
|
}
|
|
);
|
|
|
|
# --------- Verify History Table ----------------
|
|
create_table(\$output, 'Verify', $action,
|
|
cols => [
|
|
LinkID => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
Status => { type => 'SMALLINT', not_null => 1, default => 0 },
|
|
Date_Checked => { type => 'DATE' }
|
|
],
|
|
index => {
|
|
veriflndx => ['LinkID']
|
|
},
|
|
fk => {
|
|
Links => { LinkID => 'ID' }
|
|
}
|
|
);
|
|
|
|
# --------- Session Table ----------------
|
|
create_table(\$output, 'Sessions', $action,
|
|
cols => [
|
|
session_id => { type => 'CHAR', size => 32, not_null => 1, binary => 1 },
|
|
session_user_id => { type => 'CHAR', size => 50, not_null => 1 },
|
|
session_date => { type => 'INT', not_null => 1 },
|
|
session_expires => { type => 'TINYINT', default => 1 },
|
|
session_data => { type => 'TEXT' }
|
|
],
|
|
pk => 'session_id',
|
|
fk => {
|
|
Users => { session_user_id => 'Username' }
|
|
}
|
|
);
|
|
|
|
# --------- Email Template Table ----------------
|
|
create_table(\$output, 'EmailTemplates', $action,
|
|
cols => [
|
|
Name => { type => 'CHAR', size => 50, not_null => 1, regex => '\S' },
|
|
MsgFrom => { type => 'TEXT', not_null => 1, regex => '\A(?:\S+\@[a-zA-Z0-9][a-zA-Z0-9-]*(?:\.[a-zA-Z0-9][a-zA-Z0-9-]*)+)\Z' },
|
|
MsgFromName => { type => 'TEXT', not_null => 1 },
|
|
Subject => { type => 'TEXT', not_null => 1 },
|
|
Message => { type => 'MEDIUMTEXT', not_null => 1 },
|
|
MessageFormat => { type => 'ENUM', values => [qw[text html]], not_null => 1, default => 'text' },
|
|
LinkTemplate => { type => 'MEDIUMTEXT' }
|
|
],
|
|
pk => 'Name'
|
|
);
|
|
|
|
# --------- Email Mailings Table -------------
|
|
create_table(\$output, 'EmailMailings', $action,
|
|
cols => [
|
|
ID => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
Mailing => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
Email => { type => 'TEXT', size => 75, not_null => 1 },
|
|
Sent => { type => 'TINYINT', default => 0, not_null => 1 },
|
|
LinkID => { type => 'INT', unsigned => 1 } # If this is a sending to link owners, this will hold the Link ID
|
|
],
|
|
pk => 'ID',
|
|
ai => 'ID'
|
|
);
|
|
|
|
# --------- Email Mailing Index Table --------
|
|
create_table(\$output, 'MailingIndex', $action,
|
|
cols => [
|
|
Mailing => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
extra => { type => 'TINYTEXT', not_null => 1 },
|
|
done => { type => 'INT' },
|
|
mailfrom => { type => 'TEXT', not_null => 1 },
|
|
name => { type => 'TEXT', not_null => 1 },
|
|
subject => { type => 'TEXT', not_null => 1 },
|
|
message => { type => 'MEDIUMTEXT', not_null => 1 },
|
|
messageformat => { type => 'ENUM', values => [qw[text html]], not_null => 1, default => 'text' },
|
|
],
|
|
pk => 'Mailing',
|
|
ai => 'Mailing'
|
|
);
|
|
|
|
# --------- MailingList Table ----------------
|
|
create_table(\$output, 'MailingList', $action,
|
|
cols => [
|
|
ID => { type => 'INT', not_null => 1 },
|
|
Email => { type => 'CHAR', size => 255, not_null => 1 }
|
|
],
|
|
index => {
|
|
maillistndx => ['Email']
|
|
}
|
|
);
|
|
|
|
# --------- MailingListIndex Table ----------------
|
|
create_table(\$output, 'MailingListIndex', $action,
|
|
cols => [
|
|
ID => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
Name => { type => 'CHAR', size => 255, not_null => 1 },
|
|
DateModified => { type => 'INT', not_null => 1 },
|
|
DateCreated => { type => 'INT', not_null => 1 }
|
|
],
|
|
pk => 'ID',
|
|
ai => 'ID'
|
|
);
|
|
|
|
# --------- ClickTrack Table ----------------
|
|
create_table(\$output, 'ClickTrack', $action,
|
|
cols => [
|
|
LinkID => { type => 'INT', not_null => 1 },
|
|
IP => { type => 'CHAR', size => 16, not_null => 1 },
|
|
ClickType => { type => 'ENUM', values => ['Rate', 'Hits','Review'], not_null => 1 },
|
|
ReviewID => { type => 'INT', not_null => 1, default => 0},
|
|
Created => { type => 'TIMESTAMP' }
|
|
],
|
|
subclass => {
|
|
table => { ClickTrack => 'Links::Table::ClickTrack' }
|
|
},
|
|
unique => {
|
|
ct_licr => ['LinkID', 'IP', 'ClickType','ReviewID']
|
|
},
|
|
index => {
|
|
cndx => ['Created']
|
|
}
|
|
);
|
|
|
|
# --------- Payments Table ----------------
|
|
create_table(\$output, 'Payments', $action,
|
|
cols => [
|
|
payments_id => { type => 'CHAR', not_null => 1, size => 16 },
|
|
payments_linkid => { type => 'INT', unsigned => 1, not_null => 1 },
|
|
payments_status => { type => 'INT', not_null => 1, default => 0, unsigned => 1 }, # 0 = pending, 1 = completed, 2 = declined, 3 = error
|
|
payments_method => { type => 'CHAR', not_null => 1, size => 25 },
|
|
payments_type => { type => 'TINYINT', not_null => 1, unsigned => 1 }, # 0 = initial payment, 1 = renewal payment, 2 = recurring payment
|
|
payments_amount => { type => 'DOUBLE', not_null => 1 },
|
|
payments_term => { type => 'CHAR', not_null => 1, size => 10 }, # e.g. 8d, 1m, 2y, 3w, unlimited, etc.
|
|
payments_start => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
payments_last => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
],
|
|
pk => 'payments_id',
|
|
fk => {
|
|
Links => { payments_linkid => 'ID' }
|
|
},
|
|
index => {
|
|
p_sl => ['payments_status', 'payments_last'],
|
|
p_ll => ['payments_linkid', 'payments_last'],
|
|
p_al => ['payments_amount', 'payments_last'],
|
|
}
|
|
);
|
|
|
|
# --------- Payment Logs Table ----------------
|
|
create_table(\$output, 'PaymentLogs', $action,
|
|
cols => [
|
|
paylogs_id => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
paylogs_payments_id => { type => 'CHAR', not_null => 1, size => 16 },
|
|
paylogs_type => { type => 'INT', not_null => 1, default => 0, unsigned => 1 }, # 0 = info, 1 = accepted, 2 = declined, 3 = error
|
|
paylogs_time => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
paylogs_viewed => { type => 'TINYINT', not_null => 1, default => 0, unsigned => 1 },
|
|
paylogs_text => { type => 'TEXT' },
|
|
],
|
|
pk => 'paylogs_id',
|
|
ai => 'paylogs_id',
|
|
fk => {
|
|
Payments => { paylogs_payments_id => 'payments_id' }
|
|
},
|
|
index => {
|
|
pl_yt => ['paylogs_type', 'paylogs_time'],
|
|
pl_t => ['paylogs_time']
|
|
}
|
|
);
|
|
|
|
# --------- Bookmark Folders Table ----------------
|
|
create_table(\$output, 'Bookmark_Folders', $action,
|
|
cols => [
|
|
my_folder_id => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
my_folder_name => { type => 'VARCHAR', not_null => 1, size => 255 },
|
|
my_folder_description => { type => 'VARCHAR', size => 255 },
|
|
my_folder_user_username_fk => { type => 'VARCHAR', size => 50 },
|
|
my_folder_default => { type => 'TINYINT', not_null => 1, default => 0, unsigned => 1 },
|
|
my_folder_public => { type => 'TINYINT', not_null => 1, default => 0, unsigned => 1 }
|
|
],
|
|
pk => 'my_folder_id',
|
|
ai => 'my_folder_id',
|
|
fk => {
|
|
Users => { my_folder_user_username_fk => 'Username' }
|
|
}
|
|
);
|
|
|
|
# --------- Bookmark Links Table ----------------
|
|
create_table(\$output, 'Bookmark_Links', $action,
|
|
cols => [
|
|
my_id => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
my_link_id_fk => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
my_user_username_fk => { type => 'VARCHAR', size => 50 },
|
|
my_folder_id_fk => { type => 'INT', not_null => 1, unsigned => 1 },
|
|
my_comment => { type => 'VARCHAR', size => '255' }
|
|
],
|
|
pk => 'my_id',
|
|
ai => 'my_id',
|
|
fk => {
|
|
Users => { my_user_username_fk => 'Username' },
|
|
Bookmark_Folders => { my_folder_id_fk => 'my_folder_id' },
|
|
Links => { my_link_id_fk => 'ID' },
|
|
}
|
|
);
|
|
|
|
# --------- SearchLogs Table ----------------
|
|
create_table(\$output, 'SearchLogs', $action,
|
|
cols => [
|
|
slog_query => { type => 'VARCHAR', not_null => 1, size => 255 },
|
|
slog_count => { type => 'INT', not_null => 1, default => 0 },
|
|
slog_hits => { type => 'INT', not_null => 1, default => 0 },
|
|
slog_time => { type => 'FLOAT' },
|
|
slog_last => { type => 'INT', not_null => 1, default => 0 },
|
|
],
|
|
pk => 'slog_query'
|
|
);
|
|
|
|
# --------- Newsletter Subscription Table ----------------
|
|
create_table(\$output, 'NewsletterSubscription', $action,
|
|
cols => [
|
|
UserID => { type => 'CHAR', size => 50 },
|
|
CategoryID => { type => 'INT', not_null => 1 },
|
|
],
|
|
unique => {
|
|
ns_uc => ['UserID', 'CategoryID']
|
|
},
|
|
fk => {
|
|
Users => { UserID => 'Username' },
|
|
Category => { CategoryID => 'ID' }
|
|
}
|
|
);
|
|
|
|
return $output;
|
|
}
|
|
|
|
sub create_table {
|
|
my ($output, $table, $action, @def) = @_;
|
|
|
|
$$output .= Links::language('dialog_create', $table);
|
|
my $c = $DB->creator($table);
|
|
$c->clear_schema() if $action eq 'force';
|
|
|
|
@def % 2 and die "Odd number of table defs passed to create_table()";
|
|
while (@def) {
|
|
my ($meth, $arg) = splice @def, 0, 2;
|
|
$c->$meth($arg);
|
|
}
|
|
|
|
if ($c->create($action)) {
|
|
$$output .= Links::language('dialog_ok');
|
|
return 1;
|
|
}
|
|
else {
|
|
$$output .= Links::language($GT::SQL::errcode eq 'TBLEXISTS' ? ('error_failed_exists') : ('error_failed_other', $GT::SQL::error));
|
|
$GT::SQL::errcode if 0; # silence "used only once" warning
|
|
$c->set_defaults;
|
|
$c->save_schema;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
sub load_from_sql {
|
|
# ---------------------------------------------------------------
|
|
# Creates def files based on existing tables.
|
|
#
|
|
my ($output, $return);
|
|
foreach my $table (@TABLES) {
|
|
$output .= "$table .. ";
|
|
my $c = $DB->creator($table);
|
|
$return = $c->load_table($table);
|
|
if ($return) {
|
|
if ($table eq 'Links' or $table eq 'Users' or $table eq 'Category') {
|
|
$c->subclass(
|
|
table => { $table => "Links::Table::$table" },
|
|
html => { $table => "Links::HTML::$table" }
|
|
);
|
|
}
|
|
elsif ($table eq 'CatLinks' or $table eq 'ClickTrack') {
|
|
$c->subclass(
|
|
table => { $table => "Links::Table::$table" }
|
|
);
|
|
}
|
|
$output .= "ok!\n";
|
|
$c->save_schema();
|
|
}
|
|
else {
|
|
$output .= "failed: $GT::SQL::error\n";
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
sub load {
|
|
# ---------------------------------------------------------------
|
|
# Return a hash of current connection settings.
|
|
#
|
|
my %h = ();
|
|
$h{prefix} = $DB->prefix();
|
|
$h{database} = $DB->{connect}->{database};
|
|
$h{login} = $DB->{connect}->{login};
|
|
$h{password} = $DB->{connect}->{password};
|
|
$h{host} = $DB->{connect}->{host};
|
|
$h{host} .= ":" . $DB->{connect}->{port} if $DB->{connect}->{port};
|
|
$h{driver} = $DB->{connect}->{driver};
|
|
return \%h;
|
|
}
|
|
|
|
1;
|