diff options
| author | nwrl <n/a> | 2025-08-07 14:52:14 -0500 |
|---|---|---|
| committer | nwrl <n/a> | 2025-08-07 14:52:14 -0500 |
| commit | 9d792ef2a7b24172d04a85797c97f9f241cde17f (patch) | |
| tree | 44693b156f615d3ca4c9047f7292312af2ae0e7c /nameblocker.sp | |
| parent | 5fd1519b8d7ee69c9decb7d076d2072af2fc4978 (diff) | |
Add database locking where necessary
Diffstat (limited to 'nameblocker.sp')
| -rw-r--r-- | nameblocker.sp | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/nameblocker.sp b/nameblocker.sp index 9e16b97..c4c945c 100644 --- a/nameblocker.sp +++ b/nameblocker.sp | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | // first writing to the database and then updating the lists, there realistically shouldn't be any weird memory problems. | 32 | // first writing to the database and then updating the lists, there realistically shouldn't be any weird memory problems. |
| 33 | // That makes this a whole lot easier | 33 | // That makes this a whole lot easier |
| 34 | 34 | ||
| 35 | // If database locking takes too long I might need to use threaded calls, which sounds like a fucking nightmare | ||
| 36 | |||
| 35 | #pragma newdecls required | 37 | #pragma newdecls required |
| 36 | #pragma semicolon 1 | 38 | #pragma semicolon 1 |
| 37 | 39 | ||
| @@ -124,39 +126,60 @@ void xRegisterIntConVar(ConVar& cv, int defaultVal, const char[] name, const cha | |||
| 124 | 126 | ||
| 125 | int initPrepStatements() { | 127 | int initPrepStatements() { |
| 126 | char sqlerr[256 + 1]; | 128 | char sqlerr[256 + 1]; |
| 127 | if((dbInsert = SQL_PrepareQuery(db, DBINSERTSTATEMENT, sqlerr, sizeof(sqlerr))) == null) | 129 | SQL_LockDatabase(db); |
| 130 | if((dbInsert = SQL_PrepareQuery(db, DBINSERTSTATEMENT, sqlerr, sizeof(sqlerr))) == null) { | ||
| 128 | logAndFail("Could not prepare insert statement: %s", sqlerr); | 131 | logAndFail("Could not prepare insert statement: %s", sqlerr); |
| 129 | if((dbDelete = SQL_PrepareQuery(db, DBDELETESTATEMENT, sqlerr, sizeof(sqlerr))) == null) | 132 | SQL_UnlockDatabase(db); |
| 133 | } | ||
| 134 | if((dbDelete = SQL_PrepareQuery(db, DBDELETESTATEMENT, sqlerr, sizeof(sqlerr))) == null) { | ||
| 130 | logAndFail("Could not prepare delete statement: %s", sqlerr); | 135 | logAndFail("Could not prepare delete statement: %s", sqlerr); |
| 131 | if((dbReplace = SQL_PrepareQuery(db, DBREPLACESTATEMENT, sqlerr, sizeof(sqlerr))) == null) | 136 | SQL_UnlockDatabase(db); |
| 137 | } | ||
| 138 | if((dbReplace = SQL_PrepareQuery(db, DBREPLACESTATEMENT, sqlerr, sizeof(sqlerr))) == null) { | ||
| 132 | logAndFail("Could not prepare replace statement: %s", sqlerr); | 139 | logAndFail("Could not prepare replace statement: %s", sqlerr); |
| 133 | if((dbPopulate = SQL_PrepareQuery(db, DBPOPULATESTATEMENT, sqlerr, sizeof(sqlerr))) == null) | 140 | SQL_UnlockDatabase(db); |
| 141 | } | ||
| 142 | if((dbPopulate = SQL_PrepareQuery(db, DBPOPULATESTATEMENT, sqlerr, sizeof(sqlerr))) == null) { | ||
| 134 | logAndFail("Could not prepare populate statement: %s", sqlerr); | 143 | logAndFail("Could not prepare populate statement: %s", sqlerr); |
| 144 | SQL_UnlockDatabase(db); | ||
| 145 | } | ||
| 135 | 146 | ||
| 136 | // This might not work / I might have to use Format() instead of binding. We will see | 147 | // This might not work / I might have to use Format() instead of binding. We will see |
| 137 | if(SQL_BindParamString(dbInsert, 0, DBTABLENAME, true)) { | 148 | if(SQL_BindParamString(dbInsert, 0, DBTABLENAME, true)) { |
| 138 | SQL_GetError(dbInsert, sqlerr, sizeof(sqlerr)); | 149 | SQL_GetError(dbInsert, sqlerr, sizeof(sqlerr)); |
| 150 | SQL_UnlockDatabase(db); | ||
| 139 | logAndFail("Could not bind tablename to insert statement: %s", sqlerr); | 151 | logAndFail("Could not bind tablename to insert statement: %s", sqlerr); |
| 140 | } | 152 | } |
| 141 | if(SQL_BindParamString(dbDelete, 0, DBTABLENAME, true)) { | 153 | if(SQL_BindParamString(dbDelete, 0, DBTABLENAME, true)) { |
| 142 | SQL_GetError(dbDelete, sqlerr, sizeof(sqlerr)); | 154 | SQL_GetError(dbDelete, sqlerr, sizeof(sqlerr)); |
| 155 | SQL_UnlockDatabase(db); | ||
| 143 | logAndFail("Could not bind tablename to delete statement: %s", sqlerr); | 156 | logAndFail("Could not bind tablename to delete statement: %s", sqlerr); |
| 144 | } | 157 | } |
| 145 | if( SQL_BindParamString(dbReplace, 0, DBTABLENAME, true)) { | 158 | if( SQL_BindParamString(dbReplace, 0, DBTABLENAME, true)) { |
| 146 | SQL_GetError(dbReplace, sqlerr, sizeof(sqlerr)); | 159 | SQL_GetError(dbReplace, sqlerr, sizeof(sqlerr)); |
| 160 | SQL_UnlockDatabase(db); | ||
| 147 | logAndFail("Could not bind tablename to replace statement: %s", sqlerr); | 161 | logAndFail("Could not bind tablename to replace statement: %s", sqlerr); |
| 148 | } | 162 | } |
| 149 | if(SQL_BindParamString(dbPopulate, 0, DBTABLENAME, true)) { | 163 | if(SQL_BindParamString(dbPopulate, 0, DBTABLENAME, true)) { |
| 150 | SQL_GetError(dbPopulate, sqlerr, sizeof(sqlerr)); | 164 | SQL_GetError(dbPopulate, sqlerr, sizeof(sqlerr)); |
| 165 | SQL_UnlockDatabase(db); | ||
| 151 | logAndFail("Could not bind tablename to populate statement: %s", sqlerr); | 166 | logAndFail("Could not bind tablename to populate statement: %s", sqlerr); |
| 152 | } | 167 | } |
| 153 | 168 | ||
| 154 | // If I knew how to do macros this would be much nicer | 169 | // If I knew how to do macros this would be much nicer |
| 155 | 170 | ||
| 171 | SQL_UnlockDatabase(db); | ||
| 156 | return 0; | 172 | return 0; |
| 157 | } | 173 | } |
| 158 | 174 | ||
| 159 | int loadFromDatabase() { | 175 | int loadFromDatabase() { |
| 176 | // Initialize and populate datatypes | ||
| 177 | regexlist = new ArrayList(ByteCountToCells(HANDLE_SIZE)); | ||
| 178 | if(regexlist == null) logAndFail("Could not initialize regexlist ArrayList"); | ||
| 179 | |||
| 180 | patternlist = new ArrayList(ByteCountToCells(PATTERN_MAX_LEN)); | ||
| 181 | if(patternlist == null) logAndFail("Could not initialize patternlist ArrayList"); | ||
| 182 | |||
| 160 | // Get database handle | 183 | // Get database handle |
| 161 | char sqlerr[256 + 1]; | 184 | char sqlerr[256 + 1]; |
| 162 | db = SQLite_UseDatabase("sourcemod-local", sqlerr, sizeof(sqlerr)); | 185 | db = SQLite_UseDatabase("sourcemod-local", sqlerr, sizeof(sqlerr)); |
| @@ -166,23 +189,21 @@ int loadFromDatabase() { | |||
| 166 | // I could make this a prepared statement, but I don't believe it's entirely necessary | 189 | // I could make this a prepared statement, but I don't believe it's entirely necessary |
| 167 | char sqlcbuf[256 + 1]; | 190 | char sqlcbuf[256 + 1]; |
| 168 | Format(sqlcbuf, sizeof(sqlcbuf), "CREATE TABLE IF NOT EXISTS \"%s\" (id INTEGER NOT NULL, regexstr TEXT NOT NULL ON CONFLICT IGNORE, steamid64 TEXT NOT NULL ON CONFLICT IGNORE, dateof TEXT DEFAULT CURRENT_DATE, timeof TEXT DEFAULT CURRENT_TIME, PRIMARY KEY (id), UNIQUE (regexstr));", DBTABLENAME); | 191 | Format(sqlcbuf, sizeof(sqlcbuf), "CREATE TABLE IF NOT EXISTS \"%s\" (id INTEGER NOT NULL, regexstr TEXT NOT NULL ON CONFLICT IGNORE, steamid64 TEXT NOT NULL ON CONFLICT IGNORE, dateof TEXT DEFAULT CURRENT_DATE, timeof TEXT DEFAULT CURRENT_TIME, PRIMARY KEY (id), UNIQUE (regexstr));", DBTABLENAME); |
| 192 | |||
| 193 | SQL_LockDatabase(db); | ||
| 169 | if(!SQL_FastQuery(db, sqlcbuf)) { | 194 | if(!SQL_FastQuery(db, sqlcbuf)) { |
| 170 | SQL_GetError(db, sqlerr, sizeof(sqlerr)); | 195 | SQL_GetError(db, sqlerr, sizeof(sqlerr)); |
| 196 | SQL_UnlockDatabase(db); | ||
| 171 | logAndFail("Could not initialize nameblocker table: %s", sqlerr); | 197 | logAndFail("Could not initialize nameblocker table: %s", sqlerr); |
| 172 | } | 198 | } |
| 173 | 199 | ||
| 174 | // Initialize and populate datatypes | ||
| 175 | regexlist = new ArrayList(ByteCountToCells(HANDLE_SIZE)); | ||
| 176 | if(regexlist == null) logAndFail("Could not initialize regexlist ArrayList"); | ||
| 177 | |||
| 178 | patternlist = new ArrayList(ByteCountToCells(PATTERN_MAX_LEN)); | ||
| 179 | if(patternlist == null) logAndFail("Could not initialize patternlist ArrayList"); | ||
| 180 | |||
| 181 | // select patterns from nameblock table/database | 200 | // select patterns from nameblock table/database |
| 182 | if(SQL_Execute(dbPopulate)) { | 201 | if(SQL_Execute(dbPopulate)) { |
| 183 | SQL_GetError(dbPopulate, sqlerr, sizeof(sqlerr)); | 202 | SQL_GetError(dbPopulate, sqlerr, sizeof(sqlerr)); |
| 203 | SQL_UnlockDatabase(db); | ||
| 184 | logAndFail("Population query failed"); | 204 | logAndFail("Population query failed"); |
| 185 | } | 205 | } |
| 206 | SQL_UnlockDatabase(db); | ||
| 186 | 207 | ||
| 187 | // compile each pattern & insert | 208 | // compile each pattern & insert |
| 188 | Regex cur; char reerr[256]; RegexError reenum; | 209 | Regex cur; char reerr[256]; RegexError reenum; |
