App-Sqitch

 view release on metacpan or  search on metacpan

lib/App/Sqitch/Engine/clickhouse.pm  view on Meta::CPAN

    # LIMIT/OFFSET don't support parameters, alas. So just put them in the query.
    my ($self, $lim, $off)  = @_;
    return ["LIMIT $lim", "OFFSET $off"], [] if $lim && $off;
    return ["LIMIT $lim"], [] if $lim;
    return ["OFFSET $off"], [] if $off;
    return [], [];
}

# ClickHouse ODBC does not support arrays. So we must parse them manually.
# I'd rather not do an eval, so rip this out once the issue is fixed.
# https://github.com/clickHouse/clickhouse-odbc/issues/525
sub _parse_array {
    no utf8;
    return [] unless $_[1];
    my $list = eval $_[1];
    return [] unless $list;
    shift @{ $list } if @{ $list } && $list->[0] eq '';
    return $list;
}

sub _version_query { 'SELECT CAST(ROUND(MAX(version), 1) AS CHAR) FROM releases' }

sub _initialized {
    my $self = shift;
    return try {
        $self->dbh->selectcol_arrayref(q{
            SELECT true
             FROM information_schema.tables
            WHERE TABLE_CATALOG = current_database()
              AND TABLE_SCHEMA  = ?
              AND TABLE_NAME    = ?
        }, undef, $self->registry, 'changes')->[0]
    } catch {
        return 0 if $DBI::state && $DBI::state eq 'HY000';
        die $_;
    }
}

sub _initialize {
    my $self   = shift;
    hurl engine => __x(
        'Sqitch database {database} already initialized',
        database => $self->registry,
    ) if $self->initialized;

    # Create the Sqitch database if it does not exist.
    (my $db = $self->registry) =~ s/"/""/g;
    $self->_run(
        '--query' => sprintf(
            q{CREATE DATABASE IF NOT EXISTS "%s" COMMENT 'Sqitch database deployment metadata v%s'},
            $self->registry, $self->registry_release,
        ),
    );

    # Deploy the registry to the Sqitch database.
    $self->run_upgrade( file(__FILE__)->dir->file('clickhouse.sql') );
    $self->_register_release;
}

sub _no_table_error  {
    # /HTTP status code: 404$/
    return $DBI::state && $DBI::state eq 'HY000'; # General Error
}

sub _no_column_error  {
    return $DBI::state && $DBI::state eq '42703'; # ERRCODE_UNDEFINED_COLUMN
}

sub _unique_error  {
    # ClickHouse doe not support unique constraints.
    return 0;
}

sub _regex_op { 'REGEXP' }

sub _listagg_format { q{groupArraySorted(10000)(%1$s)} }

sub _cid {
    my ( $self, $ord, $offset, $project ) = @_;

    my $off = $offset ? " OFFSET $offset" : '';
    return try {
        return $self->dbh->selectcol_arrayref(qq{
            SELECT change_id
              FROM changes
             WHERE project = ?
             ORDER BY committed_at $ord
             LIMIT 1$off
        }, undef, $project || $self->plan->project)->[0];
    } catch {
        return if $self->_no_table_error && !$self->initialized;
        die $_;
    };
}

# Override to query for existing tags separately.
sub _log_event {
    my ( $self, $event, $change, $tags, $requires, $conflicts) = @_;
    my $dbh    = $self->dbh;
    my $sqitch = $self->sqitch;

    $tags      ||= $self->_log_tags_param($change);
    $requires  ||= $self->_log_requires_param($change);
    $conflicts ||= $self->_log_conflicts_param($change);

    # Use the array() constructor to insert arrays of values. Remove if
    # https://github.com/clickHouse/clickhouse-odbc/issues/525 fixed.
    my $tag_ph = 'array('. join(', ', ('?') x @{ $tags      }) . ')';
    my $req_ph = 'array('. join(', ', ('?') x @{ $requires  }) . ')';
    my $con_ph = 'array('. join(', ', ('?') x @{ $conflicts }) . ')';
    my $ts     = $self->_ts_default;

    $dbh->do(qq{
        INSERT INTO events (
              event
            , change_id
            , change
            , project
            , note
            , tags
            , requires



( run in 2.341 seconds using v1.01-cache-2.11-cpan-437f7b0c052 )