mirror of https://github.com/acanas/swad-core.git
Version 22.49.7: Oct 18, 2022 Code refactoring related to database.
This commit is contained in:
parent
11ddb85b10
commit
98c0490344
|
@ -245,7 +245,7 @@ static void RSS_WriteCallsForExams (FILE *FileRSS,struct Crs_Course *Crs)
|
||||||
unsigned NumExams;
|
unsigned NumExams;
|
||||||
unsigned NumExa;
|
unsigned NumExa;
|
||||||
|
|
||||||
if (Gbl.DB.DatabaseIsOpen)
|
if (DB_CheckIfDatabaseIsOpen ())
|
||||||
{
|
{
|
||||||
/***** Write exam announcements (only future exams) in current course *****/
|
/***** Write exam announcements (only future exams) in current course *****/
|
||||||
if ((NumExams = Cfe_DB_GetFutureCallsForExamsInCurrentCrs (&mysql_res)))
|
if ((NumExams = Cfe_DB_GetFutureCallsForExamsInCurrentCrs (&mysql_res)))
|
||||||
|
|
|
@ -716,7 +716,7 @@ void Cfe_CreateListCallsForExams (struct Cfe_CallsForExams *CallsForExams)
|
||||||
unsigned NumExaAnns;
|
unsigned NumExaAnns;
|
||||||
unsigned NumExaAnn;
|
unsigned NumExaAnn;
|
||||||
|
|
||||||
if (Gbl.DB.DatabaseIsOpen)
|
if (DB_CheckIfDatabaseIsOpen ())
|
||||||
{
|
{
|
||||||
/***** Get exam dates (ordered from more recent to older)
|
/***** Get exam dates (ordered from more recent to older)
|
||||||
of visible calls for exams
|
of visible calls for exams
|
||||||
|
|
|
@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate
|
||||||
|
|
||||||
TODO: Attach pdf files in multimedia.
|
TODO: Attach pdf files in multimedia.
|
||||||
*/
|
*/
|
||||||
#define Log_PLATFORM_VERSION "SWAD 22.49.6 (2022-10-18)"
|
#define Log_PLATFORM_VERSION "SWAD 22.49.7 (2022-10-18)"
|
||||||
#define CSS_FILE "swad22.49.4.css"
|
#define CSS_FILE "swad22.49.4.css"
|
||||||
#define JS_FILE "swad22.49.js"
|
#define JS_FILE "swad22.49.js"
|
||||||
/*
|
/*
|
||||||
|
Version 22.49.7: Oct 18, 2022 Code refactoring related to database. (333218 lines)
|
||||||
Version 22.49.6: Oct 18, 2022 Code refactoring related to alerts. (333197 lines)
|
Version 22.49.6: Oct 18, 2022 Code refactoring related to alerts. (333197 lines)
|
||||||
Version 22.49.5: Oct 18, 2022 Code refactoring related to boxes. (333190 lines)
|
Version 22.49.5: Oct 18, 2022 Code refactoring related to boxes. (333190 lines)
|
||||||
Version 22.49.4: Oct 18, 2022 Lighter background colors in tables.
|
Version 22.49.4: Oct 18, 2022 Lighter background colors in tables.
|
||||||
|
|
|
@ -429,7 +429,7 @@ static void Con_ShowConnectedUsrsWithARoleBelongingToCurrentCrsOnRightColumn (Ro
|
||||||
|
|
||||||
static unsigned Con_GetConnectedUsrsTotal (Rol_Role_t Role)
|
static unsigned Con_GetConnectedUsrsTotal (Rol_Role_t Role)
|
||||||
{
|
{
|
||||||
if (!Gbl.DB.DatabaseIsOpen)
|
if (!DB_CheckIfDatabaseIsOpen ())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/***** Get number of connected users with a role from database *****/
|
/***** Get number of connected users with a role from database *****/
|
||||||
|
|
|
@ -51,7 +51,16 @@ extern struct Globals Gbl;
|
||||||
/************************* Private global variables **************************/
|
/************************* Private global variables **************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static MYSQL DB_mysql;
|
static struct
|
||||||
|
{
|
||||||
|
MYSQL mysql;
|
||||||
|
bool IsOpen;
|
||||||
|
bool ThereAreLockedTables;
|
||||||
|
} DB_Database =
|
||||||
|
{
|
||||||
|
.IsOpen = false,
|
||||||
|
.ThereAreLockedTables = false,
|
||||||
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/***************************** Private prototypes ****************************/
|
/***************************** Private prototypes ****************************/
|
||||||
|
@ -3896,7 +3905,7 @@ static void DB_CreateTable (const char *Query)
|
||||||
HTM_Txt (Query);
|
HTM_Txt (Query);
|
||||||
HTM_LI_End ();
|
HTM_LI_End ();
|
||||||
|
|
||||||
if (mysql_query (&DB_mysql,Query))
|
if (mysql_query (&DB_Database.mysql,Query))
|
||||||
DB_ExitOnMySQLError ("can not create table");
|
DB_ExitOnMySQLError ("can not create table");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3906,15 +3915,24 @@ static void DB_CreateTable (const char *Query)
|
||||||
|
|
||||||
void DB_OpenDBConnection (void)
|
void DB_OpenDBConnection (void)
|
||||||
{
|
{
|
||||||
if (mysql_init (&DB_mysql) == NULL)
|
if (mysql_init (&DB_Database.mysql) == NULL)
|
||||||
Err_ShowErrorAndExit ("Can not init MySQL.");
|
Err_ShowErrorAndExit ("Can not init MySQL.");
|
||||||
|
|
||||||
if (mysql_real_connect (&DB_mysql,Cfg_DATABASE_HOST,
|
if (mysql_real_connect (&DB_Database.mysql,Cfg_DATABASE_HOST,
|
||||||
Cfg_DATABASE_USER,Gbl.Config.DatabasePassword,
|
Cfg_DATABASE_USER,Gbl.Config.DatabasePassword,
|
||||||
Cfg_DATABASE_DBNAME,0,NULL,0) == NULL)
|
Cfg_DATABASE_DBNAME,0,NULL,0) == NULL)
|
||||||
DB_ExitOnMySQLError ("can not connect to database");
|
DB_ExitOnMySQLError ("can not connect to database");
|
||||||
|
|
||||||
Gbl.DB.DatabaseIsOpen = true;
|
DB_Database.IsOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/************************ Check if database is open **************************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
bool DB_CheckIfDatabaseIsOpen (void)
|
||||||
|
{
|
||||||
|
return DB_Database.IsOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -3923,10 +3941,10 @@ void DB_OpenDBConnection (void)
|
||||||
|
|
||||||
void DB_CloseDBConnection (void)
|
void DB_CloseDBConnection (void)
|
||||||
{
|
{
|
||||||
if (Gbl.DB.DatabaseIsOpen)
|
if (DB_CheckIfDatabaseIsOpen ())
|
||||||
{
|
{
|
||||||
mysql_close (&DB_mysql); // Close the connection to the database
|
mysql_close (&DB_Database.mysql); // Close the connection to the database
|
||||||
Gbl.DB.DatabaseIsOpen = false;
|
DB_Database.IsOpen = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4171,13 +4189,13 @@ static unsigned long DB_QuerySELECTusingQueryStr (char *Query,
|
||||||
Err_ShowErrorAndExit ("Wrong query string.");
|
Err_ShowErrorAndExit ("Wrong query string.");
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
|
||||||
/***** Store query result *****/
|
/***** Store query result *****/
|
||||||
if ((*mysql_res = mysql_store_result (&DB_mysql)) == NULL)
|
if ((*mysql_res = mysql_store_result (&DB_Database.mysql)) == NULL)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
|
||||||
/***** Return number of rows of result *****/
|
/***** Return number of rows of result *****/
|
||||||
|
@ -4288,7 +4306,7 @@ void DB_QueryINSERT (const char *MsgError,const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
@ -4312,13 +4330,13 @@ long DB_QueryINSERTandReturnCode (const char *MsgError,const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
|
||||||
/***** Return the code of the inserted item *****/
|
/***** Return the code of the inserted item *****/
|
||||||
return (long) mysql_insert_id (&DB_mysql);
|
return (long) mysql_insert_id (&DB_Database.mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -4339,7 +4357,7 @@ void DB_QueryREPLACE (const char *MsgError,const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
@ -4363,7 +4381,7 @@ void DB_QueryUPDATE (const char *MsgError,const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
@ -4387,7 +4405,7 @@ void DB_QueryDELETE (const char *MsgError,const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
@ -4411,7 +4429,7 @@ void DB_CreateTmpTable (const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError ("can not create temporary table");
|
DB_ExitOnMySQLError ("can not create temporary table");
|
||||||
|
@ -4441,7 +4459,7 @@ void DB_Query (const char *MsgError,const char *fmt,...)
|
||||||
Err_NotEnoughMemoryExit ();
|
Err_NotEnoughMemoryExit ();
|
||||||
|
|
||||||
/***** Query database and free query string pointer *****/
|
/***** Query database and free query string pointer *****/
|
||||||
Result = mysql_query (&DB_mysql,Query); // Returns 0 on success
|
Result = mysql_query (&DB_Database.mysql,Query); // Returns 0 on success
|
||||||
free (Query);
|
free (Query);
|
||||||
if (Result)
|
if (Result)
|
||||||
DB_ExitOnMySQLError (MsgError);
|
DB_ExitOnMySQLError (MsgError);
|
||||||
|
@ -4470,18 +4488,30 @@ void DB_ExitOnMySQLError (const char *Message)
|
||||||
char BigErrorMsg[64 * 1024];
|
char BigErrorMsg[64 * 1024];
|
||||||
|
|
||||||
snprintf (BigErrorMsg,sizeof (BigErrorMsg),"Database error: %s (%s).",
|
snprintf (BigErrorMsg,sizeof (BigErrorMsg),"Database error: %s (%s).",
|
||||||
Message,mysql_error (&DB_mysql));
|
Message,mysql_error (&DB_Database.mysql));
|
||||||
Err_ShowErrorAndExit (BigErrorMsg);
|
Err_ShowErrorAndExit (BigErrorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*********** Set variable that indicates there are locked tables *************/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
void DB_SetThereAreLockedTables (void)
|
||||||
|
{
|
||||||
|
DB_Database.ThereAreLockedTables = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/********** Unlock tables to make the exchange of items atomic ***************/
|
/********** Unlock tables to make the exchange of items atomic ***************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void DB_UnlockTables (void)
|
void DB_UnlockTables (void)
|
||||||
{
|
{
|
||||||
Gbl.DB.LockedTables = false; // Set to false before the following unlock...
|
if (DB_Database.ThereAreLockedTables)
|
||||||
// ...to not retry the unlock if error in unlocking
|
{
|
||||||
DB_Query ("can not unlock tables",
|
DB_Database.ThereAreLockedTables = false; // Set to false before the following unlock...
|
||||||
"UNLOCK TABLES");
|
// ...to not retry the unlock if error in unlocking
|
||||||
|
DB_Query ("can not unlock tables",
|
||||||
|
"UNLOCK TABLES");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
void DB_CreateTablesIfNotExist (void);
|
void DB_CreateTablesIfNotExist (void);
|
||||||
void DB_OpenDBConnection (void);
|
void DB_OpenDBConnection (void);
|
||||||
|
bool DB_CheckIfDatabaseIsOpen (void);
|
||||||
void DB_CloseDBConnection (void);
|
void DB_CloseDBConnection (void);
|
||||||
|
|
||||||
void DB_BuildQuery (char **Query,const char *fmt,...);
|
void DB_BuildQuery (char **Query,const char *fmt,...);
|
||||||
|
@ -77,6 +78,7 @@ void DB_Query (const char *MsgError,const char *fmt,...);
|
||||||
void DB_FreeMySQLResult (MYSQL_RES **mysql_res);
|
void DB_FreeMySQLResult (MYSQL_RES **mysql_res);
|
||||||
void DB_ExitOnMySQLError (const char *Message);
|
void DB_ExitOnMySQLError (const char *Message);
|
||||||
|
|
||||||
|
void DB_SetThereAreLockedTables (void);
|
||||||
void DB_UnlockTables (void);
|
void DB_UnlockTables (void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -553,8 +553,7 @@ void Err_NoPermissionExit (void)
|
||||||
void Err_ShowErrorAndExit (const char *Txt)
|
void Err_ShowErrorAndExit (const char *Txt)
|
||||||
{
|
{
|
||||||
/***** Unlock tables if locked *****/
|
/***** Unlock tables if locked *****/
|
||||||
if (Gbl.DB.LockedTables)
|
DB_UnlockTables ();
|
||||||
DB_UnlockTables ();
|
|
||||||
|
|
||||||
if (!Gbl.WebService.IsWebService)
|
if (!Gbl.WebService.IsWebService)
|
||||||
{
|
{
|
||||||
|
|
|
@ -631,7 +631,7 @@ void Exa_DB_LockTables (void)
|
||||||
{
|
{
|
||||||
DB_Query ("can not lock tables to exchange sets of questions",
|
DB_Query ("can not lock tables to exchange sets of questions",
|
||||||
"LOCK TABLES exa_sets WRITE");
|
"LOCK TABLES exa_sets WRITE");
|
||||||
Gbl.DB.LockedTables = true;
|
DB_SetThereAreLockedTables ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -498,7 +498,7 @@ void Gam_DB_LockTable (void)
|
||||||
{
|
{
|
||||||
DB_Query ("can not lock tables to move game question",
|
DB_Query ("can not lock tables to move game question",
|
||||||
"LOCK TABLES gam_questions WRITE");
|
"LOCK TABLES gam_questions WRITE");
|
||||||
Gbl.DB.LockedTables = true;
|
DB_SetThereAreLockedTables ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -106,9 +106,6 @@ void Gbl_InitializeGlobals (void)
|
||||||
Gbl.F.XML = NULL;
|
Gbl.F.XML = NULL;
|
||||||
Gbl.F.Rep = NULL; // Report
|
Gbl.F.Rep = NULL; // Report
|
||||||
|
|
||||||
Gbl.DB.DatabaseIsOpen = false;
|
|
||||||
Gbl.DB.LockedTables = false;
|
|
||||||
|
|
||||||
Gbl.Prefs.Language = Txt_Current_CGI_SWAD_Language;
|
Gbl.Prefs.Language = Txt_Current_CGI_SWAD_Language;
|
||||||
Gbl.Prefs.FirstDayOfWeek = Cal_FIRST_DAY_OF_WEEK_DEFAULT; // Default first day of week
|
Gbl.Prefs.FirstDayOfWeek = Cal_FIRST_DAY_OF_WEEK_DEFAULT; // Default first day of week
|
||||||
Gbl.Prefs.DateFormat = Dat_FORMAT_DEFAULT; // Default date format
|
Gbl.Prefs.DateFormat = Dat_FORMAT_DEFAULT; // Default date format
|
||||||
|
|
|
@ -97,11 +97,6 @@ struct Globals
|
||||||
bool DivsEndWritten; // Used to avoid writing more than once the HTML end
|
bool DivsEndWritten; // Used to avoid writing more than once the HTML end
|
||||||
bool HTMLEndWritten; // Used to avoid writing more than once the HTML end
|
bool HTMLEndWritten; // Used to avoid writing more than once the HTML end
|
||||||
} Layout;
|
} Layout;
|
||||||
struct
|
|
||||||
{
|
|
||||||
bool DatabaseIsOpen;
|
|
||||||
bool LockedTables;
|
|
||||||
} DB;
|
|
||||||
|
|
||||||
/* To compute execution time of the program */
|
/* To compute execution time of the program */
|
||||||
struct timeval tvStart;
|
struct timeval tvStart;
|
||||||
|
|
|
@ -54,7 +54,7 @@ void Grp_DB_LockTables (void)
|
||||||
"crs_users READ,"
|
"crs_users READ,"
|
||||||
"crs_user_settings READ,"
|
"crs_user_settings READ,"
|
||||||
"roo_rooms READ");
|
"roo_rooms READ");
|
||||||
Gbl.DB.LockedTables = true;
|
DB_SetThereAreLockedTables ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -313,7 +313,7 @@ void Hld_GetListHolidays (struct Hld_Holidays *Holidays)
|
||||||
unsigned NumHld;
|
unsigned NumHld;
|
||||||
struct Hld_Holiday *Hld;
|
struct Hld_Holiday *Hld;
|
||||||
|
|
||||||
if (Gbl.DB.DatabaseIsOpen)
|
if (DB_CheckIfDatabaseIsOpen ())
|
||||||
{
|
{
|
||||||
if (Holidays->LstIsRead)
|
if (Holidays->LstIsRead)
|
||||||
Hld_FreeListHolidays (Holidays);
|
Hld_FreeListHolidays (Holidays);
|
||||||
|
|
|
@ -282,7 +282,7 @@ void Lnk_GetListLinks (void)
|
||||||
MYSQL_RES *mysql_res;
|
MYSQL_RES *mysql_res;
|
||||||
unsigned NumLnk;
|
unsigned NumLnk;
|
||||||
|
|
||||||
if (Gbl.DB.DatabaseIsOpen)
|
if (DB_CheckIfDatabaseIsOpen ())
|
||||||
{
|
{
|
||||||
/***** Get institutional links from database *****/
|
/***** Get institutional links from database *****/
|
||||||
if ((Gbl.Links.Num = Lnk_DB_GetLinks (&mysql_res))) // Links found...
|
if ((Gbl.Links.Num = Lnk_DB_GetLinks (&mysql_res))) // Links found...
|
||||||
|
|
|
@ -153,7 +153,7 @@ void Prg_DB_LockTableItems (void)
|
||||||
{
|
{
|
||||||
DB_Query ("can not lock table",
|
DB_Query ("can not lock table",
|
||||||
"LOCK TABLES prg_items WRITE");
|
"LOCK TABLES prg_items WRITE");
|
||||||
Gbl.DB.LockedTables = true;
|
DB_SetThereAreLockedTables ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -635,7 +635,7 @@ void Prg_DB_LockTableResources (void)
|
||||||
{
|
{
|
||||||
DB_Query ("can not lock table",
|
DB_Query ("can not lock table",
|
||||||
"LOCK TABLES prg_resources WRITE");
|
"LOCK TABLES prg_resources WRITE");
|
||||||
Gbl.DB.LockedTables = true;
|
DB_SetThereAreLockedTables ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
Loading…
Reference in New Issue