* 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:
Benoît Minisini 2011-12-22 00:31:57 +00:00
parent ade026fd48
commit c1f20cb4fe
6 changed files with 144 additions and 94 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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)
{

View file

@ -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()

View file

@ -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),

View file

@ -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 */