Set up + run perltidy, plus some manual format changes too
This commit is contained in:
parent
fd585edc80
commit
51b2c54e9a
|
@ -7,3 +7,9 @@ charmboard.conf
|
|||
|
||||
# Perl::Critic
|
||||
perlcritic.log
|
||||
|
||||
# Perl::Tidy
|
||||
perltidy.log
|
||||
*.tdy
|
||||
*.pm.LOG
|
||||
*.pl.LOG
|
|
@ -0,0 +1,42 @@
|
|||
-w
|
||||
-log
|
||||
-i=2
|
||||
-l=70
|
||||
-enc=utf8
|
||||
-gcs
|
||||
-ole=unix
|
||||
-it=2
|
||||
-ci=4
|
||||
-xci
|
||||
-cti=1
|
||||
-nolq
|
||||
-nola
|
||||
-pt=2
|
||||
-bt=1
|
||||
-bbt=0
|
||||
-tso
|
||||
-nsts
|
||||
-sfs
|
||||
-nasc
|
||||
-dsm
|
||||
-aws
|
||||
-dws
|
||||
-fpva
|
||||
-lop
|
||||
-ibc
|
||||
-nfs
|
||||
-ce
|
||||
-nbl
|
||||
-olc
|
||||
-dsm
|
||||
-olq
|
||||
-kis
|
||||
-bbb
|
||||
-kbl=1
|
||||
-bar
|
||||
-otr
|
||||
-bbhb=3
|
||||
-bbhbi=1
|
||||
-wn
|
||||
-vt=1
|
||||
-nlal
|
|
@ -16,48 +16,53 @@ sub startup {
|
|||
$self->plugin('TagHelpers');
|
||||
|
||||
# load configuration from config file
|
||||
my $config = $self->plugin('Config' =>
|
||||
{file => 'charmboard.conf'});
|
||||
my $config =
|
||||
$self->plugin('Config' => { file => 'charmboard.conf' });
|
||||
|
||||
# set this specific forum's name
|
||||
$self->helper(board_name => sub {$config->{board_name}});
|
||||
$self->helper(board_name => sub { $config->{board_name} });
|
||||
|
||||
# load dev env only stuff, if applicable
|
||||
if ($config->{environment} eq 'dev') {
|
||||
$self->plugin('Renderer::WithoutCache');
|
||||
$self->renderer->cache->max_keys(0)};
|
||||
$self->renderer->cache->max_keys(0)
|
||||
}
|
||||
|
||||
# import Mojolicious secrets
|
||||
$self->secrets($config->{secrets});
|
||||
|
||||
# import password pepper value
|
||||
$self->helper(
|
||||
pepper => sub {$config->{pass_crypt}->{pepper}});
|
||||
$self->helper(pepper => sub { $config->{pass_crypt}->{pepper} });
|
||||
|
||||
## database setup
|
||||
# ? this could maybe be a given/when
|
||||
{ my ($_dsn, $_unicode);
|
||||
{
|
||||
my ($_dsn, $_unicode);
|
||||
if ($self->config->{database}->{type} ~~ 'sqlite') {
|
||||
$_dsn = "dbi:SQLite:" . $config->{database}->{name};
|
||||
$_unicode = "sqlite_unicode"}
|
||||
$_unicode = "sqlite_unicode"
|
||||
|
||||
elsif ($self->config->{database}->{type} ~~ 'mariadb') {
|
||||
} elsif ($self->config->{database}->{type} ~~ 'mariadb') {
|
||||
$_dsn = "dbi:mysql:" . $config->{database}->{name};
|
||||
$_unicode = "mysql_enable_utf"}
|
||||
$_unicode = "mysql_enable_utf"
|
||||
|
||||
else {die "\nUnknown, unsupported, or empty database type
|
||||
} else {
|
||||
die "\nUnknown, unsupported, or empty database type
|
||||
in charmboard.conf. If you're sure you've set it to
|
||||
something supported, maybe double check your spelling?
|
||||
\n\n\t
|
||||
Valid options: 'sqlite', 'mariadb'"};
|
||||
Valid options: 'sqlite', 'mariadb'"
|
||||
}
|
||||
|
||||
our $schema = CharmBoard::Schema->connect(
|
||||
$_dsn,
|
||||
$config->{database}->{user},
|
||||
$config->{database}->{pass},
|
||||
{$_unicode => 1});
|
||||
{ $_unicode => 1 }
|
||||
);
|
||||
|
||||
$self->helper(schema => sub {$schema})}
|
||||
$self->helper(schema => sub { $schema })
|
||||
}
|
||||
|
||||
# router
|
||||
my $r = $self->routes;
|
||||
|
@ -65,34 +70,41 @@ sub startup {
|
|||
# view subforum
|
||||
$r->get('/subforum/:id')->to(
|
||||
controller => 'Controller::ViewSubf',
|
||||
action => 'subf_view');
|
||||
action => 'subf_view'
|
||||
);
|
||||
|
||||
# controller routes
|
||||
## index page
|
||||
$r->get('/')->to(
|
||||
controller => 'Controller::Index',
|
||||
action => 'index');
|
||||
action => 'index'
|
||||
);
|
||||
|
||||
## registration page
|
||||
$r->get('/register')->to(
|
||||
controller => 'Controller::Register',
|
||||
action => 'register');
|
||||
action => 'register'
|
||||
);
|
||||
$r->post('/register')->to(
|
||||
controller => 'Controller::Register',
|
||||
action => 'register_do');
|
||||
action => 'register_do'
|
||||
);
|
||||
|
||||
## login page
|
||||
$r->get('/login')->to(
|
||||
controller => 'Controller::Login',
|
||||
action => 'login');
|
||||
action => 'login'
|
||||
);
|
||||
$r->post('/login')->to(
|
||||
controller => 'Controller::Login',
|
||||
action => 'login_do');
|
||||
action => 'login_do'
|
||||
);
|
||||
|
||||
## logout
|
||||
$r->get('/logout')->to(
|
||||
controller => 'Controller::Logout',
|
||||
action => 'logout_do')
|
||||
action => 'logout_do'
|
||||
)
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -103,17 +115,17 @@ __END__
|
|||
CharmBoard - revive the fun posting experience!
|
||||
|
||||
=head1 NOTES
|
||||
This documentation is intended for prospective code
|
||||
contributors. If you're looking to set CharmBoard up,
|
||||
look for the Markdown format (.md) documentation instead.
|
||||
This documentation is intended for prospective code contributors. If
|
||||
you're looking to set CharmBoard up, look for the Markdown format
|
||||
(.md) documentation instead.
|
||||
|
||||
CharmBoard uses a max line length of 60 chars and a tab
|
||||
size of two spaces.
|
||||
CharmBoard uses a max line length of 70 chars and a tab size of two
|
||||
spaces.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
CharmBoard is forum software written in Perl with
|
||||
Mojolicious, intended to be a more fun alternative to the
|
||||
bigger forum suites available today, inspired by older
|
||||
forum software like AcmlmBoard, while also being more
|
||||
modernized in terms of security practices than they are.
|
||||
CharmBoard is forum software written in Perl with Mojolicious,
|
||||
intended to be a more fun alternative to the bigger forum suites
|
||||
available today, inspired by older forum software like AcmlmBoard,
|
||||
while also being more modernized in terms of security practices than
|
||||
they are.
|
||||
=cut
|
||||
|
|
|
@ -12,20 +12,17 @@ sub index {
|
|||
my $self = shift;
|
||||
|
||||
# fetch a list of all categories
|
||||
my @all_cat =
|
||||
$self->schema->resultset('Categories')->fetch_all;
|
||||
my @all_cat = $self->schema->resultset('Categories')->fetch_all;
|
||||
|
||||
# create a Tree::Simple object that will contain the list
|
||||
# of categories and the subforums that belong to them
|
||||
my $tree =
|
||||
Tree::Simple->new("subf_list", Tree::Simple->ROOT);
|
||||
my $tree = Tree::Simple->new("subf_list", Tree::Simple->ROOT);
|
||||
|
||||
my (@fetch_subf, $cat_branch);
|
||||
foreach my $iter_cat (@all_cat) {
|
||||
# create branch of subf_list for the current category
|
||||
|
||||
$cat_branch =
|
||||
Tree::Simple->new($iter_cat, $tree);
|
||||
# create branch of subf_list for the current category
|
||||
$cat_branch = Tree::Simple->new($iter_cat, $tree);
|
||||
|
||||
# fetch all subforums that belong to this category
|
||||
@fetch_subf =
|
||||
|
@ -35,11 +32,15 @@ sub index {
|
|||
# add each fetched subforum as children of the branch
|
||||
# for the current category
|
||||
foreach my $iter_subf (@fetch_subf) {
|
||||
Tree::Simple->new($iter_subf, $cat_branch)}}
|
||||
Tree::Simple->new($iter_subf, $cat_branch)
|
||||
}
|
||||
}
|
||||
|
||||
$self->render(
|
||||
template => 'index',
|
||||
category_tree => $tree)}
|
||||
category_tree => $tree
|
||||
)
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -15,7 +15,9 @@ sub login {
|
|||
$self->render(
|
||||
template => 'login',
|
||||
error => $self->flash('error'),
|
||||
message => $self->flash('message'))};
|
||||
message => $self->flash('message')
|
||||
)
|
||||
}
|
||||
|
||||
sub login_do {
|
||||
my $self = shift;
|
||||
|
@ -28,21 +30,23 @@ sub login_do {
|
|||
# 'our' so they work throughout the entire subroutine
|
||||
our ($user_info, $pass_check, $user_id, $session_key);
|
||||
|
||||
try { # check user credentials first
|
||||
# check user credentials first
|
||||
try {
|
||||
# check to see if user by entered username exists
|
||||
$user_info = $self->schema->resultset('Users')->search(
|
||||
{username => $username});
|
||||
$user_info = $self->schema->resultset('Users')
|
||||
->search({ username => $username });
|
||||
$user_info or die;
|
||||
|
||||
# now check password validity
|
||||
$pass_check = passchk($user_info->get_column('salt')->first,
|
||||
$user_info->get_column('password')->first, $password);
|
||||
$pass_check or die;}
|
||||
$pass_check or die;
|
||||
|
||||
catch ($catch_error) { # redirect to login page on fail
|
||||
} catch ($catch_error) { # redirect to login page on fail
|
||||
print $catch_error;
|
||||
$self->flash(error => 'Username or password incorrect.');
|
||||
$self->redirect_to('login');}
|
||||
$self->redirect_to('login');
|
||||
}
|
||||
|
||||
try { # now attempt to create session
|
||||
# get user ID for session creation
|
||||
|
@ -57,23 +61,29 @@ sub login_do {
|
|||
user_id => $user_id,
|
||||
session_expiry => time + 604800,
|
||||
is_ip_bound => 0,
|
||||
bound_ip => undef }) or die;
|
||||
bound_ip => undef
|
||||
})
|
||||
or die;
|
||||
|
||||
# now create session cookie for user
|
||||
$self->session(is_auth => 1);
|
||||
$self->session(user_id => $user_id);
|
||||
$self->session(is_auth => 1 );
|
||||
$self->session(user_id => $user_id );
|
||||
$self->session(session_key => $session_key);
|
||||
$self->session(expiration => 604800);
|
||||
$self->session(expiration => 604800 );
|
||||
|
||||
# redirect to index upon success
|
||||
$self->redirect_to('/')}
|
||||
$self->redirect_to('/')
|
||||
|
||||
catch ($catch_error) { # redirect to login page on fail
|
||||
} catch ($catch_error) { # redirect to login page on fail
|
||||
print $catch_error;
|
||||
$self->flash(error => 'Your username and password were correct,
|
||||
but a server error prevented you from logging in. This has been
|
||||
logged so the administrator can fix it.');
|
||||
$self->redirect_to('login')}}
|
||||
$self->flash(
|
||||
error => 'Your username and password were correct, but a server
|
||||
error prevented you from logging in. This has been logged
|
||||
so the administrator can fix it.'
|
||||
);
|
||||
$self->redirect_to('login')
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
@ -11,11 +11,16 @@ sub logout_do {
|
|||
my $self = shift;
|
||||
|
||||
# destroy entry for this session in the database
|
||||
$self->schema->resultset('Session')->search({
|
||||
session_key => $self->session('session_key')})->delete;
|
||||
$self->schema->resultset('Session')
|
||||
->search({ session_key => $self->session('session_key') })
|
||||
->delete;
|
||||
|
||||
# now nuke the actual session cookie
|
||||
$self->session(expires => 1);
|
||||
|
||||
# redirect to index
|
||||
$self->redirect_to('/')}
|
||||
$self->redirect_to('/')
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
|
|
@ -14,7 +14,9 @@ sub register {
|
|||
$self->render(
|
||||
template => 'register',
|
||||
error => $self->flash('error'),
|
||||
message => $self->flash('message'))};
|
||||
message => $self->flash('message')
|
||||
)
|
||||
}
|
||||
|
||||
# process submitted registration form
|
||||
sub register_do {
|
||||
|
@ -31,7 +33,8 @@ sub register_do {
|
|||
# 'our' so they work throughout the entire subroutine
|
||||
our ($userCheck, $emailCheck, $salt, $hash);
|
||||
|
||||
try { # make sure registration info is valid
|
||||
# make sure registration info is valid
|
||||
try {
|
||||
# TODO: implement email validation here at some point
|
||||
|
||||
# check to make sure all required fields are filled
|
||||
|
@ -46,23 +49,25 @@ sub register_do {
|
|||
# check to make sure username and/or email isn't already in use;
|
||||
# if not, continue with registration
|
||||
## search for input username and email in database
|
||||
$userCheck = $self->schema->resultset('Users')->search(
|
||||
{username => $username})->single;
|
||||
$emailCheck = $self->schema->resultset('Users')->search(
|
||||
{email => $email})->single;
|
||||
$userCheck = $self->schema->resultset('Users')
|
||||
->search({ username => $username })->single;
|
||||
$emailCheck = $self->schema->resultset('Users')
|
||||
->search({ email => $email })->single;
|
||||
|
||||
($userCheck && $emailCheck) eq undef
|
||||
or die "Username already in use.\nemail already in use.";
|
||||
($userCheck) eq undef
|
||||
or die "Username already in use.";
|
||||
($emailCheck) eq undef
|
||||
or die "email already in use."}
|
||||
catch ($catchError) {
|
||||
or die "email already in use."
|
||||
} catch ($catchError) {
|
||||
$self->flash(error => $catchError);
|
||||
$self->redirect_to('register');}
|
||||
$self->redirect_to('register')
|
||||
}
|
||||
|
||||
try {
|
||||
$password = $self->pepper . ':' . $password;
|
||||
|
||||
# return hashed result + salt
|
||||
($salt, $hash) = passgen($password) or die;
|
||||
|
||||
|
@ -72,15 +77,22 @@ sub register_do {
|
|||
email => $email,
|
||||
password => $hash,
|
||||
salt => $salt,
|
||||
signup_date => time }) or die;
|
||||
signup_date => time
|
||||
})
|
||||
or die;
|
||||
|
||||
$self->flash(message => 'User registered successfully!');
|
||||
$self->redirect_to('register')}
|
||||
catch ($catchError) {
|
||||
$self->redirect_to('register')
|
||||
} catch ($catchError) {
|
||||
print $catchError;
|
||||
$self->flash(error => 'Your registration info was correct, but a
|
||||
server error prevented you from registering. This has been
|
||||
logged so the administrator can fix it.');
|
||||
$self->redirect_to('register')}}
|
||||
$self->flash(
|
||||
error =>
|
||||
'Your registration info was correct, but a server error
|
||||
prevented you from registering. This has been logged so the
|
||||
administrator can fix it.'
|
||||
);
|
||||
$self->redirect_to('register')
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
|
@ -24,9 +24,11 @@ sub subf_view {
|
|||
template => 'subf',
|
||||
subf_id => $subf_id,
|
||||
cat_title => $cat_title,
|
||||
subf_title =>
|
||||
$self->schema->resultset('Subforums')
|
||||
subf_title => $self->schema->resultset('Subforums')
|
||||
->title_from_id($subf_id),
|
||||
thread_list => \@thread_list)}
|
||||
thread_list => \@thread_list
|
||||
)
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
|
|
@ -12,26 +12,30 @@ use Exporter qw(import);
|
|||
our @EXPORT = qw(passgen passchk);
|
||||
|
||||
sub passgen {
|
||||
my $argon2 = Authen::Passphrase::Argon2->new(
|
||||
my $_argon2 = Authen::Passphrase::Argon2->new(
|
||||
salt => seasoning(32),
|
||||
passphrase => $_[0],
|
||||
cost => 17,
|
||||
factor => '32M',
|
||||
parallelism => 1,
|
||||
size => 32 );
|
||||
size => 32
|
||||
);
|
||||
|
||||
return ($argon2->salt_hex, $argon2->hash_hex)};
|
||||
return ($_argon2->salt_hex, $_argon2->hash_hex)
|
||||
}
|
||||
|
||||
sub passchk {
|
||||
my $argon2 = Authen::Passphrase::Argon2->new(
|
||||
my $_argon2 = Authen::Passphrase::Argon2->new(
|
||||
salt_hex => $_[0],
|
||||
hash_hex => $_[1],
|
||||
cost => 17,
|
||||
factor => '32M',
|
||||
parallelism => 1,
|
||||
size => 32 );
|
||||
size => 32
|
||||
);
|
||||
|
||||
return ($argon2->match($_[2]))}
|
||||
return ($_argon2->match($_[2]))
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
@ -11,16 +11,20 @@ use Exporter qw(import);
|
|||
our @EXPORT = qw(seasoning);
|
||||
|
||||
sub seasoning {
|
||||
my @spices = qw(0 1 2 3 4 5 6 7 8 9 a b c d e f g
|
||||
my @_spices = qw(0 1 2 3 4 5 6 7 8 9 a b c d e f g
|
||||
h i j k l m n o p q r s t u v w x y z A B C D E F
|
||||
G H I J K L M N O P Q R S T U V W X Y Z ! @ $ % ^
|
||||
& * / ? . ; : \ [ ] - _ < > ` ~ + = £ ¥ ¢ §);
|
||||
|
||||
my $blend;
|
||||
while (length($blend) < $_[0]) {
|
||||
# gen num to choose char for $blend
|
||||
$blend = $blend . $spices[irand(@spices)]};
|
||||
my $_blend;
|
||||
while (length($_blend) < $_[0]) {
|
||||
|
||||
return ($blend); }
|
||||
# gen num to choose char for $blend
|
||||
$_blend = $_blend . $_spices[ irand(@_spices) ]
|
||||
}
|
||||
|
||||
return ($_blend)
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
|
|
@ -9,7 +9,8 @@ use base qw(DBIx::Class::Schema);
|
|||
|
||||
__PACKAGE__->load_namespaces(
|
||||
result_namespace => 'Source',
|
||||
resultset_namespace => 'Set');
|
||||
resultset_namespace => 'Set'
|
||||
);
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
@ -10,26 +10,26 @@ use base 'DBIx::Class::ResultSet';
|
|||
sub fetch_all {
|
||||
my $_set = shift;
|
||||
|
||||
my $_fetch =
|
||||
$_set->search({},
|
||||
{order_by => 'cat_rank'});
|
||||
my $_fetch = $_set->search({}, { order_by => 'cat_rank' });
|
||||
|
||||
return($_fetch->get_column('cat_id')->all)}
|
||||
return ($_fetch->get_column('cat_id')->all)
|
||||
}
|
||||
|
||||
sub title_from_id {
|
||||
my $_set = shift;
|
||||
|
||||
return(
|
||||
$_set->search({'cat_id' => $_[0]})->
|
||||
get_column('cat_name')->first)}
|
||||
return (
|
||||
$_set->search({ 'cat_id' => $_[0] })->get_column('cat_name')
|
||||
->first)
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
=pod
|
||||
=head1 NAME
|
||||
CharmBoard::Schema::Set::Categories - DBIC ResultSet for
|
||||
the categories table
|
||||
CharmBoard::Schema::Set::Categories - DBIC ResultSet for the
|
||||
categories table
|
||||
|
||||
=head1 SYNOPSIS
|
||||
=head1 DESCRIPTION
|
||||
|
|
|
@ -10,26 +10,26 @@ use base 'DBIx::Class::ResultSet';
|
|||
sub fetch_by_cat {
|
||||
my $_set = shift;
|
||||
|
||||
my $_fetch =
|
||||
$_set->search(
|
||||
{'subf_cat' => $_[0] },
|
||||
{order_by => 'subf_rank'});
|
||||
my $_fetch = $_set->search({ 'subf_cat' => $_[0] },
|
||||
{ order_by => 'subf_rank' });
|
||||
|
||||
return($_fetch->get_column('subf_id')->all)}
|
||||
return ($_fetch->get_column('subf_id')->all)
|
||||
}
|
||||
|
||||
sub cat_from_id {
|
||||
my $_set = shift;
|
||||
|
||||
return(
|
||||
$_set->search({'subf_id' => $_[0]})->
|
||||
get_column('subf_cat')->first)}
|
||||
return (
|
||||
$_set->search({ 'subf_id' => $_[0] })->get_column('subf_cat')
|
||||
->first)
|
||||
}
|
||||
|
||||
sub title_from_id {
|
||||
my $_set = shift;
|
||||
|
||||
return(
|
||||
$_set->search({'subf_id' => $_[0]})->
|
||||
get_column('subf_name')->first)}
|
||||
return ($_set->search({ 'subf_id' => $_[0] })
|
||||
->get_column('subf_name')->first)
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -11,16 +11,17 @@ sub fetch_by_subf {
|
|||
my $_set = shift;
|
||||
|
||||
my $_fetch =
|
||||
$_set->search({'thread_subf' => $_[0]});
|
||||
$_set->search({ 'thread_subf' => $_[0] });
|
||||
|
||||
return($_fetch->get_column('thread_id')->all)}
|
||||
return ($_fetch->get_column('thread_id')->all)
|
||||
}
|
||||
|
||||
sub title_from_id {
|
||||
my $_set = shift;
|
||||
|
||||
return(
|
||||
$_set->search({'thread_id' => $_[0]})->
|
||||
get_column('thread_title')->first)}
|
||||
return ($_set->search({ 'thread_id' => $_[0] })
|
||||
->get_column('thread_title')->first)
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -9,16 +9,20 @@ use base qw(DBIx::Class::Core);
|
|||
|
||||
__PACKAGE__->table('categories');
|
||||
__PACKAGE__->add_columns(
|
||||
cat_id => {
|
||||
data_type => 'integer',
|
||||
cat_id =>
|
||||
{ data_type => 'integer',
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0, },
|
||||
cat_rank => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0, },
|
||||
cat_name => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, });
|
||||
is_nullable => 0,
|
||||
},
|
||||
cat_rank =>
|
||||
{ data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
cat_name =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
}
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key('cat_id');
|
||||
|
||||
|
|
|
@ -9,32 +9,37 @@ use base qw(DBIx::Class::Core);
|
|||
|
||||
__PACKAGE__->table('posts');
|
||||
__PACKAGE__->add_columns(
|
||||
post_id => {
|
||||
data_type => 'integer',
|
||||
post_id =>
|
||||
{ data_type => 'integer',
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0, },
|
||||
user_id => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
user_id =>
|
||||
{ data_type => 'integer',
|
||||
is_foreign_key => 1,
|
||||
is_nullable => 0, },
|
||||
thread_id => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
thread_id =>
|
||||
{ data_type => 'integer',
|
||||
is_foreign_key => 1,
|
||||
is_nullable => 0, },
|
||||
post_date => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0, });
|
||||
is_nullable => 0,
|
||||
},
|
||||
post_date =>
|
||||
{ data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
}
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key('post_id');
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
user_id =>
|
||||
'CharmBoard::Schema::Source::Users',
|
||||
'user_id' );
|
||||
user_id => 'CharmBoard::Schema::Source::Users',
|
||||
'user_id'
|
||||
);
|
||||
__PACKAGE__->belongs_to(
|
||||
thread_id =>
|
||||
'CharmBoard::Schema::Source::Threads',
|
||||
'thread_id' );
|
||||
thread_id => 'CharmBoard::Schema::Source::Threads',
|
||||
'thread_id'
|
||||
);
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -9,28 +9,34 @@ use base qw(DBIx::Class::Core);
|
|||
|
||||
__PACKAGE__->table('sessions');
|
||||
__PACKAGE__->add_columns(
|
||||
session_key => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
user_id => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0, },
|
||||
session_expiry => {
|
||||
data_type => 'numeric',
|
||||
is_nullable => 0, },
|
||||
is_ip_bound => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0, },
|
||||
bound_ip => {
|
||||
data_type => 'text',
|
||||
is_nullable => 1, });
|
||||
session_key =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
user_id =>
|
||||
{ data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
session_expiry =>
|
||||
{ data_type => 'numeric',
|
||||
is_nullable => 0,
|
||||
},
|
||||
is_ip_bound =>
|
||||
{ data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
bound_ip =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 1,
|
||||
}
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key('session_key');
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
user_id =>
|
||||
'CharmBoard::Schema::Source::Users',
|
||||
'user_id');
|
||||
user_id => 'CharmBoard::Schema::Source::Users',
|
||||
'user_id'
|
||||
);
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -9,31 +9,37 @@ use base qw(DBIx::Class::Core);
|
|||
|
||||
__PACKAGE__->table('subforums');
|
||||
__PACKAGE__->add_columns(
|
||||
subf_id => {
|
||||
data_type => 'integer',
|
||||
subf_id =>
|
||||
{ data_type => 'integer',
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0, },
|
||||
subf_cat => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
subf_cat =>
|
||||
{ data_type => 'integer',
|
||||
is_foreign_key => 1,
|
||||
is_nullable => 0, },
|
||||
subf_rank => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
subf_rank =>
|
||||
{ data_type => 'integer',
|
||||
is_numeric => 1,
|
||||
is_nullable => 0, },
|
||||
subf_name => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
subf_desc => {
|
||||
data_type => 'text',
|
||||
is_nullable => 1, });
|
||||
is_nullable => 0,
|
||||
},
|
||||
subf_name =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
subf_desc =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 1,
|
||||
}
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key('subf_id');
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
subf_cat =>
|
||||
'CharmBoard::Schema::Source::Categories',
|
||||
{'foreign.cat_id' => 'self.subf_cat'});
|
||||
subf_cat => 'CharmBoard::Schema::Source::Categories',
|
||||
{ 'foreign.cat_id' => 'self.subf_cat' }
|
||||
);
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -9,31 +9,37 @@ use base qw(DBIx::Class::Core);
|
|||
|
||||
__PACKAGE__->table('threads');
|
||||
__PACKAGE__->add_columns(
|
||||
thread_id => {
|
||||
data_type => 'integer',
|
||||
thread_id =>
|
||||
{ data_type => 'integer',
|
||||
is_auto_increment => 1,
|
||||
is_nullable => 0, },
|
||||
thread_title => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
thread_op => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
thread_title =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
thread_op =>
|
||||
{ data_type => 'integer',
|
||||
is_foreign_key => 1,
|
||||
is_nullable => 0, },
|
||||
thread_subf => {
|
||||
data_type => 'integer',
|
||||
is_nullable => 0,
|
||||
},
|
||||
thread_subf =>
|
||||
{ data_type => 'integer',
|
||||
is_foreign_key => 1,
|
||||
is_nullable => 0, });
|
||||
is_nullable => 0,
|
||||
}
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key('thread_id');
|
||||
|
||||
__PACKAGE__->belongs_to(
|
||||
thread_subf =>
|
||||
'CharmBoard::Schema::Source::Subforums',
|
||||
{'foreign.subf_id' => 'self.thread_subf'});
|
||||
thread_subf => 'CharmBoard::Schema::Source::Subforums',
|
||||
{ 'foreign.subf_id' => 'self.thread_subf' }
|
||||
);
|
||||
__PACKAGE__->belongs_to(
|
||||
thread_op => 'CharmBoard::Schema::Source::Posts',
|
||||
{'foreign.post_id' => 'self.thread_op'});
|
||||
{ 'foreign.post_id' => 'self.thread_op' }
|
||||
);
|
||||
|
||||
1;
|
||||
__END__
|
|
@ -9,27 +9,34 @@ use base qw(DBIx::Class::Core);
|
|||
|
||||
__PACKAGE__->table('users');
|
||||
__PACKAGE__->add_columns(
|
||||
user_id => {
|
||||
data_type => 'integer',
|
||||
user_id =>
|
||||
{ data_type => 'integer',
|
||||
is_numeric => 1,
|
||||
is_nullable => 0,
|
||||
is_auto_increment => 1, },
|
||||
username => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
email => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
password => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
salt => {
|
||||
data_type => 'text',
|
||||
is_nullable => 0, },
|
||||
signup_date => {
|
||||
data_type => 'integer',
|
||||
is_auto_increment => 1,
|
||||
},
|
||||
username =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
email =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
password =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
salt =>
|
||||
{ data_type => 'text',
|
||||
is_nullable => 0,
|
||||
},
|
||||
signup_date =>
|
||||
{ data_type => 'integer',
|
||||
is_numeric => 1,
|
||||
is_nullable => 0, });
|
||||
is_nullable => 0,
|
||||
}
|
||||
);
|
||||
|
||||
__PACKAGE__->set_primary_key('user_id');
|
||||
|
||||
|
|
|
@ -13,5 +13,3 @@ use Mojolicious::Commands;
|
|||
Mojolicious::Commands->start_app('CharmBoard');
|
||||
|
||||
__END__
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue