Пример #1
0
/* errorf() callback for PGtypeArgs, see PQputf() and PQgetf().
 * Always returns -1.
 */
int
pqt_argserrorf(PGtypeArgs *args, const char *format, ...)
{
	va_list ap;
	char fqtn[200];

	if (!args || !format || !*format)
		return -1;

	pqt_fqtn(fqtn, sizeof(fqtn), args->typhandler->typschema,
		args->typhandler->typname);

	/* put the header */
	PQseterror("%s[pos:%d] - ", fqtn, args->typpos);

	/* append message from type handler */
	va_start(ap, format);
	vseterror(format, ap, TRUE);
	return -1;
}
Пример #2
0
static int registerSubClass(PGtypeData *connData, const char *type_name,
	PGtypeProc typput, PGtypeProc typget)
{
	char *s;
	PGtypeHandler *h_sub;
	PGtypeHandler *h_base;
	char sub_typschema[PQT_MAXIDLEN + 1];
	char sub_typname[PQT_MAXIDLEN + 1];
	char base_typschema[PQT_MAXIDLEN + 1];
	char base_typname[PQT_MAXIDLEN + 1];
	char sub_fqtn[200];
	char base_fqtn[200];

	if (!(s = parseType(type_name, sub_typschema, sub_typname, 1)))
		return FALSE;

	if (*s != '=')
	{
		PQseterror("Missing inheritence operator '=': %s", type_name);
		return FALSE;
	}

	if (!parseType(s + 1, base_typschema, base_typname, 1))
		return FALSE;

	/* lookup the base handler */
	h_base = pqt_gethandler(connData->typhandlers, connData->typhcnt,
		base_typschema, base_typname);

	if (!h_base)
	{
		PQseterror("typname '%s' does not exist, '%s' cannot sub-class it",
			pqt_fqtn(base_fqtn, sizeof(base_fqtn), base_typschema, base_typname),
			pqt_fqtn(sub_fqtn, sizeof(sub_fqtn), sub_typschema, sub_typname));
		return FALSE;
	}

	/* cannot sub-class a record type */
	if (h_base->typoid == RECORDOID)
	{
		PQseterror("Cannot sub-class pg_catalog.record '%s'",
			pqt_fqtn(sub_fqtn, sizeof(sub_fqtn), sub_typschema, sub_typname));
		return FALSE;
	}

	if (!expandHandlers(connData))
		return FALSE;

	h_sub = &connData->typhandlers[connData->typhcnt];
	memset(h_sub, 0, sizeof(PGtypeHandler));

	h_sub->id = connData->typhcnt + countof(pg_handlers);
	h_sub->typlen = h_base->typlen;
	h_sub->typoid = h_base->typoid;
	h_sub->typoid_array = h_base->typoid_array;
	h_sub->typput = typput;
	h_sub->typget = typget;
	h_sub->base_id = h_base->id;

	pqt_strcpy(h_sub->typschema,
		sizeof(h_sub->typschema), sub_typschema);

	pqt_strcpy(h_sub->typname,
		sizeof(h_sub->typname), sub_typname);

	connData->typhcnt++;
	return TRUE;
}
Пример #3
0
char *pqt_parse(const char *format, PGtypeHandler *h, int hcnt,
                char *stmtBuf, size_t stmtBufLen, PGtypeHandler **out, size_t *stmtPos,
                int *typpos, int *flags)
{
    int specMark;
    char *s = skipQuotes((char *) format);
    char typname[PQT_MAXIDLEN + 1];
    char schema[PQT_MAXIDLEN + 1];
    char tmp[200];

    *out = NULL;

    if (!s)
        return NULL;

    /* found quotes to skip */
    if (s != format)
    {
        if (stmtBuf)
        {
            size_t n = s - format;
            CHKSTMTBUF(n);
            memcpy(stmtBuf + *stmtPos, format, n);
            (*stmtPos) += n;
        }

        return s;
    }

    specMark = *format;
    if (specMark != '%' && specMark != '#')
    {
        if (stmtBuf)
        {
            CHKSTMTBUF(1);
            stmtBuf[*stmtPos] = *format;
            (*stmtPos)++;
        }

        format++;
        return (char *) format;
    }

    /* spec skips % or # */
    if (!(s = pqt_parsetype(format + 1, schema, typname, flags, *typpos + 1)))
        return NULL;

    if (*flags & TYPFLAG_INVALID)
    {
        if (stmtBuf)
        {
            CHKSTMTBUF(1);
            stmtBuf[*stmtPos] = *format++;
            (*stmtPos)++;
            PQseterror(NULL); /* set by pqt_parsetype */
            return (char *) format;
        }

        return NULL;
    }

    (*typpos)++;

    if (!(*out = pqt_gethandler(h, hcnt, schema, typname)))
    {
        PQseterror("Uknown type '%s' (position %d)",
                   pqt_fqtn(tmp, sizeof(tmp), schema, typname), *typpos);
        return NULL;
    }

    if (stmtBuf)
    {
        int n = pqt_snprintf(tmp, sizeof(tmp), "$%d", *typpos);
        CHKSTMTBUF(n);
        memcpy(stmtBuf + *stmtPos, tmp, n);
        (*stmtPos) += n;
    }

    if (!(*out)->typput)
    {
        PGtypeHandler *o = pqt_gethandlerbyid(h, hcnt, h->base_id);
        if (!o || !o->typput)
        {
            PQseterror(
                "Type '%s' doesn't support put operations (position %d)",
                pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, (*out)->typname), *typpos);

            *out = NULL;
            return NULL;
        }

        *out = o;
    }

    if ((*flags & TYPFLAG_POINTER) && !pqt_allowsptr(*out))
    {
        PQseterror(
            "Type '%s' doesn't support putting pointers (position %d)",
            pqt_fqtn(tmp, sizeof(tmp), (*out)->typschema, (*out)->typname), *typpos);

        *out = NULL;
        return NULL;
    }

    if (specMark == '#')
        (*flags) |= TYPFLAG_BYNAME;

    return s;
}