pointcloud/pgsql/pc_pgsql.c
Paul Ramsey e8a7788d00 Add in XML function to pgsql
Set up XML validation tests
2013-01-18 16:15:39 -08:00

151 lines
2.5 KiB
C

#include "pc_pgsql.h"
#include "executor/spi.h"
PG_MODULE_MAGIC;
static void *
pgsql_alloc(size_t size)
{
void * result;
result = palloc(size);
if ( ! result )
{
ereport(ERROR, (errmsg_internal("Out of virtual memory")));
return NULL;
}
return result;
}
static void *
pgsql_realloc(void *mem, size_t size)
{
void * result;
result = repalloc(mem, size);
return result;
}
static void
pgsql_free(void *ptr)
{
pfree(ptr);
}
static void
pgsql_msg_handler(int sig, const char *fmt, va_list ap)
{
#define MSG_MAXLEN 1024
char msg[MSG_MAXLEN] = {0};
vsnprintf(msg, MSG_MAXLEN, fmt, ap);
msg[MSG_MAXLEN-1] = '\0';
ereport(sig, (errmsg_internal("%s", msg)));
}
static void
pgsql_error(const char *fmt, va_list ap)
{
pgsql_msg_handler(ERROR, fmt, ap);
}
static void
pgsql_warn(const char *fmt, va_list ap)
{
pgsql_msg_handler(WARNING, fmt, ap);
}
static void
pgsql_info(const char *fmt, va_list ap)
{
pgsql_msg_handler(NOTICE, fmt, ap);
}
/* Module loading callback */
void _PG_init(void);
void
_PG_init(void)
{
elog(LOG, "Pointcloud (%s) module loaded", POINTCLOUD_VERSION);
pc_set_handlers(pgsql_alloc, pgsql_realloc,
pgsql_free, pgsql_error,
pgsql_info, pgsql_warn);
}
/* Module unload callback */
void _PG_fini(void);
void
_PG_fini(void)
{
elog(LOG, "Pointcloud (%s) module unloaded", POINTCLOUD_VERSION);
}
/**
* TODO: Back this routine with a statement level memory cache.
*/
PCSCHEMA *
pc_get_schema_by_id(uint32_t pcid)
{
char sql[256];
char *xml, *xml_spi;
int err;
size_t size;
PCSCHEMA *schema;
if (SPI_OK_CONNECT != SPI_connect ())
{
elog(NOTICE, "pc_get_schema_by_id: could not connect to SPI manager");
SPI_finish();
return NULL;
}
sprintf(sql, "select %s from %s where pcid = %d", POINTCLOUD_FORMATS, POINTCLOUD_FORMATS_XML, pcid);
err = SPI_exec(sql, 1);
if ( err < 0 )
{
elog(NOTICE, "pc_get_schema_by_id: error (%d) executing query: %s", err, sql);
SPI_finish();
return NULL;
}
/* No entry in POINTCLOUD_FORMATS */
if (SPI_processed <= 0)
{
SPI_finish();
return NULL;
}
/* Result */
xml_spi = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1);
/* NULL result */
if ( ! xml_spi )
{
SPI_finish();
return NULL;
}
/* Copy result to upper executor context */
size = strlen(xml_spi) + 1;
xml = SPI_palloc(size);
memcpy(xml, xml_spi, size);
/* Disconnect from SPI */
SPI_finish();
/* Build the schema object */
schema = pc_schema_from_xml(xml);
if ( ! schema )
{
elog(ERROR, "unable to parse XML representation of schema");
}
return schema;
}