[GB.DB]
* NEW: Connection.Timeout is a new property that defines the connection timeout in seconds. The value is 20 seconds by default. git-svn-id: svn://localhost/gambas/trunk@4309 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
ade026fd48
commit
c1f20cb4fe
6 changed files with 144 additions and 94 deletions
|
@ -599,6 +599,8 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
|
|||
char *name;
|
||||
char *host;
|
||||
char *socket;
|
||||
my_bool reconnect = TRUE;
|
||||
unsigned int timeout;
|
||||
|
||||
conn = mysql_init(NULL);
|
||||
|
||||
|
@ -621,8 +623,14 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
|
|||
}
|
||||
else
|
||||
socket = NULL;
|
||||
|
||||
if (!mysql_real_connect( conn, host, desc->user, desc->password,
|
||||
|
||||
mysql_options(conn, MYSQL_OPT_RECONNECT, &reconnect);
|
||||
|
||||
timeout = db->timeout;
|
||||
|
||||
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
|
||||
|
||||
if (!mysql_real_connect(conn, host, desc->user, desc->password,
|
||||
name, desc->port == NULL ? 0 : atoi(desc->port), socket,
|
||||
CLIENT_MULTI_RESULTS /*client flag */)){
|
||||
mysql_close(conn);
|
||||
|
|
|
@ -524,6 +524,7 @@ fflush(stderr);
|
|||
|
||||
}
|
||||
|
||||
SQLSetConnectAttr(odbc->odbcHandle, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)(intptr_t)db->timeout, 0);
|
||||
/* Connect to Database (Data Source Name) */
|
||||
retcode =SQLConnect(odbc->odbcHandle, (SQLCHAR *) desc->host, SQL_NTS, (SQLCHAR *) desc->user, SQL_NTS, (SQLCHAR *) desc->password, SQL_NTS);
|
||||
if ((retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO))
|
||||
|
@ -575,7 +576,7 @@ fflush(stderr);
|
|||
|
||||
static void close_database(DB_DATABASE *db)
|
||||
{
|
||||
SQLRETURN retcode;
|
||||
//SQLRETURN retcode;
|
||||
#ifdef ODBC_DEBUG_HEADER
|
||||
fprintf(stderr,"[ODBC][%s][%d]\n",__FILE__,__LINE__);
|
||||
fprintf(stderr,"\tclose_database\n");
|
||||
|
@ -584,37 +585,38 @@ fflush(stderr);
|
|||
|
||||
ODBC_CONN *conn = (ODBC_CONN *)db->handle;
|
||||
|
||||
if (conn->odbcHandle != NULL){
|
||||
retcode=SQLDisconnect(conn->odbcHandle);
|
||||
}else
|
||||
{
|
||||
GB.Error("ODBC module internal error");
|
||||
}
|
||||
if (conn->odbcHandle)
|
||||
SQLDisconnect(conn->odbcHandle);
|
||||
else
|
||||
GB.Error("ODBC module internal error");
|
||||
|
||||
|
||||
if (conn->odbcHandle != NULL){
|
||||
retcode=SQLFreeHandle(SQL_HANDLE_DBC, conn->odbcHandle);
|
||||
conn->odbcHandle=NULL;
|
||||
}else
|
||||
if (conn->odbcHandle)
|
||||
{
|
||||
GB.Error("ODBC module internal error");
|
||||
SQLFreeHandle(SQL_HANDLE_DBC, conn->odbcHandle);
|
||||
conn->odbcHandle = NULL;
|
||||
}
|
||||
else
|
||||
GB.Error("ODBC module internal error");
|
||||
|
||||
if (conn->odbcEnvHandle != NULL){
|
||||
retcode=SQLFreeHandle(SQL_HANDLE_ENV, conn->odbcEnvHandle);
|
||||
conn->odbcEnvHandle=NULL;
|
||||
}else
|
||||
if (conn->odbcEnvHandle)
|
||||
{
|
||||
GB.Error("ODBC module internal error");
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, conn->odbcEnvHandle);
|
||||
conn->odbcEnvHandle = NULL;
|
||||
}
|
||||
else
|
||||
GB.Error("ODBC module internal error");
|
||||
|
||||
if (conn->dsn_name != NULL)free(conn->dsn_name);
|
||||
if (conn->user_name != NULL)free(conn->user_name);
|
||||
if (conn != NULL){
|
||||
SQL_Handle_free(conn);
|
||||
db->handle=NULL;
|
||||
if (conn->dsn_name)
|
||||
free(conn->dsn_name);
|
||||
|
||||
if (conn->user_name)
|
||||
free(conn->user_name);
|
||||
|
||||
if (conn)
|
||||
{
|
||||
SQL_Handle_free(conn);
|
||||
db->handle = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1082,14 +1084,12 @@ fflush(stderr);
|
|||
|
||||
static int query_fill(DB_DATABASE *db, DB_RESULT result, int pos, GB_VARIANT_VALUE * buffer, int next)
|
||||
{
|
||||
|
||||
|
||||
ODBC_RESULT *res = (ODBC_RESULT *) result;
|
||||
GB_VARIANT value;
|
||||
SQLRETURN retcode2;
|
||||
SQLINTEGER i;
|
||||
ODBC_FIELDS *current;
|
||||
SQLRETURN retcode;
|
||||
//SQLRETURN retcode;
|
||||
int nresultcols;
|
||||
SQLINTEGER displaysize;
|
||||
//int V_OD_erg=0;
|
||||
|
@ -1100,16 +1100,13 @@ fprintf(stderr,"\tquery_fill result %p,result->odbcStatHandle %p, pos %d\n",res,
|
|||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
|
||||
nresultcols = get_num_columns(res);
|
||||
|
||||
current = res->fields;
|
||||
for (i = 0; i < nresultcols; i++)
|
||||
{
|
||||
|
||||
if(current->next != NULL)current = (ODBC_FIELDS *) current->next;
|
||||
|
||||
|
||||
if(current->next != NULL)
|
||||
current = (ODBC_FIELDS *) current->next;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1123,7 +1120,6 @@ fflush(stderr);
|
|||
{
|
||||
retcode2 = SQLFetchScroll(res->odbcStatHandle, SQL_FETCH_NEXT, pos + 1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1176,7 +1172,7 @@ if (displaysize>0)
|
|||
if (type != SQL_LONGVARCHAR && type != SQL_VARBINARY && type != SQL_LONGVARBINARY)
|
||||
{
|
||||
fieldata=malloc(sizeof(char)*(displaysize));
|
||||
retcode=SQLGetData(res->odbcStatHandle,i+1,SQL_C_CHAR , fieldata,displaysize,&read);
|
||||
SQLGetData(res->odbcStatHandle,i+1,SQL_C_CHAR , fieldata,displaysize,&read);
|
||||
|
||||
} else
|
||||
{
|
||||
|
@ -1237,20 +1233,19 @@ return FALSE;
|
|||
|
||||
static void blob_read(DB_RESULT result, int pos, int field, DB_BLOB *blob)
|
||||
{
|
||||
|
||||
|
||||
int i;
|
||||
//int outlen;
|
||||
//int precision;
|
||||
//int scale;
|
||||
//int displaysize;
|
||||
//char * pointer;
|
||||
ODBC_RESULT * res= (ODBC_RESULT *) result;
|
||||
ODBC_FIELDS * cfield ;
|
||||
SQLLEN strlen;
|
||||
SQLRETURN retcode;
|
||||
i=0;
|
||||
cfield=res->fields;
|
||||
int i;
|
||||
//int outlen;
|
||||
//int precision;
|
||||
//int scale;
|
||||
//int displaysize;
|
||||
//char * pointer;
|
||||
ODBC_RESULT * res= (ODBC_RESULT *) result;
|
||||
ODBC_FIELDS * cfield ;
|
||||
SQLLEN strlen;
|
||||
SQLRETURN retcode;
|
||||
|
||||
i = 0;
|
||||
cfield = res->fields;
|
||||
|
||||
#ifdef ODBC_DEBUG_HEADER
|
||||
fprintf(stderr,"[ODBC][%s][%d]\n",__FILE__,__LINE__);
|
||||
|
@ -1258,49 +1253,71 @@ fprintf(stderr,"\tblob_read DB_RESULT %p, dbresult->stathandle %p, pos %d , fiel
|
|||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
while (i < field ){
|
||||
|
||||
if (cfield->next== NULL){
|
||||
while (i < field )
|
||||
{
|
||||
if (cfield->next== NULL)
|
||||
{
|
||||
GB.Error("ODBC module :Internal error1");
|
||||
return;
|
||||
}
|
||||
cfield=(ODBC_FIELDS *) cfield->next;
|
||||
if (cfield== NULL){
|
||||
GB.Error("ODBC module :Internal error2");
|
||||
}
|
||||
i=i+1;
|
||||
}
|
||||
if(i>field) GB.Error("ODBC module : Internal error");
|
||||
|
||||
blob->data=NULL;
|
||||
if (cfield->outlen > 0) {
|
||||
blob->data=malloc( sizeof(char)*cfield->outlen);
|
||||
cfield=(ODBC_FIELDS *) cfield->next;
|
||||
|
||||
if (cfield== NULL)
|
||||
{
|
||||
GB.Error("ODBC module :Internal error2");
|
||||
return;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i > field)
|
||||
{
|
||||
GB.Error("ODBC module : Internal error");
|
||||
return;
|
||||
}
|
||||
|
||||
blob->data=NULL;
|
||||
if (cfield->outlen > 0)
|
||||
{
|
||||
blob->data = malloc( sizeof(char)*cfield->outlen);
|
||||
blob->length = cfield->outlen;
|
||||
|
||||
DB.Query.Init();
|
||||
|
||||
retcode=SQLGetData(res->odbcStatHandle,field+1,SQL_C_BINARY , blob->data,blob->length, &strlen);
|
||||
}else
|
||||
retcode = SQLGetData(res->odbcStatHandle,field+1,SQL_C_BINARY , blob->data,blob->length, &strlen);
|
||||
|
||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
|
||||
{
|
||||
blob->data=NULL; //
|
||||
blob->length=0;
|
||||
GB.Error("Unable to retrieve blob data");
|
||||
free(blob->data);
|
||||
blob->length = 0;
|
||||
blob->data = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
blob->data = NULL; //
|
||||
blob->length = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
char *data;
|
||||
int len;
|
||||
|
||||
if (!unquote_blob(blob->data, blob->length, DB.Query.AddLength))
|
||||
{
|
||||
len = DB.Query.Length();
|
||||
data = DB.Query.GetNew();
|
||||
if (!unquote_blob(blob->data, blob->length, DB.Query.AddLength))
|
||||
{
|
||||
len = DB.Query.Length();
|
||||
data = DB.Query.GetNew();
|
||||
}
|
||||
else
|
||||
blob->constant = TRUE;
|
||||
|
||||
free(blob->data);//091107
|
||||
blob->data=data;
|
||||
blob->length=len;
|
||||
|
||||
|
||||
blob->data = data;
|
||||
blob->length = len;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1415,9 +1432,13 @@ fflush(stderr);
|
|||
retcode=SQLDescribeCol(res->odbcStatHandle, field + 1, colname, sizeof(colname),
|
||||
&colnamelen, &coltype, &precision, &scale, NULL);
|
||||
|
||||
|
||||
return conv_type(coltype);
|
||||
|
||||
if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
|
||||
{
|
||||
GB.Error("Unable to retrieve field type");
|
||||
return GB_T_NULL;
|
||||
}
|
||||
else
|
||||
return conv_type(coltype);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -681,13 +681,20 @@ static int open_database(DB_DESC *desc, DB_DATABASE *db)
|
|||
PGresult *res;
|
||||
int status;
|
||||
char *name;
|
||||
char dbname[512];
|
||||
|
||||
if (desc->name)
|
||||
name = desc->name;
|
||||
else
|
||||
name = "template1";
|
||||
|
||||
conn = PQsetdbLogin(desc->host, desc->port, NULL, NULL, name, desc->user, desc->password);
|
||||
if (snprintf(dbname, sizeof(dbname), "dbname='%s' timeout=%d", get_quote_string(name, strlen(name), '\''), db->timeout) >= sizeof(dbname))
|
||||
{
|
||||
GB.Error("Cannot open database: database name too long");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
conn = PQsetdbLogin(desc->host, desc->port, NULL, NULL, dbname, desc->user, desc->password);
|
||||
|
||||
if (!conn)
|
||||
{
|
||||
|
|
|
@ -171,7 +171,9 @@ void gPrinter::storeSettings()
|
|||
|
||||
g_object_unref(G_OBJECT(_settings));
|
||||
_settings = gtk_print_settings_copy(gtk_print_operation_get_print_settings(_operation));
|
||||
#if DEBUG_ME
|
||||
gtk_print_settings_to_file(_settings, "/home/benoit/settings.txt", NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void gPrinter::defineSettings()
|
||||
|
|
|
@ -149,6 +149,7 @@ BEGIN_METHOD(CCONNECTION_new, GB_STRING url)
|
|||
|
||||
THIS->db.handle = NULL;
|
||||
THIS->db.ignore_case = FALSE; // Now case is sensitive by default!
|
||||
THIS->db.timeout = 20; // Connection timeout is 20 seconds by default
|
||||
|
||||
if (_current == NULL)
|
||||
_current = THIS;
|
||||
|
@ -191,7 +192,6 @@ BEGIN_METHOD(CCONNECTION_new, GB_STRING url)
|
|||
}
|
||||
|
||||
THIS->desc.host = GB.NewZeroString(url);
|
||||
|
||||
THIS->desc.name = GB.NewZeroString(name);
|
||||
|
||||
__BAD_URL:
|
||||
|
@ -247,6 +247,16 @@ BEGIN_PROPERTY(CCONNECTION_version)
|
|||
END_PROPERTY
|
||||
|
||||
|
||||
BEGIN_PROPERTY(Connection_Timeout)
|
||||
|
||||
if (READ_PROPERTY)
|
||||
GB.ReturnInteger(THIS->db.timeout);
|
||||
else
|
||||
THIS->db.timeout = VPROP(GB_INTEGER);
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
|
||||
BEGIN_PROPERTY(CCONNECTION_opened)
|
||||
|
||||
CHECK_DB();
|
||||
|
@ -722,6 +732,7 @@ GB_DESC CConnectionDesc[] =
|
|||
GB_PROPERTY("Password", "s", CCONNECTION_password),
|
||||
GB_PROPERTY("Name", "s", CCONNECTION_name),
|
||||
GB_PROPERTY("Port", "s", CCONNECTION_port),
|
||||
GB_PROPERTY("Timeout", "i", Connection_Timeout),
|
||||
GB_PROPERTY_READ("Charset", "s", CCONNECTION_charset),
|
||||
GB_PROPERTY_READ("Version", "i", CCONNECTION_version),
|
||||
GB_PROPERTY_READ("Opened", "b", CCONNECTION_opened),
|
||||
|
|
|
@ -48,25 +48,26 @@ typedef
|
|||
|
||||
typedef
|
||||
struct {
|
||||
void *handle; /* Connection handle */
|
||||
int version; /* Version of the database system */
|
||||
char *charset; /* Charset used by the database */
|
||||
void *data; /* Can be used by the driver for storing its own private data */
|
||||
void *handle; /* Connection handle */
|
||||
int version; /* Version of the database system */
|
||||
char *charset; /* Charset used by the database */
|
||||
void *data; /* Can be used by the driver for storing its own private data */
|
||||
int error; /* Last SQL error code raise by a query */
|
||||
unsigned ignore_case : 1; /* If table, field and index names are case sensitive */
|
||||
int timeout; /* Connection timeout */
|
||||
unsigned ignore_case : 1; /* If table, field and index names are case sensitive */
|
||||
struct {
|
||||
unsigned no_table_type : 1; /* Tables do not have types */
|
||||
unsigned no_serial : 1; /* Serial fields are not supported */
|
||||
unsigned no_blob : 1; /* Blob fields are not supported */
|
||||
unsigned no_seek : 1; /* Cannot seek anywhere in a Result */
|
||||
unsigned no_nest : 1; /* Cannot nest transactions */
|
||||
unsigned no_case : 1; /* If table, field and index names can be case sensitive or not */
|
||||
unsigned no_table_type : 1; /* Tables do not have types */
|
||||
unsigned no_serial : 1; /* Serial fields are not supported */
|
||||
unsigned no_blob : 1; /* Blob fields are not supported */
|
||||
unsigned no_seek : 1; /* Cannot seek anywhere in a Result */
|
||||
unsigned no_nest : 1; /* Cannot nest transactions */
|
||||
unsigned no_case : 1; /* If table, field and index names can be case sensitive or not */
|
||||
unsigned schema : 1; /* If table names can be prefixed by a schema name and a dot */
|
||||
}
|
||||
flags;
|
||||
struct {
|
||||
const char *keyword; /* keyword for limiting the result of a query */
|
||||
int pos; /* position of 'limit' keyword */
|
||||
const char *keyword; /* keyword for limiting the result of a query */
|
||||
int pos; /* position of 'limit' keyword */
|
||||
}
|
||||
limit;
|
||||
const char *db_name_char; /* These characters are allowed in a database name */
|
||||
|
|
Loading…
Reference in a new issue