Exemple #1
0
/* 
 * Adapter function to PQunescapeBytea()
 * This function should properly unescape the charactor representation
 * of the binary data returned from PostgreSQL and return raw binary data.
 */
SEXP
RS_PostgreSQL_unescape_bytea(SEXP escapedstring)
{
    SEXP output;
    size_t raw_length;
    const char* strbuffer;
    unsigned char* rawbuffer;
    strbuffer = CHAR(STRING_ELT(escapedstring, 0));
    if(!strbuffer) RS_DBI_errorMessage("strbuffer is NULL!", RS_DBI_ERROR);
    if (strbuffer[0] == '\\' && strbuffer[1] == 'x'){
      /* the new hex fomat */
        int i;
        size_t enc_length = LENGTH(STRING_ELT(escapedstring, 0));
        raw_length = enc_length / 2 - 1;
        output = allocVector(RAWSXP, raw_length);
        rawbuffer = RAW(output);
        for(i = 0; i < raw_length; i++){
          rawbuffer[i] = (hex2n(strbuffer[2+ i*2]) << 4) + hex2n(strbuffer[2+i*2+1]);
        }
        return output;
    }else{ /* the old escape format */
        rawbuffer = PQunescapeBytea((const unsigned char*) strbuffer,  &raw_length);
        /* explicit cast to suppress warning on signedness by clang */
        if(!rawbuffer) RS_DBI_errorMessage("PQunescapeByea Failed", RS_DBI_ERROR);
        output = allocVector(RAWSXP, raw_length);
        memcpy(RAW(output), rawbuffer, raw_length);
        free(rawbuffer);
        return output;
    }
}
VALUE typecast_detect(const char *data, size_t size, int type) {
    VALUE value;
    char *bytea;
    size_t bytea_len;
    switch (type) {
        case SWIFT_TYPE_INT:
            return rb_cstr2inum(data, 10);
        case SWIFT_TYPE_FLOAT:
            return rb_float_new(atof(data));
        case SWIFT_TYPE_NUMERIC:
            return rb_funcall(cBigDecimal, fnew, 1, rb_str_new(data, size));
        case SWIFT_TYPE_BOOLEAN:
            return (data && (data[0] =='t' || data[0] == '1')) ? Qtrue : Qfalse;
        case SWIFT_TYPE_BLOB:
            bytea = PQunescapeBytea(data, &bytea_len);
            value = rb_str_new(bytea, bytea_len);
            PQfreemem(bytea);
            return rb_funcall(cStringIO, fnew, 1, value);
        case SWIFT_TYPE_TIMESTAMP:
            return datetime_parse(cSwiftDateTime, data, size);
        case SWIFT_TYPE_DATE:
            return date_parse(cSwiftDateTime, data, size);
        default:
            return rb_enc_str_new(data, size, rb_utf8_encoding());
    }
}
Exemple #3
0
static VALUE typecast(const char *value, long length, const VALUE type, int encoding) {

  if (type == rb_cInteger) {
    return rb_cstr2inum(value, 10);
  } else if (type == rb_cString) {
    return DO_STR_NEW(value, length, encoding);
  } else if (type == rb_cFloat) {
    return rb_float_new(rb_cstr_to_dbl(value, Qfalse));
  } else if (type == rb_cBigDecimal) {
    return rb_funcall(rb_cBigDecimal, ID_NEW, 1, rb_str_new(value, length));
  } else if (type == rb_cDate) {
    return parse_date(value);
  } else if (type == rb_cDateTime) {
    return parse_date_time(value);
  } else if (type == rb_cTime) {
    return parse_time(value);
  } else if (type == rb_cTrueClass) {
    return *value == 't' ? Qtrue : Qfalse;
  } else if (type == rb_cByteArray) {
    size_t new_length = 0;
    char* unescaped = (char *)PQunescapeBytea((unsigned char*)value, &new_length);
    VALUE byte_array = rb_funcall(rb_cByteArray, ID_NEW, 1, rb_str_new(unescaped, new_length));
    PQfreemem(unescaped);
    return byte_array;
  } else if (type == rb_cClass) {
    return rb_funcall(rb_cObject, rb_intern("full_const_get"), 1, rb_str_new(value, length));
  } else if (type == rb_cObject) {
    return rb_marshal_load(rb_str_new(value, length));
  } else if (type == rb_cNilClass) {
    return Qnil;
  } else {
    return DO_STR_NEW(value, length, encoding);
  }

}
Exemple #4
0
static VALUE typecast(const char* data, uint64_t len, int pgtype) {
  size_t bytea_len;
  unsigned char* bytea;
  VALUE rv;

  switch(pgtype) {
    case 16:
      return *data == 't' ? Qtrue : Qfalse;
    case 17:
      bytea = PQunescapeBytea(data, &bytea_len);
      rv = rb_funcall(cStringIO, fnew, 1, rb_str_new(bytea, bytea_len));
      PQfreemem(bytea);
      return rv;
    case 20:
    case 21:
    case 22:
    case 23:
    case 26:
      return rb_cstr2inum(data, 10);
    case 700:
    case 701:
    case 790:
      return rb_float_new(atof(data));
    case 1700:
      return rb_funcall(cBigDecimal, fnew, 1, rb_str_new(data, len));
    case 1082:
      return typecast_date(data, len);
    case 1114:
    case 1184:
      return typecast_timestamp(data, len);
    default:
      return rb_str_new(data, len);
  }
}
Exemple #5
0
/* --------------------------------
 * ForwardCacheToFrontend - simply forwards cached data to the frontend
 *
 * since the cached data passed from the caller is in escaped binary string
 * format, unescape it and send it to the frontend appending 'Z' at the end.
 * returns 0 on success, -1 otherwise.
 * --------------------------------
 */
static int ForwardCacheToFrontend(POOL_CONNECTION *frontend, char *cache, char tstate)
{
	int sendlen;
	size_t sz;
	char *binary_cache = NULL;

	binary_cache = (char *)PQunescapeBytea((unsigned char *)cache, &sz);
	sendlen = (int) sz;
	if (malloc_failed(binary_cache))
		return -1;

	pool_debug("ForwardCacheToFrontend: query cache found (%d bytes)", sendlen);

	/* forward cache to the frontend */
	pool_write(frontend, binary_cache, sendlen);

	/* send ReadyForQuery to the frontend*/
	pool_write(frontend, "Z", 1);
	sendlen = htonl(5);
	pool_write(frontend, &sendlen, sizeof(int));
	if (pool_write_and_flush(frontend, &tstate, 1) < 0)
	{
		pool_error("pool_query_cache_lookup: error while writing data to the frontend");
		PQfreemem(binary_cache);
		return -1;
	}

	PQfreemem(binary_cache);
	return 0;
}
Exemple #6
0
static inline QByteArray byteArrayFromData(const char *data)
{
    size_t unescapedLen;
    unsigned char *unescapedData = PQunescapeBytea((const unsigned char*)data, &unescapedLen);
    const QByteArray result((const char*)unescapedData, unescapedLen);
    //! @todo avoid deep copy; QByteArray does not allow passing ownership of data; maybe copy PQunescapeBytea code?
    PQfreemem(unescapedData);
    return result;
}
Exemple #7
0
void pp_export(PGconn * conn, const char * query)
{

	const int ascFmt = 0;
	int len = 0, i;
	int rows, ncol, icol;
	char * val;
	char * file;
	PGresult * res;
	const char * const * ival = (const char * const *) &val;
	FILE * fimg;

	/* execute the user provided query */
	res = PQexecParams(conn, query,
			0, //n. of params
			NULL, //oids guessed by backend
			NULL,
			NULL,
			NULL,
			ascFmt);
	if (PQresultStatus(res) != PGRES_TUPLES_OK) {
		pp_print_error(PQerrorMessage(conn));
		PQclear(res);
		return;
	}

	/* some check */
	icol = PQfnumber(res, opts.imagecol);
	if(icol==-1) {
		fprintf(stderr, "ERROR: Image column '%s' does not exist in result set.\n", opts.imagecol);
		PQclear(res);
		return;
	}
	if (!opts.nameprefix) {
		ncol = PQfnumber(res, opts.namecol);
		if(ncol==-1) {
			fprintf(stderr, "ERROR: Name column '%s' does not exist in result set.\n", opts.namecol);
			PQclear(res);
			return;
		}
	}
	rows = PQntuples(res);
	
	/* fetch the data and save */
	for (i = 0; i < rows; ++i) {
		val = PQunescapeBytea( PQgetvalue(res, i, icol), &len);
		if(opts.namecol) file = PQgetvalue(res, i, ncol);
		else file = image_name(opts.nameprefix, i);
		fimg = fopen(file, "w");
		fwrite(val, len, 1, fimg);
		fclose(fimg);
		PQfreemem(val);
		fprintf(stderr, "INFO: exported file %s\n", file);
	}
	PQclear(res);
}
const char* PgSQLResult::getDataStream(const std::string& s, uint64_t& size)
{
	std::string buf = PQgetvalue(m_handle, m_cursor, PQfnumber(m_handle, s.c_str()));
	uint8_t* temp = PQunescapeBytea( (const uint8_t*)buf.c_str(), (size_t*)&size);

	char* value = new char[buf.size()];
	strcpy(value, (char*)temp);

	PQfreemem(temp);
	return value;
}
Exemple #9
0
/*
 * Document-class: PG::TextDecoder::Bytea < PG::SimpleDecoder
 *
 * This is a decoder class for conversion of PostgreSQL bytea type
 * to binary String objects.
 *
 */
static VALUE
pg_text_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
{
	struct pg_blob_initialization bi;

	bi.blob_string = (char *)PQunescapeBytea((unsigned char*)val, &bi.length);
	if (bi.blob_string == NULL) {
		rb_raise(rb_eNoMemError, "PQunescapeBytea failure: probably not enough memory");
	}
	return rb_ensure(pg_create_blob, (VALUE)&bi, pg_pq_freemem, (VALUE)bi.blob_string);
}
CL_DataBuffer CL_PgsqlReaderProvider::get_column_binary(int index) const
{
	const unsigned char *const str = reinterpret_cast<unsigned char*>(PQgetvalue(result, current_row, index));
	if (str == nullptr)
		throw ("Index out of range");
	size_t length;
	auto deleter = [](void *ptr) {if (ptr) {free(ptr);} };
	CL_UniquePtr<unsigned char, decltype(deleter)> value(PQunescapeBytea(
				str,
				&length),
				deleter);
	CL_DataBuffer output(value.get(), length);
	return output;
}
/*
 * Document-class: PG::TextDecoder::Bytea < PG::SimpleDecoder
 *
 * This is a decoder class for conversion of PostgreSQL bytea type
 * to binary String objects.
 *
 */
static VALUE
pg_text_dec_bytea(t_pg_coder *conv, char *val, int len, int tuple, int field, int enc_idx)
{
    unsigned char *to;
    size_t to_len;
    VALUE ret;

    to = PQunescapeBytea( (unsigned char *)val, &to_len);

    ret = rb_tainted_str_new((char*)to, to_len);
    PQfreemem(to);

    return ret;
}
static inline value unescape_bytea(const char *s)
{
  size_t len;
  value v_res;
  char *buf = (char *) PQunescapeBytea((unsigned char*) s, &len);
  if (buf == NULL) {
    caml_failwith("Postgresql.unescape_bytea: illegal bytea string");
    return Val_unit;
  }
  v_res = caml_alloc_string(len);
  memcpy(String_val(v_res), buf, len);
  PQfreemem(buf);
  return v_res;
}
Exemple #13
0
VALUE do_postgres_typecast(const char *value, long length, const VALUE type, int encoding) {
  if (type == rb_cTrueClass) {
    return *value == 't' ? Qtrue : Qfalse;
  }
  else if (type == rb_cByteArray) {
    size_t new_length = 0;
    char *unescaped = (char *)PQunescapeBytea((unsigned char*)value, &new_length);
    VALUE byte_array = rb_funcall(rb_cByteArray, DO_ID_NEW, 1, rb_str_new(unescaped, new_length));

    PQfreemem(unescaped);
    return byte_array;
  }
  else {
    return data_objects_typecast(value, length, type, encoding);
  }
}
Exemple #14
0
    void operator()(std::ostream* v)
    {
        if(blob_ == bytea_type) 
        {
            unsigned char *val = (unsigned char*)PQgetvalue(res_, current_, fetch_col_);
            size_t len = 0;

            unsigned char *buf = PQunescapeBytea(val, &len);
            if(!buf)
                throw bad_value_cast();

            BOOST_SCOPE_EXIT((buf)) {
                PQfreemem(buf);
            } BOOST_SCOPE_EXIT_END

            v->write((char *)buf,len);
        }
Exemple #15
0
BYTE * CPgSQL::ReadScorcoData(const char * SQL, const char * param, BOOL * pSqlError, int * size)
{
	*pSqlError = false;
	*size = 0;

	PGresult* rco_result = NULL;
	if ( strcmp(param, "FETCHMODE") != 0 ) {
		// In normal mode (NOT in FETCHMODE), run the SQL query for a new result set
		rco_result = PQexec(pgsql, SQL);
	} else {
		// In FETCHMODE, use the result set from previous call to EXEC of a SQL query.
		rco_result = result;
	}
	if ( PQresultStatus(rco_result) != PGRES_TUPLES_OK ) {
		PQclear(rco_result);
		*pSqlError = true;
		return NULL;
	}
	if ( PQntuples(rco_result) > 0 ) {
		 // At lest one row left in the result set, assume it's the first field from the query,
		 // unescape it (since PostgreSQL is being queried in text mode), and return it in a
		 // heap allocated block of memory for the NWN VM to deallocate.
		unsigned int one_field_len = PQgetlength(rco_result, 0, 0);
		unsigned char* one_field = (unsigned char*)PQgetvalue(rco_result, 0, 0); // static do not deallocate !
		unsigned int unesc_field_len = 0;
		unsigned char *unesc_field = PQunescapeBytea(one_field, &unesc_field_len);
		if (unesc_field == NULL) {
			*pSqlError = true;
			return NULL;
		}
		PQclear(rco_result);
		*size = unesc_field_len;
		return unesc_field;
	} else {
		PQclear (rco_result);
		return NULL;
	}

	return NULL;
}
Exemple #16
0
/*!
 * \brief Convert a str to a db value, copy strings
 *
 * Convert a str to a db value, copy strings.
 * The postgresql module uses a custom escape function for BLOBs.
 * If the _s is linked in the db_val result, it will be returned zero
 * \param _t destination value type
 * \param _v destination value
 * \param _s source string
 * \param _l string length
 * \return 0 on success, negative on error
 */
int db_postgres_str2val(const db_type_t _t, db_val_t* _v, const char* _s,
		const int _l)
{
	/* use common function for non BLOB, NULL setting and input
	 * parameter checking */
	if ( _t != DB1_BLOB || _s == NULL || _v == NULL) {
		return db_str2val(_t, _v, _s, _l, 1);
	} else {
		char * tmp_s = NULL;
		LM_DBG("converting BLOB [%.*s]\n", _l, _s);
		/*
		 * The string is stored in new allocated memory, which we could
		 * not free later thus we need to copy it to some new memory here.
		 */
		tmp_s = (char*)PQunescapeBytea((unsigned char*)_s,
					(size_t*)(void*)&(VAL_BLOB(_v).len));
		if(tmp_s==NULL) {
			LM_ERR("PQunescapeBytea failed\n");
			return -7;
		}
		VAL_BLOB(_v).s = pkg_malloc(VAL_BLOB(_v).len + 1);
		if (VAL_BLOB(_v).s == NULL) {
			LM_ERR("no private memory left\n");
			PQfreemem(tmp_s);
			return -8;
		}
		LM_DBG("allocate %d+1 bytes memory for BLOB at %p",
				VAL_BLOB(_v).len, VAL_BLOB(_v).s);
		memcpy(VAL_BLOB(_v).s, tmp_s, VAL_BLOB(_v).len);
		PQfreemem(tmp_s);

		VAL_BLOB(_v).s[VAL_BLOB(_v).len] = '\0';
		VAL_TYPE(_v) = DB1_BLOB;
		VAL_FREE(_v) = 1;

		LM_DBG("got blob len %d\n", _l);
		return 0;

	}
}
Exemple #17
0
/*
 * Convert a str to a db value, does not copy strings
 * The postgresql module uses a custom escape function for BLOBs,
 * so the common db_str2val function from db_ut.h could not used.
 * If the _s is linked in the db_val result, it will be returned zero
 */
int pg_str2val(db_type_t _t, db_val_t* _v, char* _s, int _l)
{
	static str dummy_string = {"", 0};

#ifdef PARANOID
	if (!_v) {
		LM_ERR("db_val_t parameter cannot be NULL\n");
	}
#endif

	if (!_s) {
		memset(_v, 0, sizeof(db_val_t));
		/* Initialize the string pointers to a dummy empty
		 * string so that we do not crash when the NULL flag
		 * is set but the module does not check it properly
		 */
		VAL_STRING(_v) = dummy_string.s;
		VAL_STR(_v) = dummy_string;
		VAL_BLOB(_v) = dummy_string;
		VAL_TYPE(_v) = _t;
		VAL_NULL(_v) = 1;
		return 0;
	}
	VAL_NULL(_v) = 0;

	switch(_t) {
	case DB_INT:
		LM_DBG("converting INT [%s]\n", _s);
		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
			LM_ERR("failed to convert INT value from string\n");
			return -2;
		} else {
			VAL_TYPE(_v) = DB_INT;
			return 0;
		}
		break;

	case DB_BITMAP:
		LM_DBG("converting BITMAP [%s]\n", _s);
		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
			LM_ERR("failed to convert BITMAP value from string\n");
			return -3;
		} else {
			VAL_TYPE(_v) = DB_BITMAP;
			return 0;
		}
		break;
	
	case DB_DOUBLE:
		LM_DBG("converting DOUBLE [%s]\n", _s);
		if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) {
			LM_ERR("failed to convert DOUBLE value from string\n");
			return -4;
		} else {
			VAL_TYPE(_v) = DB_DOUBLE;
			return 0;
		}
		break;

	case DB_STRING:
		LM_DBG("converting STRING [%s]\n", _s);
		VAL_STRING(_v) = _s;
		VAL_TYPE(_v) = DB_STRING;
		return 0;

	case DB_STR:
		LM_DBG("converting STR [%s]\n", _s);
		VAL_STR(_v).s = (char*)_s;
		VAL_STR(_v).len = _l;
		VAL_TYPE(_v) = DB_STR;
		_s = 0;
		return 0;

	case DB_DATETIME:
		LM_DBG("converting DATETIME [%s]\n", _s);
		if (db_str2time(_s, &VAL_TIME(_v)) < 0) {
			LM_ERR("failed to convert datetime\n");
			return -5;
		} else {
			VAL_TYPE(_v) = DB_DATETIME;
			return 0;
		}
		break;

	case DB_BLOB:
		LM_DBG("converting BLOB [%s]\n", _s);
		/* PQunescapeBytea:  Converts a string representation of binary data 
		 * into binary data — the reverse of PQescapeBytea.
		 * This is needed when retrieving bytea data in text format, 
		 * but not when retrieving it in binary format.
		 */
		VAL_BLOB(_v).s = (char*)PQunescapeBytea((unsigned char*)_s, 
			(size_t*)(void*)&(VAL_BLOB(_v).len) );
		VAL_TYPE(_v) = DB_BLOB;
		LM_DBG("got blob len %d\n", _l);
		return 0;
	}
	return -6;
}
Exemple #18
0
QVariant QPSQLResult::data(int i)
{
    if (i >= PQnfields(d->result)) {
        qWarning("QPSQLResult::data: column %d out of range", i);
        return QVariant();
    }
    int ptype = PQftype(d->result, i);
    QVariant::Type type = qDecodePSQLType(ptype);
    const char *val = PQgetvalue(d->result, at(), i);
    if (PQgetisnull(d->result, at(), i))
        return QVariant(type);
    switch (type) {
    case QVariant::Bool:
        return QVariant((bool)(val[0] == 't'));
    case QVariant::String:
        return d->driver->isUtf8 ? QString::fromUtf8(val) : QString::fromAscii(val);
    case QVariant::LongLong:
        if (val[0] == '-')
            return QString::fromLatin1(val).toLongLong();
        else
            return QString::fromLatin1(val).toULongLong();
    case QVariant::Int:
        return atoi(val);
    case QVariant::Double:
        if (ptype == QNUMERICOID) {
            if (d->precisionPolicy != QSql::HighPrecision) {
                QVariant retval;
                bool convert;
                if (d->precisionPolicy == QSql::LowPrecisionInt64)
                    retval = QString::fromAscii(val).toLongLong(&convert);
                else if (d->precisionPolicy == QSql::LowPrecisionInt32)
                    retval = QString::fromAscii(val).toInt(&convert);
                else if (d->precisionPolicy == QSql::LowPrecisionDouble)
                    retval = QString::fromAscii(val).toDouble(&convert);
                if (!convert)
                    return QVariant();
                return retval;
            }
            return QString::fromAscii(val);
        }
        return strtod(val, 0);
    case QVariant::Date:
        if (val[0] == '\0') {
            return QVariant(QDate());
        } else {
#ifndef QT_NO_DATESTRING
            return QVariant(QDate::fromString(QString::fromLatin1(val), Qt::ISODate));
#else
            return QVariant(QString::fromLatin1(val));
#endif
        }
    case QVariant::Time: {
        const QString str = QString::fromLatin1(val);
#ifndef QT_NO_DATESTRING
        if (str.isEmpty())
            return QVariant(QTime());
        if (str.at(str.length() - 3) == QLatin1Char('+'))
            // strip the timezone
            return QVariant(QTime::fromString(str.left(str.length() - 3), Qt::ISODate));
        return QVariant(QTime::fromString(str, Qt::ISODate));
#else
        return QVariant(str);
#endif
    }
    case QVariant::DateTime: {
        QString dtval = QString::fromLatin1(val);
#ifndef QT_NO_DATESTRING
        if (dtval.length() < 10)
            return QVariant(QDateTime());
        // remove the timezone
        if (dtval.at(dtval.length() - 3) == QLatin1Char('+'))
            dtval.chop(3);
        // milliseconds are sometimes returned with 2 digits only
        if (dtval.at(dtval.length() - 3).isPunct())
            dtval += QLatin1Char('0');
        if (dtval.isEmpty())
            return QVariant(QDateTime());
        else
            return QVariant(QDateTime::fromString(dtval, Qt::ISODate));
#else
        return QVariant(dtval);
#endif
    }
    case QVariant::ByteArray: {
        size_t len;
        unsigned char *data = PQunescapeBytea((unsigned char*)val, &len);
        QByteArray ba((const char*)data, len);
        qPQfreemem(data);
        return QVariant(ba);
    }
    default:
    case QVariant::Invalid:
        qWarning("QPSQLResult::data: unknown data type");
    }
    return QVariant();
}
Exemple #19
0
unsigned char *postgresql_util_unescape_binary(const unsigned char *from,
                                               size_t *to_length)
{
    return PQunescapeBytea(from, to_length);
}
Exemple #20
0
static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees )
{
	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
	struct pdo_column_data *cols = stmt->columns;
	size_t tmp_len;

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

	/* We have already increased count by 1 in pgsql_stmt_fetch() */
	if (PQgetisnull(S->result, S->current_row - 1, colno)) { /* Check if we got NULL */
		*ptr = NULL;
		*len = 0;
	} else {
		*ptr = PQgetvalue(S->result, S->current_row - 1, colno);
		*len = PQgetlength(S->result, S->current_row - 1, colno);

		switch (cols[colno].param_type) {

			case PDO_PARAM_INT:
				ZEND_ATOL(S->cols[colno].intval, *ptr);
				*ptr = (char *) &(S->cols[colno].intval);
				*len = sizeof(zend_long);
				break;

			case PDO_PARAM_BOOL:
				S->cols[colno].boolval = **ptr == 't' ? 1: 0;
				*ptr = (char *) &(S->cols[colno].boolval);
				*len = sizeof(zend_bool);
				break;

			case PDO_PARAM_LOB:
				if (S->cols[colno].pgsql_type == OIDOID) {
					/* ooo, a real large object */
					char *end_ptr;
					Oid oid = (Oid)strtoul(*ptr, &end_ptr, 10);
					int loid = lo_open(S->H->server, oid, INV_READ);
					if (loid >= 0) {
						*ptr = (char*)pdo_pgsql_create_lob_stream(&stmt->database_object_handle, loid, oid);
						*len = 0;
						return *ptr ? 1 : 0;
					}
					*ptr = NULL;
					*len = 0;
					return 0;
				} else {
					char *tmp_ptr = (char *)PQunescapeBytea((unsigned char *)*ptr, &tmp_len);
					if (!tmp_ptr) {
						/* PQunescapeBytea returned an error */
						*len = 0;
						return 0;
					}
					if (!tmp_len) {
						/* Empty string, return as empty stream */
						*ptr = (char *)php_stream_memory_open(TEMP_STREAM_READONLY, "", 0);
						PQfreemem(tmp_ptr);
						*len = 0;
					} else {
						*ptr = estrndup(tmp_ptr, tmp_len);
						PQfreemem(tmp_ptr);
						*len = tmp_len;
						*caller_frees = 1;
					}
				}
				break;
			case PDO_PARAM_NULL:
			case PDO_PARAM_STR:
			case PDO_PARAM_STMT:
			case PDO_PARAM_INPUT_OUTPUT:
			case PDO_PARAM_ZVAL:
			default:
				break;
		}
	}

	return 1;
}
Exemple #21
0
/*
 * Convert a str to a db value, does not copy strings
 * The postgresql module uses a custom escape function for BLOBs.
 * If the _s is linked in the db_val result, it will be returned zero
 */
int db_postgres_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l)
{
	static str dummy_string = {"", 0};
	char *x;

	if (!_v) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	if (!_s) {
		memset(_v, 0, sizeof(db_val_t));
		/* Initialize the string pointers to a dummy empty
		 * string so that we do not crash when the NULL flag
		 * is set but the module does not check it properly
		 */
		VAL_STR(_v) = dummy_string;
		VAL_TYPE(_v) = _t;
		VAL_NULL(_v) = 1;
		return 0;
	}
	VAL_NULL(_v) = 0;

	switch(_t) {
	case DB_INT:
		LM_DBG("converting INT [%s]\n", _s);
		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
			LM_ERR("failed to convert INT value from string\n");
			return -2;
		} else {
			VAL_TYPE(_v) = DB_INT;
			return 0;
		}
		break;

	case DB_BIGINT:
		LM_DBG("converting BIGINT [%s]\n", _s);
		if (db_str2bigint(_s, &VAL_BIGINT(_v)) < 0) {
			LM_ERR("failed to convert BIGINT value from string\n");
			return -2;
		} else {
			VAL_TYPE(_v) = DB_BIGINT;
			return 0;
		}
		break;

	case DB_BITMAP:
		LM_DBG("converting BITMAP [%s]\n", _s);
		if (db_str2int(_s, &VAL_INT(_v)) < 0) {
			LM_ERR("failed to convert BITMAP value from string\n");
			return -3;
		} else {
			VAL_TYPE(_v) = DB_BITMAP;
			return 0;
		}
		break;

	case DB_DOUBLE:
		LM_DBG("converting DOUBLE [%s]\n", _s);
		if (db_str2double(_s, &VAL_DOUBLE(_v)) < 0) {
			LM_ERR("failed to convert DOUBLE value from string\n");
			return -4;
		} else {
			VAL_TYPE(_v) = DB_DOUBLE;
			return 0;
		}
		break;

	case DB_STRING:
		LM_DBG("converting STRING [%s]\n", _s);
		VAL_STRING(_v) = _s;
		VAL_TYPE(_v) = DB_STRING;
		VAL_FREE(_v) = 1;
		return 0;

	case DB_STR:
		LM_DBG("converting STR [%.*s]\n", _l, _s);
		VAL_STR(_v).s = (char*)_s;
		VAL_STR(_v).len = _l;
		VAL_TYPE(_v) = DB_STR;
		VAL_FREE(_v) = 1;
		return 0;

	case DB_DATETIME:
		LM_DBG("converting DATETIME [%s]\n", _s);
		if (db_str2time(_s, &VAL_TIME(_v)) < 0) {
			LM_ERR("failed to convert datetime\n");
			return -5;
		} else {
			VAL_TYPE(_v) = DB_DATETIME;
			return 0;
		}
		break;

	case DB_BLOB:
		LM_DBG("converting BLOB [%.*s]\n", _l, _s);
		/* PQunescapeBytea:  Converts a string representation of binary data
		 * into binary data - the reverse of PQescapeBytea.
		 * This is needed when retrieving bytea data in text format,
		 * but not when retrieving it in binary format.
		 */
		x = (char*)PQunescapeBytea((unsigned char*)_s,
			(size_t*)(void*)&(VAL_BLOB(_v).len) );
		VAL_BLOB(_v).s = pkg_malloc( VAL_BLOB(_v).len+1 );
		if (VAL_BLOB(_v).s==NULL) {
			LM_ERR("failed to allocate pkg for BLOB\n");
			return -6;
		}
		memcpy( VAL_BLOB(_v).s, x, VAL_BLOB(_v).len);
		VAL_BLOB(_v).s[VAL_BLOB(_v).len]='\0';
		free(x);
		VAL_TYPE(_v) = DB_BLOB;
		VAL_FREE(_v) = 1;
		LM_DBG("got blob len %d\n", _l);
		return 0;
	}
	return -6;
}
int main(int, char **)
{
    PQescapeBytea(0, 0, 0);
    PQunescapeBytea(0, 0);
    return 0;
}