· 7 years ago · Sep 24, 2018, 04:14 AM
1package Proj::Model::User;
2use strict;
3use warnings;
4use utf8;
5
6use parent qw/Proj::Model/;
7use Try::Tiny;
8use Proj::Utils;
9use Proj::Exception;
10
11sub readonly { 0 }
12sub db_name { 'main' }
13sub table_name { 'user' }
14sub column_list { [qw/id name pass mail created_at updated_at/] }
15
16my %add_args = (
17 name => 'Str',
18 pass => 'Str',
19 mail => 'Str',
20 created_at => +{ isa => 'Str', default => sub { Proj::Utils::now_db_datetime() } },
21);
22__PACKAGE__->query(
23 '_add',
24 %add_args,
25 "INSERT INTO @{[ __PACKAGE__->table_name ]}(name, pass, mail, created_at) VALUES (?, ?, ?, ?)"
26);
27sub add {
28 my $self = shift;
29 my $args = $self->args(%add_args);
30
31 my $txn = $self->txn_scope;
32 try {
33 if ($self->fetch_by_name($args->{name})) {
34 Proj::Exception::Model::DuplicateUser->throw;
35 }
36
37 $self->_add(
38 user => $args->{user},
39 pass => Proj::Utils::to_hash($args->{pass}),
40 mail => $args->{mail},
41 created_at => $args->{created_at},
42 );
43 }
44 catch {
45 my $e = $_;
46 $txn->rollback;
47 die $e;
48 };
49 $txn->commit;
50
51 return $self->last_insert_id;
52}
53
54__PACKAGE__->select_row(
55 'fetch_by_id',
56 id => 'Int',
57 "SELECT @{[ join(',', __PACKAGE__->column_list) ]} FROM @{[ __PACKAGE__->table_name ]} WHERE id = ?"
58);
59
60__PACKAGE__->select_row(
61 'fetch_by_name',
62 name => 'Str',
63 "SELECT @{[ join(',', __PACKAGE__->column_list) ]} FROM @{[ __PACKAGE__->table_name ]} WHERE name = ?"
64);
65
66__PACKAGE__->select_row(
67 'fetch_by_mail',
68 mail => 'Str',
69 "SELECT @{[ join(',', __PACKAGE__->column_list) ]} FROM @{[ __PACKAGE__->table_name ]} WHERE mail = ?"
70);
71
72sub fetch_with_auth {
73 my $self = shift;
74 my $args = $self->args(
75 name => 'Str',
76 pass => 'Str',
77 );
78
79 my $row = $self->fetch_by_name($args->{name});
80 if ($row) {
81 return $row if Proj::Utils::to_hash($args->{pass}) eq $row->{pass};
82 }
83}
84
851;
86__DATA__
87CREATE DATABASE IF NOT EXISTS `main`;
88CREATE TABLE `user` (
89 id INTEGER UNSIGNED PRIMARY AUTO_INCREMENT,
90 name VARCHAR(32) BINARY NOT NULL,
91 pass VARCHAR(128) BINARY NOT NULL,
92 mail VARCHAR(128) BINARY NOT NULL,
93 created_at DATETIME NOT NULL,
94 updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
95 UNIQUE KEY name (name),
96 UNIQUE KEY mail (mail)
97);