Esempio n. 1
0
File: odbc.c Progetto: Bakus/gammu
const char *SMSDODBC_GetString(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	SQLLEN sqllen;
	int size;
	SQLRETURN ret;
	char shortbuffer[1];

	if (field > SMSD_ODBC_MAX_RETURN_STRINGS) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, too many fields!", field);
		return NULL;
	}

	/* Figure out string length */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, shortbuffer, 0, &sqllen);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string,0) failed");
		return NULL;
	}

	/*
	 * This hack seems to be needed to avoid type breakage on Win64, don't ask me why.
	 *
	 * Might be actually bug in MinGW compiler, but when using SQLLEN type bellow
	 * anything fails (it does not match to SQL_NULL_DATA and realloc always fails).
	 */
	size = sqllen;

	/* Did not we get NULL? */
	if (size == SQL_NULL_DATA) {
		SMSD_Log(DEBUG_SQL, Config, "Field %d returning NULL", field);
		return NULL;
	}

	/* Allocate string */
	Config->conn.odbc.retstr[field] = realloc(Config->conn.odbc.retstr[field], size + 1);
	if (Config->conn.odbc.retstr[field] == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, failed to allocate %d bytes of memory", field, size + 1);
		return NULL;
	}

	/* Actually grab result from database */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, Config->conn.odbc.retstr[field], size + 1, &sqllen);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string) failed");
		return NULL;
	}

	SMSD_Log(DEBUG_SQL, Config, "Field %d returning string \"%s\"", field, Config->conn.odbc.retstr[field]);

	return Config->conn.odbc.retstr[field];
}
Esempio n. 2
0
File: odbc.c Progetto: liyvhg/gammu
/* Connects to database */
static GSM_Error SMSDODBC_Connect(GSM_SMSDConfig * Config)
{
	SQLRETURN ret;
	int field;
	char driver_name[1000];
	SQLSMALLINT len;

	for (field = 0; field < SMSD_ODBC_MAX_RETURN_STRINGS; field++) {
		Config->conn.odbc.retstr[field] = NULL;
	}

	ret = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &Config->conn.odbc.env);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_ENV, Config->conn.odbc.env, "SQLAllocHandle(ENV) failed");
		return ERR_DB_DRIVER;
	}

	ret = SQLSetEnvAttr (Config->conn.odbc.env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_ENV, Config->conn.odbc.env, "SQLSetEnvAttr failed");
		return ERR_DB_CONFIG;
	}

	ret = SQLAllocHandle (SQL_HANDLE_DBC, Config->conn.odbc.env, &Config->conn.odbc.dbc);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_ENV, Config->conn.odbc.env, "SQLAllocHandle(DBC) failed");
		return ERR_DB_CONFIG;
	}

	ret = SQLConnect(Config->conn.odbc.dbc,
			  (SQLCHAR*)Config->host, SQL_NTS,
			  (SQLCHAR*)Config->user, SQL_NTS,
			  (SQLCHAR*)Config->password, SQL_NTS);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_DBC, Config->conn.odbc.dbc, "SQLConnect failed");
		return ERR_DB_CONNECT;
	}

	ret = SQLGetInfo(Config->conn.odbc.dbc, SQL_DRIVER_NAME, driver_name, sizeof(driver_name), &len);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_DBC, Config->conn.odbc.dbc, "SQLGetInfo failed");
		return ERR_DB_CONNECT;
	} else{
		SMSD_Log(DEBUG_NOTICE, Config, "Connected to driver %s", driver_name);
	}


	return ERR_NONE;
}
Esempio n. 3
0
File: odbc.c Progetto: liyvhg/gammu
const char *SMSDODBC_GetString(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	SQLLEN size;
	SQLRETURN ret;
	char shortbuffer[1];

	if (field > SMSD_ODBC_MAX_RETURN_STRINGS) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, too many fields!", field);
		return NULL;
	}

	/* Figure out string length */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, shortbuffer, 0, &size);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string,0) failed");
		return NULL;
	}

	/* Did not we get NULL? */
	if (size == SQL_NULL_DATA) {
		SMSD_Log(DEBUG_SQL, Config, "Field %d returning NULL", field);
		return NULL;
	}

	/* Allocate string */
	Config->conn.odbc.retstr[field] = realloc(Config->conn.odbc.retstr[field], size + 1);
	if (Config->conn.odbc.retstr[field] == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, failed to allocate %ld bytes of memory", field, (long)(size + 1));
		return NULL;
	}

	/* Actually grab result from database */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, Config->conn.odbc.retstr[field], size + 1, &size);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string) failed");
		return NULL;
	}

	SMSD_Log(DEBUG_SQL, Config, "Field %d returning string \"%s\"", field, Config->conn.odbc.retstr[field]);

	return Config->conn.odbc.retstr[field];
}
Esempio n. 4
0
File: odbc.c Progetto: liyvhg/gammu
long long SMSDODBC_GetNumber(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	SQLRETURN ret;
	SQLINTEGER value = -1;

	ret = SQLGetData(res->odbc, field + 1, SQL_C_SLONG, &value, 0, NULL);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(long) failed");
		return -1;
	}
	return value;
}
Esempio n. 5
0
File: odbc.c Progetto: liyvhg/gammu
unsigned long SMSDODBC_AffectedRows(GSM_SMSDConfig * Config, SQL_result *res)
{
	SQLRETURN ret;
	SQLLEN count;

	ret = SQLRowCount (res->odbc, &count);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_DBC, Config->conn.odbc.dbc, "SQLRowCount failed");
		return 0;
	}
	return (unsigned long)count;
}
Esempio n. 6
0
File: odbc.c Progetto: liyvhg/gammu
/* set pointer to next row */
int SMSDODBC_NextRow(GSM_SMSDConfig * Config, SQL_result *res)
{
	SQLRETURN ret;

	ret = SQLFetch(res->odbc);

	if (!SQL_SUCCEEDED(ret)) {
		if (ret != SQL_NO_DATA) {
			SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLFetch failed");
		}
		return 0;
	}
	return 1;
}
Esempio n. 7
0
File: odbc.c Progetto: liyvhg/gammu
time_t SMSDODBC_GetDate(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	SQL_TIMESTAMP_STRUCT sqltime;
	GSM_DateTime DT;
	SQLRETURN ret;

	ret = SQLGetData(res->odbc, field + 1, SQL_C_TYPE_TIMESTAMP, &sqltime, 0, NULL);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(timestamp) failed");
		return -1;
	}

	DT.Year = sqltime.year;
	DT.Month = sqltime.month;
	DT.Day = sqltime.day;
	DT.Hour = sqltime.hour;
	DT.Minute = sqltime.minute;
	DT.Second = sqltime.second;

	return Fill_Time_T(DT);
}
Esempio n. 8
0
File: odbc.c Progetto: liyvhg/gammu
static GSM_Error SMSDODBC_Query(GSM_SMSDConfig * Config, const char *query, SQL_result * res)
{
	SQLRETURN ret;

	ret = SQLAllocHandle(SQL_HANDLE_STMT, Config->conn.odbc.dbc, &res->odbc);
	if (!SQL_SUCCEEDED(ret)) {
		return ERR_SQL;
	}

	ret = SQLExecDirect (res->odbc, (SQLCHAR*)query, SQL_NTS);
	/*
	 * If SQLExecDirect executes a searched update, insert, or delete
	 * statement that does not affect any rows at the data source, the call
	 * to SQLExecDirect returns SQL_NO_DATA.
	 */
	if (SQL_SUCCEEDED(ret) || ret == SQL_NO_DATA) {
		return ERR_NONE;
	}

	SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLExecDirect failed");
	return ERR_SQL;
}