/
Table.pm
78 lines (68 loc) · 2.06 KB
/
Table.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use v6;
role Soonish::Table {
has Int $.id is rw;
method !set_id($id) { $!id = $id }
has $._schema;
method table {
self.^name.split('::')[*-1].lc;
}
method attributes {
self.^attributes.map(*.Str.substr(2)).grep({ .substr(0,1) ne '_' }).map({; $_ => self."$_"()}).hash;
}
method insert-or-create() {
self.id ?? self.update !! self.insert;
}
method insert() {
my %a := self.attributes;
my $id = %a.delete('id');
if $id {
die "Cannot insert an object that already has an id!";
}
my $dbh = $._schema.dbh;
my @values = %a.values.map({ self.typemap($_) });
my $sql = join ' ',
"INSERT INTO $dbh.quote-identifier($.table) ( ",
%a.keys.map({$dbh.quote-identifier($_)}).join(', '),
') VALUES (',
('?' xx %a.elems).join(', '),
') RETURNING id';
my $sth = $dbh.prepare($sql);
$sth.execute(@values);
$id = $sth.fetchrow[0].Int;
$.id = $id;
$sth.finish;
self;
}
method update() {
my %a := self.attributes;
my $id = %a.delete('id');
unless $.id {
die "Can only update an object that already has an id!";
}
my $dbh = $._schema.dbh;
my @values = %a.values.map({ self.typemap($_) });
my $sql = join ' ',
"UPDATE $dbh.quote-identifier($.table) SET ",
%a.keys.map({$dbh.quote-identifier($_) ~ " = ?"}).join(', '),
' WHERE ',
$dbh.quote-identifier('id'),
' = ?',
;
my $sth = $dbh.prepare($sql);
$sth.execute(@values, $.id);
$sth.finish;
self;
}
method insert-or-update() {
$.id ?? $.update !! $.insert;
}
method typemap($obj) {
if $obj ~~ Soonish::Table {
$obj.id ?? $obj !! $obj.insert;
$obj.id;
}
else {
$obj;
}
}
}