db: rework schema and infrastructure
This commit is contained in:
parent
fbcaea8bfc
commit
13a6d287af
@ -1,62 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
err()
|
|
||||||
{
|
|
||||||
printf "%s: %s\n" "${0##*/}" "$*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
warn()
|
|
||||||
{
|
|
||||||
printf "%s: %s\n" "${0##*/}" "$*" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
check_required_programs()
|
|
||||||
{
|
|
||||||
_rc=0
|
|
||||||
for _prog; do
|
|
||||||
if ! command -v "$_prog" >/dev/null; then
|
|
||||||
_rc=1
|
|
||||||
warn "$_prog: not found"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return $_rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
check_required_programs sqlite3 dbicdump || exit 1
|
|
||||||
|
|
||||||
sqlite3 "db/PoorBooru.db" <<'_SQL'
|
|
||||||
PRAGMA foreig_keys = ON;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS media(
|
|
||||||
media_id INTEGER PRIMARY KEY,
|
|
||||||
content BLOB (10485760) NOT NULL,
|
|
||||||
filename TEXT (255) NOT NULL,
|
|
||||||
content_type TEXT (255)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS tags(
|
|
||||||
tag_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT (255) NOT NULL UNIQUE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS media_tags(
|
|
||||||
media_id INTEGER NOT NULL,
|
|
||||||
tag_id INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (media_id) REFERENCES media (media_id) ON DELETE CASCADE,
|
|
||||||
FOREIGN KEY (tag_id) REFERENCES tags (tag_id) ON DELETE CASCADE,
|
|
||||||
PRIMARY KEY(media_id, tag_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE VIEW IF NOT EXISTS tags_count_view AS SELECT
|
|
||||||
tags.tag_id AS tag_id,
|
|
||||||
tags.name AS name,
|
|
||||||
COUNT(media_tags.media_id) AS count
|
|
||||||
FROM tags
|
|
||||||
INNER JOIN media_tags USING (tag_id)
|
|
||||||
GROUP BY tag_id;
|
|
||||||
|
|
||||||
_SQL
|
|
||||||
|
|
||||||
dbicdump -o dump_directory=./lib PoorBooru::Schema dbi:SQLite:db/PoorBooru.db
|
|
22
bin/migrate.pl
Normal file
22
bin/migrate.pl
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env perl
|
||||||
|
use v5.36;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use DBIx::Class::Schema::Loader qw(make_schema_at);
|
||||||
|
use DBIx::Migration;
|
||||||
|
use Mojo::File qw(curfile);
|
||||||
|
|
||||||
|
my $parent = curfile->dirname;
|
||||||
|
my $dsn = "dbi:SQLite:" . $parent->sibling("db", "PoorBooru.db")->to_string;
|
||||||
|
|
||||||
|
DBIx::Migration->new({
|
||||||
|
dsn => $dsn,
|
||||||
|
dir => $parent->sibling("migrations")->to_string,
|
||||||
|
})->migrate or die "couldn't run migration";
|
||||||
|
|
||||||
|
make_schema_at(
|
||||||
|
"PoorBooru::Schema",
|
||||||
|
{ dump_directory => $parent->sibling("lib")->to_string },
|
||||||
|
[ $dsn ],
|
||||||
|
);
|
@ -29,35 +29,35 @@ __PACKAGE__->table("media");
|
|||||||
is_auto_increment: 1
|
is_auto_increment: 1
|
||||||
is_nullable: 0
|
is_nullable: 0
|
||||||
|
|
||||||
=head2 content
|
=head2 seaweedfs_fid
|
||||||
|
|
||||||
data_type: 'blob'
|
data_type: 'text'
|
||||||
is_nullable: 0
|
is_nullable: 0
|
||||||
size: 10485760
|
size: 33
|
||||||
|
|
||||||
=head2 filename
|
=head2 filename
|
||||||
|
|
||||||
data_type: 'text'
|
data_type: 'text'
|
||||||
is_nullable: 0
|
is_nullable: 0
|
||||||
size: 255
|
size: 256
|
||||||
|
|
||||||
=head2 content_type
|
=head2 content_type
|
||||||
|
|
||||||
data_type: 'text'
|
data_type: 'text'
|
||||||
is_nullable: 1
|
is_nullable: 1
|
||||||
size: 255
|
size: 256
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->add_columns(
|
__PACKAGE__->add_columns(
|
||||||
"media_id",
|
"media_id",
|
||||||
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
||||||
"content",
|
"seaweedfs_fid",
|
||||||
{ data_type => "blob", is_nullable => 0, size => 10485760 },
|
{ data_type => "text", is_nullable => 0, size => 33 },
|
||||||
"filename",
|
"filename",
|
||||||
{ data_type => "text", is_nullable => 0, size => 255 },
|
{ data_type => "text", is_nullable => 0, size => 256 },
|
||||||
"content_type",
|
"content_type",
|
||||||
{ data_type => "text", is_nullable => 1, size => 255 },
|
{ data_type => "text", is_nullable => 1, size => 256 },
|
||||||
);
|
);
|
||||||
|
|
||||||
=head1 PRIMARY KEY
|
=head1 PRIMARY KEY
|
||||||
@ -100,8 +100,8 @@ Composing rels: L</media_tags> -> tag
|
|||||||
__PACKAGE__->many_to_many("tags", "media_tags", "tag");
|
__PACKAGE__->many_to_many("tags", "media_tags", "tag");
|
||||||
|
|
||||||
|
|
||||||
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-02-18 09:09:31
|
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-03-04 20:47:27
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:X0A6CSw6yWOYvxhMNRoS0g
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:E7eWNfGOqqI1Kub7Vv/WHQ
|
||||||
|
|
||||||
|
|
||||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||||
|
@ -33,7 +33,7 @@ __PACKAGE__->table("tags");
|
|||||||
|
|
||||||
data_type: 'text'
|
data_type: 'text'
|
||||||
is_nullable: 0
|
is_nullable: 0
|
||||||
size: 255
|
size: 256
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ __PACKAGE__->add_columns(
|
|||||||
"tag_id",
|
"tag_id",
|
||||||
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
{ data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
|
||||||
"name",
|
"name",
|
||||||
{ data_type => "text", is_nullable => 0, size => 255 },
|
{ data_type => "text", is_nullable => 0, size => 256 },
|
||||||
);
|
);
|
||||||
|
|
||||||
=head1 PRIMARY KEY
|
=head1 PRIMARY KEY
|
||||||
@ -98,8 +98,8 @@ Composing rels: L</media_tags> -> media
|
|||||||
__PACKAGE__->many_to_many("medias", "media_tags", "media");
|
__PACKAGE__->many_to_many("medias", "media_tags", "media");
|
||||||
|
|
||||||
|
|
||||||
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-02-18 09:09:31
|
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-03-04 20:04:03
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:tlbIFVg6S6LAWWiR0ioHFw
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:d5XP9DAiUTQzW1+c3qph4w
|
||||||
|
|
||||||
|
|
||||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use utf8;
|
use utf8;
|
||||||
package PoorBooru::Schema::Result::TagsCountView;
|
package PoorBooru::Schema::Result::TagCountView;
|
||||||
|
|
||||||
# Created by DBIx::Class::Schema::Loader
|
# Created by DBIx::Class::Schema::Loader
|
||||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
PoorBooru::Schema::Result::TagsCountView
|
PoorBooru::Schema::Result::TagCountView
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
@ -16,11 +16,11 @@ use warnings;
|
|||||||
use base 'DBIx::Class::Core';
|
use base 'DBIx::Class::Core';
|
||||||
__PACKAGE__->table_class("DBIx::Class::ResultSource::View");
|
__PACKAGE__->table_class("DBIx::Class::ResultSource::View");
|
||||||
|
|
||||||
=head1 TABLE: C<tags_count_view>
|
=head1 TABLE: C<tag_count_view>
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->table("tags_count_view");
|
__PACKAGE__->table("tag_count_view");
|
||||||
|
|
||||||
=head1 ACCESSORS
|
=head1 ACCESSORS
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ __PACKAGE__->table("tags_count_view");
|
|||||||
|
|
||||||
data_type: 'text'
|
data_type: 'text'
|
||||||
is_nullable: 1
|
is_nullable: 1
|
||||||
size: 255
|
size: 256
|
||||||
|
|
||||||
=head2 count
|
=head2 count
|
||||||
|
|
||||||
@ -46,14 +46,14 @@ __PACKAGE__->add_columns(
|
|||||||
"tag_id",
|
"tag_id",
|
||||||
{ data_type => "integer", is_nullable => 1 },
|
{ data_type => "integer", is_nullable => 1 },
|
||||||
"name",
|
"name",
|
||||||
{ data_type => "text", is_nullable => 1, size => 255 },
|
{ data_type => "text", is_nullable => 1, size => 256 },
|
||||||
"count",
|
"count",
|
||||||
{ data_type => "", is_nullable => 1 },
|
{ data_type => "", is_nullable => 1 },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-02-18 09:09:31
|
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2023-03-04 20:01:07
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9NUzqweyXVu/G84fxb3eew
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SbewAyRFuSCJXVLv6b5y0g
|
||||||
|
|
||||||
|
|
||||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
6
migrations/1_down.sql
Normal file
6
migrations/1_down.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-- DROP VIEW tagged_media_view;
|
||||||
|
DROP VIEW tag_count_view;
|
||||||
|
DROP TABLE media_tags;
|
||||||
|
DROP TABLE tags;
|
||||||
|
DROP TABLE media_content;
|
||||||
|
DROP TABLE media;
|
35
migrations/1_up.sql
Normal file
35
migrations/1_up.sql
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
CREATE TABLE media(
|
||||||
|
media_id INTEGER PRIMARY KEY,
|
||||||
|
seaweedfs_fid TEXT (33) NOT NULL,
|
||||||
|
filename TEXT (256) NOT NULL,
|
||||||
|
content_type TEXT (256)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tags(
|
||||||
|
tag_id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT (256) NOT NULL UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE media_tags(
|
||||||
|
media_id INTEGER NOT NULL,
|
||||||
|
tag_id INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY (media_id) REFERENCES media (media_id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (tag_id) REFERENCES tags (tag_id) ON DELETE CASCADE,
|
||||||
|
PRIMARY KEY(media_id, tag_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE VIEW tag_count_view AS SELECT
|
||||||
|
tags.tag_id AS tag_id,
|
||||||
|
tags.name AS name,
|
||||||
|
COUNT(media_tags.media_id) AS count
|
||||||
|
FROM tags
|
||||||
|
INNER JOIN media_tags USING (tag_id)
|
||||||
|
GROUP BY tag_id;
|
||||||
|
|
||||||
|
-- CREATE VIEW tagged_media_view AS SELECT
|
||||||
|
-- tags.tag_id AS tag_id,
|
||||||
|
-- tags.name AS tag_name,
|
||||||
|
-- media.media_id AS media_id
|
||||||
|
-- FROM media
|
||||||
|
-- INNER JOIN media_tags USING (media_id)
|
||||||
|
-- INNER JOIN tags USING (tag_id);
|
Loading…
Reference in New Issue
Block a user