DBD-PgAsync

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

        }
    }
    Safefree(string);

    if (TEND_slow) TRC(DBILOGFP, "%sEnd pg_destringify_array\n", THEADER_slow);
    return newRV_noinc((SV*)av);

} /* end of pg_destringify_array */

SV * pg_upgraded_sv(pTHX_ SV *input) {
    U8 *p, *end;
    STRLEN len;
    /* SvPV() can change the value SvUTF8() (for overloaded values and tied values). */
    p = (U8*)SvPV(input, len);
    if(SvUTF8(input)) return input;
    for(end = p + len; p != end; p++) {
        if(*p & 0x80) {
            SV *output = sv_mortalcopy(input);
            sv_utf8_upgrade(output);
            return output;
        }
    }
    return input;
}

SV * pg_downgraded_sv(pTHX_ SV *input) {
    U8 *p, *end;
    STRLEN len;
    /* SvPV() can change the value SvUTF8() (for overloaded values and tied values). */
    p = (U8*)SvPV(input, len);
    if(!SvUTF8(input)) return input;
    for(end = p + len; p != end; p++) {
        if(*p & 0x80) {
            SV *output = sv_mortalcopy(input);
            sv_utf8_downgrade(output, DBDPG_FALSE);
            return output;
        }
    }
    return input;
}

SV * pg_rightgraded_sv(pTHX_ SV *input, bool utf8) {
    return utf8 ? pg_upgraded_sv(aTHX_ input) : pg_downgraded_sv(aTHX_ input);
}

static void pg_db_detect_client_encoding_utf8(pTHX_ imp_dbh_t *imp_dbh) {
    char *clean_encoding;
    int i, j;
    const char * const client_encoding =
        PQparameterStatus(imp_dbh->conn, "client_encoding");
    if (NULL != client_encoding) {
        STRLEN len = strlen(client_encoding);
        New(0, clean_encoding, len + 1, char);
        for (i = 0, j = 0; i < len; i++) {
            const char c = toLOWER(client_encoding[i]);
            if (isALPHA(c) || isDIGIT(c))
                clean_encoding[j++] = c;
        };
        clean_encoding[j] = '\0';
        imp_dbh->client_encoding_utf8 =
            (strnEQ(clean_encoding, "utf8", 4) || strnEQ(clean_encoding, "unicode", 8))
            ? DBDPG_TRUE : DBDPG_FALSE;
        Safefree(clean_encoding);
    }
    else {
        imp_dbh->client_encoding_utf8 = DBDPG_FALSE;
    }
}

/* ================================================================== */
static long do_stmt(SV *dbh, char const *sql, int want_async,
                    async_result_handler *res_handler, void *arg,
                    char *caller)
{
    dTHX;
    D_imp_dbh(dbh);
    PGresult *result;
    imp_sth_t *sth;
    long rows;
    int want_begin, status;

    if (NULL == imp_dbh->conn) {
        pg_error(aTHX_ dbh, PGRES_FATAL_ERROR, "Database handle has been disconnected");
        return STMT_ERR;
    }

    /* Abort if we are in the middle of a copy */
    if (imp_dbh->copystate != 0) {
        if (PGRES_COPY_IN == imp_dbh->copystate) {
            croak("Must call pg_putcopyend before issuing more commands");
        }
        else {
            croak("Must call pg_getcopydata until no more rows before issuing more commands");
        }
    }            

    switch (imp_dbh->async_status) {
    case DBH_NO_ASYNC:
        break;

    case DBH_ASYNC_CONNECT:
    case DBH_ASYNC_CONNECT_POLL:
        croak("Must wait for async connect to finish before issuing commands");

    default:
        croak("Must wait for async query to finish before issuing more commands");
    }

    /* If not autocommit, start a new transaction */
    want_begin = 0;
    if (!imp_dbh->done_begin && !DBIc_has(imp_dbh, DBIcf_AutoCommit)) {
        if (want_async)
            want_begin = 1;
        else {
            status = _result(aTHX_ imp_dbh, "begin");
            if (PGRES_COMMAND_OK != status) {
                TRACE_PQERRORMESSAGE;
                pg_error(aTHX_ dbh, status, PQerrorMessage(imp_dbh->conn));
                if (TEND_slow) TRC(DBILOGFP, "%sEnd %s (error: begin failed)\n", caller, THEADER_slow);
                return STMT_ERR;
            }



( run in 0.530 second using v1.01-cache-2.11-cpan-39bf76dae61 )