/**
 * Delete the entry with the lowest expiration value
 * from the datacache right now.
 *
 * @param cls closure (our `struct Plugin`)
 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
 */
static int
postgres_plugin_del (void *cls)
{
  struct Plugin *plugin = cls;
  uint32_t size;
  uint32_t oid;
  struct GNUNET_HashCode key;
  PGresult *res;

  res = PQexecPrepared (plugin->dbh,
                        "getm",
                        0, NULL, NULL, NULL, 1);
  if (GNUNET_OK !=
      GNUNET_POSTGRES_check_result (plugin->dbh,
                                    res,
                                    PGRES_TUPLES_OK,
                                    "PQexecPrepared",
                                    "getm"))
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
	 "Ending iteration (postgres error)\n");
    return 0;
  }
  if (0 == PQntuples (res))
  {
    /* no result */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
	 "Ending iteration (no more results)\n");
    PQclear (res);
    return GNUNET_SYSERR;
  }
  if ((3 != PQnfields (res)) || (sizeof (size) != PQfsize (res, 0)) ||
      (sizeof (oid) != PQfsize (res, 1)) ||
      (sizeof (struct GNUNET_HashCode) != PQgetlength (res, 0, 2)))
  {
    GNUNET_break (0);
    PQclear (res);
    return 0;
  }
  size = ntohl (*(uint32_t *) PQgetvalue (res, 0, 0));
  oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1));
  memcpy (&key, PQgetvalue (res, 0, 2), sizeof (struct GNUNET_HashCode));
  PQclear (res);
  if (GNUNET_OK !=
      GNUNET_POSTGRES_delete_by_rowid (plugin->dbh,
                                       "delrow",
                                       oid))
    return GNUNET_SYSERR;
  plugin->num_items--;
  plugin->env->delete_notify (plugin->env->cls,
                              &key,
                              size + OVERHEAD);
  return GNUNET_OK;
}
Esempio n. 2
0
static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno)
{
	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
	struct pdo_column_data *cols = stmt->columns;
	struct pdo_bound_param_data *param;
	char *str;

	if (!S->result) {
		return 0;
	}

	str = PQfname(S->result, colno);
	cols[colno].name = zend_string_init(str, strlen(str), 0);
	cols[colno].maxlen = PQfsize(S->result, colno);
	cols[colno].precision = PQfmod(S->result, colno);
	S->cols[colno].pgsql_type = PQftype(S->result, colno);

	switch (S->cols[colno].pgsql_type) {

		case BOOLOID:
			cols[colno].param_type = PDO_PARAM_BOOL;
			break;

		case OIDOID:
			/* did the user bind the column as a LOB ? */
			if (stmt->bound_columns && (
					(param = zend_hash_index_find_ptr(stmt->bound_columns, colno)) != NULL ||
					(param = zend_hash_find_ptr(stmt->bound_columns, cols[colno].name)) != NULL)) {

				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
					cols[colno].param_type = PDO_PARAM_LOB;
					break;
				}
			}
			cols[colno].param_type = PDO_PARAM_INT;
			break;

		case INT2OID:
		case INT4OID:
			cols[colno].param_type = PDO_PARAM_INT;
			break;

		case INT8OID:
			if (sizeof(zend_long)>=8) {
				cols[colno].param_type = PDO_PARAM_INT;
			} else {
				cols[colno].param_type = PDO_PARAM_STR;
			}
			break;

		case BYTEAOID:
			cols[colno].param_type = PDO_PARAM_LOB;
			break;

		default:
			cols[colno].param_type = PDO_PARAM_STR;
	}

	return 1;
}
Esempio n. 3
0
   int CPgsqlResultHandler::extractValueAsInt(const int columnIndex)
   {
      char * valuePoint = PQgetvalue(m_res, m_currentResultIndex, columnIndex);
      int result = 0;
      if (PQbinaryTuples(m_res) == 1)
      {
         int nbBytes = PQfsize(m_res, columnIndex);

         switch (nbBytes)
         {
         case 8:
            result = Poco::ByteOrder::fromNetwork(*((Poco::Int64 *)valuePoint));
            break;
         default:
         case 4:
            result = Poco::ByteOrder::fromNetwork(*((Poco::Int32 *)valuePoint));
            break;
         case 2:
            result = Poco::ByteOrder::fromNetwork(*((Poco::Int16 *)valuePoint));
            break;
         }
      }
      else
      {
         result = atoi(valuePoint);
      }
      return result;
   }
Esempio n. 4
0
QSqlRecord QPSQLResult::record() const
{
    QSqlRecord info;
    if (!isActive() || !isSelect())
        return info;

    int count = PQnfields(d->result);
    for (int i = 0; i < count; ++i) {
        QSqlField f;
        if (d->driver->isUtf8)
            f.setName(QString::fromUtf8(PQfname(d->result, i)));
        else
            f.setName(QString::fromLocal8Bit(PQfname(d->result, i)));
        f.setType(qDecodePSQLType(PQftype(d->result, i)));
        int len = PQfsize(d->result, i);
        int precision = PQfmod(d->result, i);
        // swap length and precision if length == -1
        if (len == -1 && precision > -1) {
            len = precision - 4;
            precision = -1;
        }
        f.setLength(len);
        f.setPrecision(precision);
        f.setSqlType(PQftype(d->result, i));
        info.append(f);
    }
    return info;
}
Esempio n. 5
0
File: psql.c Progetto: aosm/X11
LispObj *
Lisp_PQfsize(LispBuiltin *builtin)
/*
 pq-fsize result field-number
 */
{
    int size, field;
    PGresult *res;

    LispObj *result, *field_number;

    field_number = ARGUMENT(1);
    result = ARGUMENT(0);

    if (!CHECKO(result, PGresult_t))
	LispDestroy("%s: cannot convert %s to PGresult*",
		    STRFUN(builtin), STROBJ(result));
    res = (PGresult*)(result->data.opaque.data);

    CHECK_INDEX(field_number);
    field = FIXNUM_VALUE(field_number);

    size = PQfsize(res, field);

    return (INTEGER(size));
}
Esempio n. 6
0
/*
 *	Read in field descriptions from a libpq result set.
 *	If self is not null, then also store the information.
 *	If self is null, then just read, don't store.
 */
BOOL
CI_read_fields_from_pgres(ColumnInfoClass *self, PGresult *pgres)
{
	CSTR		func = "CI_read_fields";
	Int2		lf;
	int			new_num_fields;
	OID		new_adtid, new_relid = 0, new_attid = 0;
	Int2		new_adtsize;
	Int4		new_atttypmod = -1;
	char	   *new_field_name;

	/* at first read in the number of fields that are in the query */
	new_num_fields = PQnfields(pgres);

	mylog("num_fields = %d\n", new_num_fields);

	if (self)
	{
		/* according to that allocate memory */
		CI_set_num_fields(self, new_num_fields);
		if (NULL == self->coli_array)
			return FALSE;
	}

	/* now read in the descriptions */
	for (lf = 0; lf < new_num_fields; lf++)
	{
		new_field_name = PQfname(pgres, lf);
		new_relid = PQftable(pgres, lf);
		new_attid = PQftablecol(pgres, lf);
		new_adtid = PQftype(pgres, lf);
		new_adtsize = PQfsize(pgres, lf);

		mylog("READING ATTTYPMOD\n");
		new_atttypmod = PQfmod(pgres, lf);

		/* Subtract the header length */
		switch (new_adtid)
		{
			case PG_TYPE_DATETIME:
			case PG_TYPE_TIMESTAMP_NO_TMZONE:
			case PG_TYPE_TIME:
			case PG_TYPE_TIME_WITH_TMZONE:
				break;
			default:
				new_atttypmod -= 4;
		}
		if (new_atttypmod < 0)
			new_atttypmod = -1;

		mylog("%s: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d (rel,att)=(%d,%d)\n", func, new_field_name, new_adtid, new_adtsize, new_atttypmod, new_relid, new_attid);

		if (self)
			CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod, new_relid, new_attid);
	}

	return TRUE;
}
Esempio n. 7
0
/*
 * call-seq:
 *    res.fsize( index )
 *
 * Returns the size of the field type in bytes.  Returns <tt>-1</tt> if the field is variable sized.
 *
 *   res = conn.exec("SELECT myInt, myVarChar50 FROM foo")
 *   res.size(0) => 4
 *   res.size(1) => -1
 */
static VALUE
pgresult_fsize(VALUE self, VALUE index)
{
	PGresult *result;
	int i = NUM2INT(index);

	result = pgresult_get(self);
	if (i < 0 || i >= PQnfields(result)) {
		rb_raise(rb_eArgError,"invalid field number %d", i);
	}
	return INT2NUM(PQfsize(result, i));
}
Esempio n. 8
0
void show_column_info(PGresult* result)
{
  int num_columns=0;
  int i;
  if(!result)
    return;
  num_columns=PQnfields(result);
  printf("%d columns in the result set\n",num_columns);

  for(i=0;i<num_columns;i++)
    printf("Field: %d,Name: %s,Internal size: %d\n",
	   i,
	   PQfname(result,i),
	   PQfsize(result,i));
}
Esempio n. 9
0
/*
 * Build "struct sqlda_compat" (metadata only) from PGresult
 * leaving enough space for the field values in
 * the given row number
 */
struct sqlda_compat *
ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat)
{
	struct sqlda_compat *sqlda;
	struct sqlvar_compat *sqlvar;
	char	   *fname;
	long		size;
	int			sqld;
	int			i;

	size = sqlda_compat_total_size(res, row, compat);
	sqlda = (struct sqlda_compat *) ecpg_alloc(size, line);
	if (!sqlda)
		return NULL;

	memset(sqlda, 0, size);
	sqlvar = (struct sqlvar_compat *) (sqlda + 1);
	sqld = PQnfields(res);
	fname = (char *) (sqlvar + sqld);

	sqlda->sqld = sqld;
	ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld);
	sqlda->desc_occ = size;		/* cheat here, keep the full allocated size */
	sqlda->sqlvar = sqlvar;

	for (i = 0; i < sqlda->sqld; i++)
	{
		sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat);
		strcpy(fname, PQfname(res, i));
		sqlda->sqlvar[i].sqlname = fname;
		fname += strlen(sqlda->sqlvar[i].sqlname) + 1;

		/*
		 * this is reserved for future use, so we leave it empty for the time
		 * being
		 */
		/* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i); */
		sqlda->sqlvar[i].sqlxid = PQftype(res, i);
		sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
	}

	return sqlda;
}
Esempio n. 10
0
File: mpq.c Progetto: Athas/mosml
/* ML type : pgresult_ -> int -> int */
EXTERNML value pq_fsize(value pgresval, value fieldno) 
{
  checkfbound(PGresult_val(pgresval), Long_val(fieldno), "pq_ftype");
  return Val_long(PQfsize(PGresult_val(pgresval), Long_val(fieldno)));
}
Esempio n. 11
0
/*************************************************************
 *Returns the size in bytes of the field associated with the
 given field index. If the size returned is -1, the field is
 a variable length field. Field indices
     start at 0.
 *************************************************************/
int
dbi_fieldsize(DBI_result *result_id,
              int field_num)
{
  return(PQfsize(result_id, field_num));
}
Esempio n. 12
0
GSQLCursorState
pgsql_cursor_open (GSQLCursor *cursor) {
	GSQL_TRACE_FUNC;
	PGconn *pgconn;
	GSQLEPGSQLSession *e_session = NULL;
	GSQLEPGSQLCursor  *e_cursor = NULL;
	GSQLEPGSQLVariable *e_var;
	GSQLVariable *var;
	GSQLWorkspace *workspace = NULL;
	PGSQL_FIELD *field;
	gulong n, n_fields, is_null = 1;
	gchar error_str[2048];
  
	g_return_val_if_fail (GSQL_IS_CURSOR(cursor), GSQL_CURSOR_STATE_ERROR);
	g_return_val_if_fail (GSQL_IS_SESSION(cursor->session), 
	                      GSQL_CURSOR_STATE_ERROR);
	e_session = cursor->session->spec;

	workspace = gsql_session_get_workspace (cursor->session);
	g_return_val_if_fail(GSQL_IS_WORKSPACE(workspace), 
	                     GSQL_CURSOR_STATE_ERROR);
	
	pgconn = e_session->pgconn;
	
	if (!pgsql_cursor_prepare (cursor)) {
		return GSQL_CURSOR_STATE_ERROR;
	}
	
	e_cursor = cursor->spec;
	e_cursor->result = PQexec(e_session->pgconn, cursor->sql);

	if ( ! e_cursor->result ) {
		g_sprintf ( error_str, "Error occured: %s",
			    pgsql_session_get_error(cursor->session) );
		gsql_message_add (workspace, GSQL_MESSAGE_ERROR, error_str);
    
		return GSQL_CURSOR_STATE_ERROR;
	}
	
	pgsql_cursor_statement_detect (cursor);

	n_fields =  PQnfields (e_cursor->result);
	if (n_fields == 0 && 
	    PQresultStatus(e_cursor->result) == PGRES_COMMAND_OK)
		return GSQL_CURSOR_STATE_OPEN;

	if (n_fields == 0 && 
	    PQresultStatus(e_cursor->result) != PGRES_COMMAND_OK) {
		g_sprintf ( error_str, "Error occured: %s", 
			    pgsql_session_get_error(cursor->session) );
		gsql_message_add (workspace, GSQL_MESSAGE_ERROR, error_str);
		return GSQL_CURSOR_STATE_ERROR;
	}
	
	for (n = 0; n < n_fields; n++) {
		// where to free this?!?
		field = g_malloc0 ( sizeof(PGSQL_FIELD) );
		field->name = PQfname(e_cursor->result, n);
		field->type = PQftype(e_cursor->result, n);
		field->size = PQfsize(e_cursor->result, n);

		var = gsql_variable_new ();
		pgsql_variable_init (var, field);
		cursor->var_list = g_list_append (cursor->var_list, var);
	}

	return GSQL_CURSOR_STATE_OPEN;
}
Esempio n. 13
0
/**********************************
 * pg_result
 get information about the results of a query

 syntax:

	pg_result result ?option?

 the options are:

	-status		the status of the result

	-error		the error message, if the status indicates error; otherwise
				an empty string

	-conn		the connection that produced the result

	-oid		if command was an INSERT, the OID of the inserted tuple

	-numTuples	the number of tuples in the query

	-cmdTuples	the number of tuples affected by the query

	-numAttrs	returns the number of attributes returned by the query

	-assign arrayName
				assign the results to an array, using subscripts of the form
				(tupno,attributeName)

	-assignbyidx arrayName ?appendstr?
				assign the results to an array using the first field's value
				as a key.
				All but the first field of each tuple are stored, using
				subscripts of the form (field0value,attributeNameappendstr)

	-getTuple tupleNumber
				returns the values of the tuple in a list

	-tupleArray tupleNumber arrayName
				stores the values of the tuple in array arrayName, indexed
				by the attributes returned

	-attributes
				returns a list of the name/type pairs of the tuple attributes

	-lAttributes
				returns a list of the {name type len} entries of the tuple
				attributes

	-clear		clear the result buffer. Do not reuse after this

 **********************************/
int
Pg_result(ClientData cData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
{
	PGresult   *result;
	const char *opt;
	int			i;
	int			tupno;
	CONST84 char *arrVar;
	char		nameBuffer[256];
	const char *appendstr;

	if (argc < 3 || argc > 5)
	{
		Tcl_AppendResult(interp, "Wrong # of arguments\n", 0);
		goto Pg_result_errReturn;		/* append help info */
	}

	result = PgGetResultId(interp, argv[1]);
	if (result == (PGresult *) NULL)
	{
		Tcl_AppendResult(interp, "\n",
						 argv[1], " is not a valid query result", 0);
		return TCL_ERROR;
	}

	opt = argv[2];

	if (strcmp(opt, "-status") == 0)
	{
		Tcl_AppendResult(interp, PQresStatus(PQresultStatus(result)), 0);
		return TCL_OK;
	}
	else if (strcmp(opt, "-error") == 0)
	{
		Tcl_SetResult(interp, (char *) PQresultErrorMessage(result),
					  TCL_STATIC);
		return TCL_OK;
	}
	else if (strcmp(opt, "-conn") == 0)
		return PgGetConnByResultId(interp, argv[1]);
	else if (strcmp(opt, "-oid") == 0)
	{
		sprintf(interp->result, "%u", PQoidValue(result));
		return TCL_OK;
	}
	else if (strcmp(opt, "-clear") == 0)
	{
		PgDelResultId(interp, argv[1]);
		PQclear(result);
		return TCL_OK;
	}
	else if (strcmp(opt, "-numTuples") == 0)
	{
		sprintf(interp->result, "%d", PQntuples(result));
		return TCL_OK;
	}
	else if (strcmp(opt, "-cmdTuples") == 0)
	{
		sprintf(interp->result, "%s", PQcmdTuples(result));
		return TCL_OK;
	}
	else if (strcmp(opt, "-numAttrs") == 0)
	{
		sprintf(interp->result, "%d", PQnfields(result));
		return TCL_OK;
	}
	else if (strcmp(opt, "-assign") == 0)
	{
		if (argc != 4)
		{
			Tcl_AppendResult(interp, "-assign option must be followed by a variable name", 0);
			return TCL_ERROR;
		}
		arrVar = argv[3];

		/*
		 * this assignment assigns the table of result tuples into a giant
		 * array with the name given in the argument. The indices of the
		 * array are of the form (tupno,attrName). Note we expect field
		 * names not to exceed a few dozen characters, so truncating to
		 * prevent buffer overflow shouldn't be a problem.
		 */
		for (tupno = 0; tupno < PQntuples(result); tupno++)
		{
			for (i = 0; i < PQnfields(result); i++)
			{
				sprintf(nameBuffer, "%d,%.200s", tupno, PQfname(result, i));
				if (Tcl_SetVar2(interp, arrVar, nameBuffer,
#ifdef TCL_ARRAYS
								tcl_value(PQgetvalue(result, tupno, i)),
#else
								PQgetvalue(result, tupno, i),
#endif
								TCL_LEAVE_ERR_MSG) == NULL)
					return TCL_ERROR;
			}
		}
		Tcl_AppendResult(interp, arrVar, 0);
		return TCL_OK;
	}
	else if (strcmp(opt, "-assignbyidx") == 0)
	{
		if (argc != 4 && argc != 5)
		{
			Tcl_AppendResult(interp, "-assignbyidx option requires an array name and optionally an append string", 0);
			return TCL_ERROR;
		}
		arrVar = argv[3];
		appendstr = (argc == 5) ? (const char *) argv[4] : "";

		/*
		 * this assignment assigns the table of result tuples into a giant
		 * array with the name given in the argument.  The indices of the
		 * array are of the form (field0Value,attrNameappendstr). Here, we
		 * still assume PQfname won't exceed 200 characters, but we dare
		 * not make the same assumption about the data in field 0 nor the
		 * append string.
		 */
		for (tupno = 0; tupno < PQntuples(result); tupno++)
		{
			const char *field0 =
#ifdef TCL_ARRAYS
			tcl_value(PQgetvalue(result, tupno, 0));

#else
			PQgetvalue(result, tupno, 0);
#endif
			char	   *workspace = malloc(strlen(field0) + strlen(appendstr) + 210);

			for (i = 1; i < PQnfields(result); i++)
			{
				sprintf(workspace, "%s,%.200s%s", field0, PQfname(result, i),
						appendstr);
				if (Tcl_SetVar2(interp, arrVar, workspace,
#ifdef TCL_ARRAYS
								tcl_value(PQgetvalue(result, tupno, i)),
#else
								PQgetvalue(result, tupno, i),
#endif
								TCL_LEAVE_ERR_MSG) == NULL)
				{
					free(workspace);
					return TCL_ERROR;
				}
			}
			free(workspace);
		}
		Tcl_AppendResult(interp, arrVar, 0);
		return TCL_OK;
	}
	else if (strcmp(opt, "-getTuple") == 0)
	{
		if (argc != 4)
		{
			Tcl_AppendResult(interp, "-getTuple option must be followed by a tuple number", 0);
			return TCL_ERROR;
		}
		tupno = atoi(argv[3]);
		if (tupno < 0 || tupno >= PQntuples(result))
		{
			Tcl_AppendResult(interp, "argument to getTuple cannot exceed number of tuples - 1", 0);
			return TCL_ERROR;
		}
#ifdef TCL_ARRAYS
		for (i = 0; i < PQnfields(result); i++)
			Tcl_AppendElement(interp, tcl_value(PQgetvalue(result, tupno, i)));
#else
		for (i = 0; i < PQnfields(result); i++)
			Tcl_AppendElement(interp, PQgetvalue(result, tupno, i));
#endif
		return TCL_OK;
	}
	else if (strcmp(opt, "-tupleArray") == 0)
	{
		if (argc != 5)
		{
			Tcl_AppendResult(interp, "-tupleArray option must be followed by a tuple number and array name", 0);
			return TCL_ERROR;
		}
		tupno = atoi(argv[3]);
		if (tupno < 0 || tupno >= PQntuples(result))
		{
			Tcl_AppendResult(interp, "argument to tupleArray cannot exceed number of tuples - 1", 0);
			return TCL_ERROR;
		}
		for (i = 0; i < PQnfields(result); i++)
		{
			if (Tcl_SetVar2(interp, argv[4], PQfname(result, i),
#ifdef TCL_ARRAYS
							tcl_value(PQgetvalue(result, tupno, i)),
#else
							PQgetvalue(result, tupno, i),
#endif
							TCL_LEAVE_ERR_MSG) == NULL)
				return TCL_ERROR;
		}
		return TCL_OK;
	}
	else if (strcmp(opt, "-attributes") == 0)
	{
		for (i = 0; i < PQnfields(result); i++)
			Tcl_AppendElement(interp, PQfname(result, i));
		return TCL_OK;
	}
	else if (strcmp(opt, "-lAttributes") == 0)
	{
		for (i = 0; i < PQnfields(result); i++)
		{
			/* start a sublist */
			if (i > 0)
				Tcl_AppendResult(interp, " {", 0);
			else
				Tcl_AppendResult(interp, "{", 0);
			Tcl_AppendElement(interp, PQfname(result, i));
			sprintf(nameBuffer, "%ld", (long) PQftype(result, i));
			Tcl_AppendElement(interp, nameBuffer);
			sprintf(nameBuffer, "%ld", (long) PQfsize(result, i));
			Tcl_AppendElement(interp, nameBuffer);
			/* end the sublist */
			Tcl_AppendResult(interp, "}", 0);
		}
		return TCL_OK;
	}
	else
	{
		Tcl_AppendResult(interp, "Invalid option\n", 0);
		goto Pg_result_errReturn;		/* append help info */
	}


Pg_result_errReturn:
	Tcl_AppendResult(interp,
					 "pg_result result ?option? where option is\n",
					 "\t-status\n",
					 "\t-error\n",
					 "\t-conn\n",
					 "\t-oid\n",
					 "\t-numTuples\n",
					 "\t-cmdTuples\n",
					 "\t-numAttrs\n"
					 "\t-assign arrayVarName\n",
					 "\t-assignbyidx arrayVarName ?appendstr?\n",
					 "\t-getTuple tupleNumber\n",
					 "\t-tupleArray tupleNumber arrayVarName\n",
					 "\t-attributes\n"
					 "\t-lAttributes\n"
					 "\t-clear\n",
					 (char *) 0);
	return TCL_ERROR;


}
Esempio n. 14
0
int get_column_info(PGresult * res, int col, int *pgtype, int *gpgtype,
		    int *sqltype, int *size)
{
    *pgtype = (int)PQftype(res, col);
    *gpgtype = get_gpg_type(*pgtype);

    /* Convert internal type to PG_TYPE_* */

    /* TODO: we should load field names from pg_type table
       instead of using copy of #defines */
    switch (*gpgtype) {
    case PG_TYPE_BIT:
    case PG_TYPE_INT2:
    case PG_TYPE_INT4:
    case PG_TYPE_INT8:
    case PG_TYPE_SERIAL:
    case PG_TYPE_OID:
	*sqltype = DB_SQL_TYPE_INTEGER;
	*size = PQfsize(res, col);
	break;

    case PG_TYPE_CHAR:
    case PG_TYPE_BPCHAR:
    case PG_TYPE_VARCHAR:
	*sqltype = DB_SQL_TYPE_CHARACTER;
	*size = PQfmod(res, col) - 4;	/* Looks strange but works, something better? */
	break;

    case PG_TYPE_TEXT:
	*sqltype = DB_SQL_TYPE_TEXT;
	break;

    case PG_TYPE_FLOAT4:
    case PG_TYPE_FLOAT8:
    case PG_TYPE_NUMERIC:
	*sqltype = DB_SQL_TYPE_DOUBLE_PRECISION;
	*size = PQfsize(res, col);
	break;

	/* I'm not sure if text length is correct for size */
    case PG_TYPE_DATE:
	*sqltype = DB_SQL_TYPE_DATE;
	*size = 10;		/* YYYY-MM-DD */
	break;

    case PG_TYPE_TIME:
	*sqltype = DB_SQL_TYPE_TIME;
	*size = 8;		/* HH:MM:SS */
	break;

    case PG_TYPE_TIMESTAMP:
	*sqltype = DB_SQL_TYPE_TIMESTAMP;
	*size = 22;		/* YYYY-MM-DD HH:MM:SS+TZ */
	break;

    case PG_TYPE_BOOL:
	*sqltype = DB_SQL_TYPE_CHARACTER;
	*size = 1;
	break;

    default:
	*sqltype = DB_SQL_TYPE_UNKNOWN;
	*size = 0;
    }

    return 0;
}
Esempio n. 15
0
size_t DTTablePostgres::columnDataSize(int columnNumber) const { //returns -1 for varchar
	if (columnNumber >= columnCount() || columnNumber < 0) {
		EXToutOfRange("Column number is out of range");
	}
	return (size_t) PQfsize(result, columnNumber);
}
Esempio n. 16
0
static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea )
{
   PGconn *       pConn = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pConn;
   SDDDATA *      pSDDData;
   PGresult *     pResult;
   ExecStatusType status;
   PHB_ITEM       pItemEof, pItem;
   HB_USHORT      uiFields, uiCount;
   HB_BOOL        bError;
   DBFIELDINFO    pFieldInfo;

   pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) );
   pSDDData        = ( SDDDATA * ) pArea->pSDDData;

   pResult = PQexec( pConn, pArea->szQuery );
   if( ! pResult )
   {
      hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_LOWMEMORY, "Query failed", NULL, 0 );  /* Low memory, etc */
      return HB_FAILURE;
   }

   status = PQresultStatus( pResult );
   if( status != PGRES_TUPLES_OK && status != PGRES_COMMAND_OK )
   {
      hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_INVALIDQUERY, PQresultErrorMessage( pResult ), pArea->szQuery, ( HB_ERRCODE ) status );
      PQclear( pResult );
      return HB_FAILURE;
   }

   pSDDData->pResult = pResult;

   uiFields = ( HB_USHORT ) PQnfields( pResult );
   SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields );

   pItemEof = hb_itemArrayNew( uiFields );
   pItem    = hb_itemNew( NULL );

   bError = HB_FALSE;
   for( uiCount = 0; uiCount < uiFields; uiCount++ )
   {
      pFieldInfo.atomName = PQfname( pResult, ( int ) uiCount );
      pFieldInfo.uiDec    = 0;

      switch( PQftype( pResult, ( int ) uiCount ) )
      {
         case BPCHAROID:
         case VARCHAROID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = ( HB_USHORT ) PQfmod( pResult, uiCount ) - 4;
            break;

         case TEXTOID:
            pFieldInfo.uiType = HB_FT_MEMO;
            pFieldInfo.uiLen  = 10;
            break;

         case NUMERICOID:
            pFieldInfo.uiType = HB_FT_DOUBLE;
            pFieldInfo.uiLen  = ( PQfmod( pResult, uiCount ) - 4 ) >> 16;
            pFieldInfo.uiDec  = ( PQfmod( pResult, uiCount ) - 4 ) & 0xFFFF;
            break;

         case INT2OID:
            pFieldInfo.uiType = HB_FT_INTEGER;
            pFieldInfo.uiLen  = 6;
            break;

         case INT4OID:
            pFieldInfo.uiType = HB_FT_INTEGER;
            pFieldInfo.uiLen  = 11;
            break;

         case INT8OID:
         case OIDOID:
            pFieldInfo.uiType = HB_FT_LONG;
            pFieldInfo.uiLen  = 20;
            break;

         case FLOAT4OID:
         case FLOAT8OID:
         case CASHOID:  /* TODO: ??? */
            pFieldInfo.uiType = HB_FT_DOUBLE;
            pFieldInfo.uiLen  = 16;
            pFieldInfo.uiDec  = 2;   /* TODO: hb_set.SET_DECIMALS ??? */
            break;

         case BOOLOID:
            pFieldInfo.uiType = HB_FT_LOGICAL;
            pFieldInfo.uiLen  = 1;
            break;

         case DATEOID:
            pFieldInfo.uiType = HB_FT_DATE;
            pFieldInfo.uiLen  = 8;
            break;

         case INETOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 29;
            break;

         case CIDROID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 32;
            break;

         case MACADDROID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 17;
            break;

         case BITOID:
         case VARBITOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = ( HB_USHORT ) PQfsize( pResult, uiCount );
            break;

         case TIMEOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 12;
            break;

         case TIMESTAMPOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 23;
            break;

         case TIMETZOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 15;
            break;

         case TIMESTAMPTZOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 26;
            break;

         case NAMEOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 63;
            break;

         case BYTEAOID:
            pFieldInfo.uiType = HB_FT_STRING;
            pFieldInfo.uiLen  = 0;
            break;

         default:
            pFieldInfo.uiType = 0;
            pFieldInfo.uiLen  = 0;
            bError = HB_TRUE;
            break;
      }
      /* printf( "field:%s \ttype:%d \tsize:%d \tformat:%d \tmod:%d err=%d\n", pFieldInfo.atomName, PQftype( pResult, ( int ) uiCount ), PQfsize( pResult, uiCount ), PQfformat( pResult, uiCount ) , PQfmod( pResult, uiCount ), bError ); */

      if( ! bError )
      {
         switch( pFieldInfo.uiType )
         {
            case HB_FT_STRING:
            {
               char * pStr;

               pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 );
               memset( pStr, ' ', pFieldInfo.uiLen );
               pStr[ pFieldInfo.uiLen ] = '\0';

               hb_itemPutCL( pItem, pStr, pFieldInfo.uiLen );
               hb_xfree( pStr );
               break;
            }
            case HB_FT_MEMO:
               hb_itemPutC( pItem, NULL );
               hb_itemSetCMemo( pItem );
               break;

            case HB_FT_INTEGER:
               hb_itemPutNI( pItem, 0 );
               break;

            case HB_FT_LONG:
               hb_itemPutNL( pItem, 0 );
               break;

            case HB_FT_DOUBLE:
               hb_itemPutND( pItem, 0.0 );
               break;

            case HB_FT_LOGICAL:
               hb_itemPutL( pItem, HB_FALSE );
               break;

            case HB_FT_DATE:
               hb_itemPutDS( pItem, NULL );
               break;

            default:
               hb_itemClear( pItem );
               bError = HB_TRUE;
               break;
         }

         hb_arraySetForward( pItemEof, uiCount + 1, pItem );

/*       if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER )
            pFieldInfo.uiType = HB_IT_LONG;
 */

         if( ! bError )
            bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE );
      }

      if( bError )
         break;
   }

   hb_itemRelease( pItem );

   if( bError )
   {
      hb_itemClear( pItemEof );
      hb_itemRelease( pItemEof );
      hb_errRT_PostgreSQLDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, 0 );
      return HB_FAILURE;
   }

   pArea->ulRecCount = ( HB_ULONG ) PQntuples( pResult );

   pArea->pRow      = ( void ** ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( void * ) );
   pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) );
   memset( pArea->pRowFlags, 0, ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) );

   *pArea->pRow = pItemEof;
   pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED;
   pArea->fFetched       = HB_TRUE;

   return HB_SUCCESS;
}
Esempio n. 17
0
/**
 * Obtain a random key-value pair from the datacache.
 *
 * @param cls closure (our `struct Plugin`)
 * @param iter maybe NULL (to just count)
 * @param iter_cls closure for @a iter
 * @return the number of results found, zero (datacache empty) or one
 */
static unsigned int
postgres_plugin_get_random (void *cls,
                            GNUNET_DATACACHE_Iterator iter,
                            void *iter_cls)
{
  struct Plugin *plugin = cls;
  unsigned int off;
  uint32_t off_be;
  struct GNUNET_TIME_Absolute expiration_time;
  uint32_t size;
  unsigned int path_len;
  const struct GNUNET_PeerIdentity *path;
  const struct GNUNET_HashCode *key;
  unsigned int type;
  PGresult *res;
  const char *paramValues[] = {
    (const char *) &off_be
  };
  int paramLengths[] = {
    sizeof (off_be)
  };
  const int paramFormats[] = { 1 };

  if (0 == plugin->num_items)
    return 0;
  if (NULL == iter)
    return 1;
  off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
                                  plugin->num_items);
  off_be = htonl (off);
  res =
    PQexecPrepared (plugin->dbh, "get_random",
                    1, paramValues, paramLengths, paramFormats,
                    1);
  if (GNUNET_OK !=
      GNUNET_POSTGRES_check_result (plugin->dbh,
                                    res,
                                    PGRES_TUPLES_OK,
                                    "PQexecPrepared",
				    "get_random"))
  {
    GNUNET_break (0);
    return 0;
  }
  if (0 == PQntuples (res))
  {
    GNUNET_break (0);
    return 0;
  }
  if ( (5 != PQnfields (res)) ||
       (sizeof (uint64_t) != PQfsize (res, 0)) ||
       (sizeof (uint32_t) != PQfsize (res, 1)) ||
       (sizeof (struct GNUNET_HashCode) != PQfsize (res, 4)) )
  {
    GNUNET_break (0);
    PQclear (res);
    return 0;
  }
  expiration_time.abs_value_us =
    GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, 0, 0));
  type = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1));
  size = PQgetlength (res, 0, 2);
  path_len = PQgetlength (res, 0, 3);
  if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break (0);
    path_len = 0;
  }
  path_len %= sizeof (struct GNUNET_PeerIdentity);
  path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, 0, 3);
  key = (const struct GNUNET_HashCode *) PQgetvalue (res, 0, 4);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Found random value with key %s of size %u bytes and type %u in database\n",
       GNUNET_h2s (key),
       (unsigned int) size,
       (unsigned int) type);
  (void) iter (iter_cls,
               key,
               size,
               PQgetvalue (res, 0, 2),
               (enum GNUNET_BLOCK_Type) type,
               expiration_time,
               path_len,
               path);
  PQclear (res);
  return 1;
}
Esempio n. 18
0
/**
 * Iterate over the results that are "close" to a particular key in
 * the datacache.  "close" is defined as numerically larger than @a
 * key (when interpreted as a circular address space), with small
 * distance.
 *
 * @param cls closure (internal context for the plugin)
 * @param key area of the keyspace to look into
 * @param num_results number of results that should be returned to @a iter
 * @param iter maybe NULL (to just count)
 * @param iter_cls closure for @a iter
 * @return the number of results found
 */
static unsigned int
postgres_plugin_get_closest (void *cls,
                             const struct GNUNET_HashCode *key,
                             unsigned int num_results,
                             GNUNET_DATACACHE_Iterator iter,
                             void *iter_cls)
{
  struct Plugin *plugin = cls;
  uint32_t nbo_limit = htonl (num_results);
  const char *paramValues[] = {
    (const char *) key,
    (const char *) &nbo_limit,
  };
  int paramLengths[] = {
    sizeof (struct GNUNET_HashCode),
    sizeof (nbo_limit)

  };
  const int paramFormats[] = { 1, 1 };
  struct GNUNET_TIME_Absolute expiration_time;
  uint32_t size;
  unsigned int type;
  unsigned int cnt;
  unsigned int i;
  unsigned int path_len;
  const struct GNUNET_PeerIdentity *path;
  PGresult *res;

  res =
      PQexecPrepared (plugin->dbh,
                      "get_closest",
                      2,
                      paramValues,
                      paramLengths,
                      paramFormats,
                      1);
  if (GNUNET_OK !=
      GNUNET_POSTGRES_check_result (plugin->dbh,
                                    res,
                                    PGRES_TUPLES_OK,
                                    "PQexecPrepared",
				    "get_closest"))
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
	 "Ending iteration (postgres error)\n");
    return 0;
  }

  if (0 == (cnt = PQntuples (res)))
  {
    /* no result */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
	 "Ending iteration (no more results)\n");
    PQclear (res);
    return 0;
  }
  if (NULL == iter)
  {
    PQclear (res);
    return cnt;
  }
  if ( (5 != PQnfields (res)) ||
       (sizeof (uint64_t) != PQfsize (res, 0)) ||
       (sizeof (uint32_t) != PQfsize (res, 1)) ||
       (sizeof (struct GNUNET_HashCode) != PQfsize (res, 4)) )
  {
    GNUNET_break (0);
    PQclear (res);
    return 0;
  }
  for (i = 0; i < cnt; i++)
  {
    expiration_time.abs_value_us =
        GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0));
    type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1));
    size = PQgetlength (res, i, 2);
    path_len = PQgetlength (res, i, 3);
    if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity)))
    {
      GNUNET_break (0);
      path_len = 0;
    }
    path_len %= sizeof (struct GNUNET_PeerIdentity);
    path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3);
    key = (const struct GNUNET_HashCode *) PQgetvalue (res, i, 4);
    LOG (GNUNET_ERROR_TYPE_DEBUG,
	 "Found result of size %u bytes and type %u in database\n",
	 (unsigned int) size,
         (unsigned int) type);
    if (GNUNET_SYSERR ==
        iter (iter_cls,
              key,
              size,
              PQgetvalue (res, i, 2),
              (enum GNUNET_BLOCK_Type) type,
	      expiration_time,
	      path_len,
	      path))
    {
      LOG (GNUNET_ERROR_TYPE_DEBUG,
	   "Ending iteration (client error)\n");
      PQclear (res);
      return cnt;
    }
  }
  PQclear (res);
  return cnt;
}
Esempio n. 19
0
RS_DBI_fields *
RS_PostgreSQL_createDataMappings(Res_Handle * rsHandle)
{
    PGresult *my_result;

    RS_DBI_connection *con;
    RS_DBI_resultSet *result;
    RS_DBI_fields *flds;

    int j, num_fields, internal_type;
    char errMsg[128];

    result = RS_DBI_getResultSet(rsHandle);
    my_result = (PGresult *) result->drvResultSet;

    con = RS_DBI_getConnection(rsHandle);
    num_fields = PQnfields(my_result);

    flds = RS_DBI_allocFields(num_fields); /* this returns malloced data (not from R) */

    char buff[1000];            /* Buffer to hold the sql query to check whether the given column is nullable */
    PGconn *conn;
    PGresult *res;
    conn = (PGconn *) con->drvConnection;

    for (j = 0; j < num_fields; j++) {

        flds->name[j] = RS_DBI_copyString(PQfname(my_result, j));

        flds->type[j] = (int) PQftype(my_result, j);

        flds->length[j] = (Sint) PQfsize(my_result, j);

        /* NOTE: PQfmod is -1 incase of no information */
        flds->precision[j] = (Sint) PQfmod(my_result, j);

        flds->scale[j] = (Sint) - 1;

        /* PQftablecol returns the column number (within its table) of
         * the column making up the specified query result column.Zero
         * is returned if the column number is out of range, or if the
         * specified column is not a simple reference to a table
         * column, or when using pre-3.0 protocol. So
         * "if(PQftablecol(my_result,j) !=0)" checks whether the
         * particular colomn in the result set is column of table or
         * not. Or else there is no meaning in checking whether a
         * column is nullable or not if it does not belong to the
         * table.
         */

        flds->nullOk[j] = (Sint) INT_MIN; /* This should translate to NA in R */

        if (PQftablecol(my_result, j) != 0) {
            /* Code to find whether a row can be nullable or not */
            /* we might better just store the table id and column number
               for lazy evaluation at dbColumnInfo call*/
            /* although the database structure can change, we are not in transaction anyway
               and there is no guarantee in current code */
            snprintf(buff, 1000, "select attnotnull from pg_attribute where attrelid=%d and attnum='%d'",
                     PQftable(my_result, j), PQftablecol(my_result, j));
            res = PQexec(conn, buff);

            if (res && (PQntuples(res) > 0)) {
                const char * attnotnull = PQgetvalue(res, 0, 0);
                if(strcmp(attnotnull, "f") == 0) {
                    flds->nullOk[j] = (Sint) 1; /* nollOK is TRUE when attnotnull is f*/
                }
                if(strcmp(attnotnull, "t") == 0) {
                    flds->nullOk[j] = (Sint) 0; /* nollOK is FALSE when attnotnull is t*/
                }
            }
            PQclear(res);
        }

        internal_type = (int) PQftype(my_result, j);

        switch (internal_type) {
        case BOOLOID:
            flds->Sclass[j] = LOGICAL_TYPE;
            break;
        case BPCHAROID:
            flds->Sclass[j] = CHARACTER_TYPE;
            flds->isVarLength[j] = (Sint) 0;
            break;
        case VARCHAROID:
        case TEXTOID:
        case BYTEAOID:
        case NAMEOID:
        case MACADDROID:
        case INETOID:
            flds->Sclass[j] = CHARACTER_TYPE;
            flds->isVarLength[j] = (Sint) 1;
            break;
        case INT2OID:
        case INT4OID:
        case OIDOID:
            flds->Sclass[j] = INTEGER_TYPE;
            break;
        case INT8OID:
            if (sizeof(Sint) >= 8) {
                flds->Sclass[j] = INTEGER_TYPE;
            }
            else {
                flds->Sclass[j] = NUMERIC_TYPE;
            }
            break;
        case NUMERICOID:
        case FLOAT8OID:
        case FLOAT4OID:
            flds->Sclass[j] = NUMERIC_TYPE;
            break;
        case DATEOID:
        case TIMEOID:
        case TIMETZOID:
        case TIMESTAMPOID:
        case TIMESTAMPTZOID:
        case INTERVALOID:
            flds->Sclass[j] = CHARACTER_TYPE;
            /*flds->isVarLength[j] = (Sint) 1; */
            break;
        default:
            flds->Sclass[j] = CHARACTER_TYPE;
            flds->isVarLength[j] = (Sint) 1;
            snprintf(buff, 1000, "select typname, typcategory from pg_type where oid = %d", internal_type);
            res = PQexec(conn, buff);
            if (res) {
                char * typename;
                char * typecat;
                int ntuples;
                ntuples = PQntuples(res);
                if(ntuples == 1) {
                    typename = PQgetvalue(res, 0, 0);
                    typecat = PQgetvalue(res, 0, 1);
                    if(*typecat == 'E') { /* This is enum, ok */
                    } else if(*typecat == 'A') { /*This is array, ok */
                    } else {
                        snprintf(errMsg, 128, "unrecognized PostgreSQL field type %s (id:%d) in column %d", typename, internal_type, j);
                        RS_DBI_errorMessage(errMsg, RS_DBI_WARNING);
                    }
                } else {
                    snprintf(errMsg, 128, "oid: %d, ntuples: %d", internal_type, ntuples);
                    RS_DBI_errorMessage(errMsg, RS_DBI_WARNING);
                }
                PQclear(res);
            } else {
Esempio n. 20
0
/* ---------------------------------------------------------------------
 * PgResultColumnSize
 * Field size in the specified column
 * ---------------------------------------------------------------------
 */
int 
PgResultColumnSize(SQLRESULT* result, int index)
{
	return PQfsize(result->Result, index);
}
Esempio n. 21
0
GSQLCursorState
pgsql_cursor_open_bind (GSQLCursor *cursor, GList *args) {
	GSQL_TRACE_FUNC;
	GSQLEPGSQLSession *e_session = NULL;
	GSQLEPGSQLCursor  *e_cursor = NULL;
	GSQLVariable *var;
	GSQLWorkspace *workspace = NULL;
	PGSQL_FIELD *field;

	gulong binds_arg, n, n_fields, is_null = 1;
	// store parameters information
	Oid *paramTypes = NULL;
	const char **paramValues = NULL;
	int *paramLengths = NULL;
	int *paramFormats = NULL;

	GList *vlist = args;
	GType vtype;
	gchar error_str[2048];
	
	g_return_if_fail (GSQL_IS_CURSOR(cursor));
	
	g_return_if_fail(GSQL_IS_SESSION(cursor->session));
	e_session = cursor->session->spec;

	workspace = gsql_session_get_workspace (cursor->session);
	g_return_if_fail(GSQL_IS_WORKSPACE(workspace));
  
	if (!pgsql_cursor_prepare (cursor)) {
		return GSQL_CURSOR_STATE_ERROR;
	}

	e_cursor = cursor->spec;
	
	binds_arg = g_list_length (args) / 2;

	paramTypes = g_malloc0 ( sizeof(Oid) * binds_arg );
	paramValues = g_malloc0 ( sizeof (char *) * binds_arg );
	paramLengths = g_malloc0 ( sizeof(int) * binds_arg );
	paramFormats = g_malloc0 ( sizeof(int) * binds_arg );
	n = 0;

	GSQL_DEBUG ( "Executing [%s]...", cursor->sql );
	while (vlist) {
		vtype = (GType) vlist->data;
		vlist = g_list_next (vlist);
		if (vlist->data == NULL)
			is_null = 1;
		else 
			is_null = 0;
		switch (vtype) {
			case G_TYPE_STRING:
			case G_TYPE_POINTER:
				paramTypes[n] = VARCHAROID;
				paramValues[n] = (char *) vlist->data;
				paramLengths[n] = g_utf8_strlen((gchar *) 
								vlist->data,
								1048576);
				paramFormats[n] = 0;
				break;
	
			case G_TYPE_INT:
			case G_TYPE_UINT:
				paramTypes[n] = INT4OID;
				paramValues[n] = (char *) &vlist->data;
				paramLengths[n] = 0;
				paramFormats[n] = 0;
				break;
				
			case G_TYPE_UINT64:
			case G_TYPE_INT64:
				paramTypes[n] = INT8OID;
				paramValues[n] = (char *) &vlist->data;
				paramLengths[n] = 0;
				paramFormats[n] = 0;
				break;
	
			case G_TYPE_DOUBLE:
				paramTypes[n] = FLOAT4OID;
				paramValues[n] = (char *) &vlist->data;
				paramLengths[n] = 0;
				paramFormats[n] = 0;
				break;
		}

		//GSQL_DEBUG ("Parms [%d] = [%s]", n, paramValues[n]);
		vlist = g_list_next (vlist);
		n++;
	}

	if (! e_session->pgconn ) {
		GSQL_DEBUG ("BIND: pgconn empty!");
	}

	if ( PQstatus(e_session->pgconn) != CONNECTION_OK ) {
		GSQL_DEBUG("BIND: lost connection!");
	}

	e_cursor->result = PQexecParams(e_session->pgconn, cursor->sql,
					binds_arg, paramTypes, paramValues,
					paramLengths, paramFormats, 0);

	if ( ! e_cursor->result ) {
		g_sprintf ( error_str, "Error occured: %s", 
			    pgsql_session_get_error(cursor->session) );
		gsql_message_add (workspace, GSQL_MESSAGE_ERROR, error_str);
		g_free (paramTypes);
		g_free (paramValues);
		g_free (paramLengths);
		g_free (paramFormats);
    
		return GSQL_CURSOR_STATE_ERROR;
	}


	pgsql_cursor_statement_detect (cursor);
  
	g_free (paramTypes);
	g_free (paramValues);
	g_free (paramLengths);
	g_free (paramFormats);
  
	n_fields =  PQnfields (e_cursor->result);

	if (n_fields == 0)
		return GSQL_CURSOR_STATE_OPEN;
  
	for (n = 0; n < n_fields; n++) {
		// TODO: free this in on_variable_delete
		field = g_malloc0 ( sizeof(PGSQL_FIELD) );
		field->name = PQfname(e_cursor->result, n);
		field->type = PQftype(e_cursor->result, n);
		field->size = PQfsize(e_cursor->result, n);

		var = gsql_variable_new ();
		pgsql_variable_init (var, field);
		cursor->var_list = g_list_append (cursor->var_list, var);
	}

	return GSQL_CURSOR_STATE_OPEN;
}
Esempio n. 22
0
int pg_createrowset(ClipMachine* mp,SQLROWSET* rs,ClipVar* ap,ClipVar* idname,const char* gen_idSQL){
	PG_ROWSET* rowset = (PG_ROWSET*)rs;
	PG_STMT* stmt = rowset->stmt;
	PG_CONN* conn = rowset->conn;
	int i,mod;

	pg_bindpars(stmt,ap);
	if(!stmt->sql){
		_clip_trap_err(mp,0,0,0,subsys,ER_NOSQL,er_nosql);
		return 1;
	}

	stmt->res = PQexec(conn->conn,stmt->sql);
	if(!stmt->res){
		_clip_trap_err(mp,0,0,0,subsys,ER_BADSTATEMENT,
			PQresultErrorMessage(stmt->res));
		return 1;
	}
	if(PQresultStatus(stmt->res)!=PGRES_TUPLES_OK){
		_clip_trap_err(mp,0,0,0,subsys,ER_BADSELECT,
			PQresultErrorMessage(stmt->res));
		return 1;
	}

	rowset->rowset_item =
		_clip_store_c_item(mp,rowset,_C_ITEM_TYPE_SQL,destroy_pg_rowset);

	rowset->binary = PQbinaryTuples(stmt->res);
	rowset->nfields = PQnfields(stmt->res);
	rowset->fields = calloc(1,rowset->nfields*sizeof(SQLFIELD));
	rowset->id = -1;
	for(i=0;i<rowset->nfields;i++){
		strncpy(rowset->fields[i].name,PQfname(stmt->res,i),
			MAXFIELDNAME);
		rowset->fields[i].name[MAXFIELDNAME] = 0;
		rowset->fields[i].type = PQftype(stmt->res,i);
		rowset->fields[i].ctype[0] = _pg_ctype(rowset->fields[i].type);
		rowset->fields[i].dec = 0;
		mod = PQfmod(stmt->res,i);
		switch(rowset->fields[i].type){
			case PGT_BPCHAR:
			case PGT_CHAR:
			case PGT_VARCHAR:
				rowset->fields[i].len = mod-4;
				break;
			case PGT_TEXT:
				rowset->fields[i].len = 10;
				break;
			case PGT_NUMERIC:
				rowset->fields[i].len = (mod >> 16);
				rowset->fields[i].dec = (mod & 0xffff)-4;
				break;
			case PGT_DATE:
				rowset->fields[i].len = 8;
				break;
			default:
				rowset->fields[i].len = PQfsize(stmt->res,i);
				break;
		}
		rowset->fields[i].ops = 0;
		if(idname && idname->t.type == CHARACTER_t && idname->s.str.buf){
			if(!strcasecmp(rowset->fields[i].name,idname->s.str.buf)){
				rowset->id = i;
			}
		} else if(rowset->fields[i].type == PGT_OID){
			rowset->id = i;
		}
	}

	rowset->lastrec = PQntuples(stmt->res);
	rowset->data = calloc(rowset->lastrec,sizeof(void*));
	return 0;
}