DBIx-QuickORM

 view release on metacpan or  search on metacpan

worktrees/audit-fixes-master/lib/DBIx/QuickORM/Dialect.pm  view on Meta::CPAN

    load_class($driver) or croak "Could not load '$driver': $@";
    my $dsn_driver = $driver;
    $dsn_driver =~ s/^DBD:://;

    my $db_name = $db->db_name;
    my $dbname_field = $self_or_class->dsn_dbname_field($driver);
    my $dsn = "dbi:${dsn_driver}:${dbname_field}=${db_name};";

    if (my $socket = $db->socket) {
        $dsn .= $self_or_class->dsn_socket_field($driver) . "=$socket";
    }
    elsif (my $host = $db->host) {
        $dsn .= "host=$host;";
        if (my $port = $db->port) {
            $dsn .= "port=$port;";
        }
    }
    else {
        croak "Cannot construct dsn without a host or socket";
    }

    return $dsn;
}

=pod

=item $sql = $dialect->upsert_statement($pk)

Returns the SQL fragment implementing an upsert keyed on the given primary
key columns. Column names are quoted so reserved-word or mixed-case columns
work.

=cut

sub upsert_statement {
    my $self = shift;
    my ($pk) = @_;
    my $dbh = $self->dbh;
    return "ON CONFLICT(" . join(", " => map { $dbh->quote_identifier($_) } @$pk) . ") DO UPDATE SET";
}

sub upsert_noop_assignment {
    my $self = shift;
    my ($quoted_col) = @_;
    # A self-assignment keeps the conflict clause a valid no-op (so RETURNING
    # still yields the row) without changing any data.
    return "$quoted_col = $quoted_col";
}

###############################################################################
# {{{ Schema Builder Code
###############################################################################

=pod

=item $schema = $dialect->build_schema_from_db(%params)

Introspects the live database and returns a L<DBIx::QuickORM::Schema>.
Requires an C<autofill> object. After all tables are built it runs the
autofill C<tables> hook with the complete name-to-table hashref under the
C<tables> key, giving callbacks one place to inspect or adjust the full set.

=cut

sub build_schema_from_db {
    my $self = shift;
    my %params = @_;

    croak "No autofill object provided" unless $params{autofill};

    my $tables = $self->build_tables_from_db(%params);

    # Volatile is a write-time concern, and views are not written through, so a
    # view column that merely inherits a base column's default/identity during
    # introspection should not carry the volatile flag. Clear it before the
    # trigger pass (which does not touch views).
    for my $table (values %$tables) {
        next unless $table->can('is_view') && $table->is_view && $table->can('column_names');
        for my $cname ($table->column_names) {
            my $col = $table->column($cname) or next;
            $col->clear_volatile if $col->can('clear_volatile');
        }
    }

    # Best-effort: flag columns a trigger is seen to modify as volatile, and warn
    # once per table when a table has an insert/update trigger whose effects we
    # cannot resolve (unless the table is asserted volatile-free).
    $self->_apply_trigger_volatility($tables, \%params);

    $params{autofill}->hook(tables => {tables => $tables});

    return DBIx::QuickORM::Schema->new(
        tables => $tables,
    );
}

sub triggers_for_table {
    my $self = shift;
    # Subclasses that support triggers override this to return a list of
    # { event => 'INSERT'|'UPDATE'|'DELETE', body => $trigger_sql } hashrefs for
    # the named table. The base class reports none.
    return ();
}

=pod

=item $tables = $dialect->build_tables_from_db(%params)

=item ($pk, $unique, $links) = $dialect->build_table_keys_from_db($table, %params)

=item $columns = $dialect->build_columns_from_db($table, %params)

=item $indexes = $dialect->build_indexes_from_db($table, %params)

Per-table introspection helpers. Stubs; subclasses override.

=item $affinity = $dialect->affinity_from_db_type(@type_names)

Resolve a storage affinity for a database column type during introspection.
Tries the static type-name map first (the fast, authoritative path); on a miss,
consults the database's own type catalog to turn the name into a numeric SQL



( run in 0.721 second using v1.01-cache-2.11-cpan-85f18b9d64f )