<commit_before>package Silki::Schema::Page;

use strict;
use warnings;
use namespace::autoclean;

use Encode qw( decode );
use Fey::Object::Iterator::FromSelect;
use Fey::Placeholder;
use List::AllUtils qw( first );
use Silki::Config;
use Silki::I18N qw( loc );
use Silki::Schema::PageRevision;
use Silki::Schema;
use Silki::Schema::File;
use Silki::Schema::PageTag;
use Silki::Schema::Tag;
use Silki::Schema::Wiki;
use Silki::Types qw( ArrayRef Bool Int Str );
use URI::Escape qw( uri_escape_utf8 uri_unescape );

use Fey::ORM::Table;
use MooseX::ClassAttribute;
use MooseX::Params::Validate qw( validated_list pos_validated_list );

with 'Silki::Role::Schema::URIMaker';

with 'Silki::Role::Schema::SystemLogger' => { methods => ['delete'] };

with 'Silki::Role::Schema::DataValidator' => {
    steps => [
        '_title_is_valid',
        '_title_is_unique',
        '_build_uri_path',
    ],
};

my $Schema = Silki::Schema->Schema();

has_policy 'Silki::Schema::Policy';

has_table( $Schema->table('Page') );

has_one( $Schema->table('User') );

has_one wiki => (
    table   => $Schema->table('Wiki'),
    handles => ['domain'],
);

has_many tags => (
    table       => $Schema->table('Tag'),
    select      => __PACKAGE__->_TagsSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has revision_count => (
    metaclass   => 'FromSelect',
    is          => 'ro',
    isa         => Int,
    lazy        => 1,
    select      => __PACKAGE__->_RevisionCountSelect(),
    bind_params => sub { $_[0]->page_id() },
    clearer     => '_clear_revision_count',
);

class_has _RevisionsSelect => (
    is      => 'ro',
    isa     => 'Fey::SQL::Select',
    lazy    => 1,
    builder => '_BuildRevisionsSelect',
);

has_one most_recent_revision => (
    table       => $Schema->table('PageRevision'),
    select      => __PACKAGE__->_MostRecentRevisionSelect(),
    bind_params => sub { $_[0]->page_id() },
    handles     => {
        content                => 'content',
        last_modified_datetime => 'creation_datetime',
    },
);

has_one first_revision => (
    table       => $Schema->table('PageRevision'),
    select      => __PACKAGE__->_FirstRevisionSelect(),
    bind_params => sub { $_[0]->page_id(), 1 },
    handles     => {
        creation_datetime => 'creation_datetime',
    },
);

query incoming_link_count => (
    select      => __PACKAGE__->_IncomingLinkCountSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has_many incoming_links => (
    table       => $Schema->table('Page'),
    select      => __PACKAGE__->_IncomingLinkSelect(),
    bind_params => sub { $_[0]->page_id() },
);

query file_count => (
    select      => __PACKAGE__->_FileCountSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has_many files => (
    table       => $Schema->table('File'),
    select      => __PACKAGE__->_FileSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has is_front_page => (
    is       => 'ro',
    isa      => Bool,
    lazy     => 1,
    init_arg => undef,
    default  => sub { $_[0]->title() eq $_[0]->wiki()->front_page_title() },
);

class_has _PageViewInsert => (
    is      => 'ro',
    isa     => 'Fey::SQL::Insert',
    lazy    => 1,
    builder => '_BuildPageViewInsert',
);

class_has _PendingPageLinkSelectSQL => (
    is      => 'ro',
    isa     => 'Fey::SQL::Select',
    lazy    => 1,
    builder => '_BuildPendingPageLinkSelectSQL',
);

class_has _PendingPageLinkDeleteSQL => (
    is      => 'ro',
    isa     => 'Fey::SQL::Delete',
    lazy    => 1,
    builder => '_BuildPendingPageLinkDeleteSQL',
);

with 'Silki::Role::Schema::Serializes';

sub _base_uri_path {
    my $self = shift;

    return $self->wiki()->_base_uri_path() . '/page/' . $self->uri_path();
}

around insert => sub {
    my $orig  = shift;
    my $class = shift;

    my $page = $class->$orig(@_);

    my $select = $class->_PendingPageLinkSelectSQL();

    my $dbh = Silki::Schema->DBIManager()->source_for_sql($select)->dbh();

    # XXX - hack but it should work fine
    my $select_sql = $select->sql($dbh) . ' FOR UPDATE';

    my $delete = $class->_PendingPageLinkDeleteSQL();

    my $update_links = sub {
        my $links = $dbh->selectcol_arrayref(
            $select_sql,<commit_msg>Don't include cached_content in serialized output for page<commit_after>package Silki::Schema::Page;

use strict;
use warnings;
use namespace::autoclean;

use Encode qw( decode );
use Fey::Object::Iterator::FromSelect;
use Fey::Placeholder;
use List::AllUtils qw( first );
use Silki::Config;
use Silki::I18N qw( loc );
use Silki::Schema::PageRevision;
use Silki::Schema;
use Silki::Schema::File;
use Silki::Schema::PageTag;
use Silki::Schema::Tag;
use Silki::Schema::Wiki;
use Silki::Types qw( ArrayRef Bool Int Str );
use URI::Escape qw( uri_escape_utf8 uri_unescape );

use Fey::ORM::Table;
use MooseX::ClassAttribute;
use MooseX::Params::Validate qw( validated_list pos_validated_list );

with 'Silki::Role::Schema::URIMaker';

with 'Silki::Role::Schema::SystemLogger' => { methods => ['delete'] };

with 'Silki::Role::Schema::DataValidator' => {
    steps => [
        '_title_is_valid',
        '_title_is_unique',
        '_build_uri_path',
    ],
};

my $Schema = Silki::Schema->Schema();

has_policy 'Silki::Schema::Policy';

has_table( $Schema->table('Page') );

has_one( $Schema->table('User') );

has_one wiki => (
    table   => $Schema->table('Wiki'),
    handles => ['domain'],
);

has_many tags => (
    table       => $Schema->table('Tag'),
    select      => __PACKAGE__->_TagsSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has revision_count => (
    metaclass   => 'FromSelect',
    is          => 'ro',
    isa         => Int,
    lazy        => 1,
    select      => __PACKAGE__->_RevisionCountSelect(),
    bind_params => sub { $_[0]->page_id() },
    clearer     => '_clear_revision_count',
);

class_has _RevisionsSelect => (
    is      => 'ro',
    isa     => 'Fey::SQL::Select',
    lazy    => 1,
    builder => '_BuildRevisionsSelect',
);

has_one most_recent_revision => (
    table       => $Schema->table('PageRevision'),
    select      => __PACKAGE__->_MostRecentRevisionSelect(),
    bind_params => sub { $_[0]->page_id() },
    handles     => {
        content                => 'content',
        last_modified_datetime => 'creation_datetime',
    },
);

has_one first_revision => (
    table       => $Schema->table('PageRevision'),
    select      => __PACKAGE__->_FirstRevisionSelect(),
    bind_params => sub { $_[0]->page_id(), 1 },
    handles     => {
        creation_datetime => 'creation_datetime',
    },
);

query incoming_link_count => (
    select      => __PACKAGE__->_IncomingLinkCountSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has_many incoming_links => (
    table       => $Schema->table('Page'),
    select      => __PACKAGE__->_IncomingLinkSelect(),
    bind_params => sub { $_[0]->page_id() },
);

query file_count => (
    select      => __PACKAGE__->_FileCountSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has_many files => (
    table       => $Schema->table('File'),
    select      => __PACKAGE__->_FileSelect(),
    bind_params => sub { $_[0]->page_id() },
);

has is_front_page => (
    is       => 'ro',
    isa      => Bool,
    lazy     => 1,
    init_arg => undef,
    default  => sub { $_[0]->title() eq $_[0]->wiki()->front_page_title() },
);

class_has _PageViewInsert => (
    is      => 'ro',
    isa     => 'Fey::SQL::Insert',
    lazy    => 1,
    builder => '_BuildPageViewInsert',
);

class_has _PendingPageLinkSelectSQL => (
    is      => 'ro',
    isa     => 'Fey::SQL::Select',
    lazy    => 1,
    builder => '_BuildPendingPageLinkSelectSQL',
);

class_has _PendingPageLinkDeleteSQL => (
    is      => 'ro',
    isa     => 'Fey::SQL::Delete',
    lazy    => 1,
    builder => '_BuildPendingPageLinkDeleteSQL',
);

with 'Silki::Role::Schema::Serializes' => {
    skip => ['cached_content'],
};

sub _base_uri_path {
    my $self = shift;

    return $self->wiki()->_base_uri_path() . '/page/' . $self->uri_path();
}

around insert => sub {
    my $orig  = shift;
    my $class = shift;

    my $page = $class->$orig(@_);

    my $select = $class->_PendingPageLinkSelectSQL();

    my $dbh = Silki::Schema->DBIManager()->source_for_sql($select)->dbh();

    # XXX - hack but it should work fine
    my $select_sql = $select->sql($dbh) . ' FOR UPDATE';

    my $delete = $class->_PendingPageLinkDeleteSQL();

    my $update_links = sub {
        my $links = $dbh->selectcol_arrayref(
            $select_sql,
{'fraction_non_alphanumeric': 0.17789694567498252, 'fraction_numerical': 0.004663091629750525, 'mean_word_length': 3.1087164750957856, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 229, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2065728', 'n_tokens_mistral': 2907, 'n_tokens_neox': 2865, 'n_words': 562}