]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/sql_cmds.c
Tweak mutex order for SD
[bacula/bacula] / bacula / src / cats / sql_cmds.c
index a96b789a04a0406bb4b8405d8d76eb908737595a..9dd7a2bdac3a07259f2db8aad7200a5661a1a393 100644 (file)
 #include "bacula.h"
 #include "cats.h"
 
+const char *cleanup_created_job =
+   "UPDATE Job SET JobStatus='f', StartTime=SchedTime, EndTime=SchedTime "
+   "WHERE JobStatus = 'C'";
+const char *cleanup_running_job = 
+   "UPDATE Job SET JobStatus='f', EndTime=StartTime WHERE JobStatus = 'R'";
 
 /* For sql_update.c db_update_stats */
 const char *fill_jobhisto =
@@ -60,7 +65,7 @@ const char *fill_jobhisto =
            "JobErrors, JobMissingFiles, PoolId, FileSetId, PriorJobId, "
            "PurgedFiles, HasBase "
           "FROM Job "
-         "WHERE JobStatus IN ('T', 'f', 'A', 'E') "
+         "WHERE JobStatus IN ('T','W','f','A','E') "
            "AND JobId NOT IN (SELECT JobId FROM JobHisto) "
            "AND JobTDate < %s ";
 
@@ -75,7 +80,7 @@ const char *client_backups =
    " WHERE Client.Name='%s'"
    " AND FileSet='%s'"
    " AND Client.ClientId=Job.ClientId"
-   " AND JobStatus='T' AND Type='B'" 
+   " AND JobStatus IN ('T','W') AND Type='B'" 
    " AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId"
    " AND Job.FileSetId=FileSet.FileSetId"
    " ORDER BY Job.StartTime";
@@ -139,10 +144,10 @@ const char *select_backup_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
    "WHERE (Job.JobTDate<%s AND ((DelCandidates.JobFiles=0) OR "
-   "(DelCandidates.JobStatus!='T'))) OR "
+   "(DelCandidates.JobStatus NOT IN ('T','W')))) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
-   "AND Job.Level='F' AND Job.JobStatus='T' AND Job.Type IN ('B','M') "
+   "AND Job.Level='F' AND Job.JobStatus IN ('T','W') AND Job.Type IN ('B','M') "
    "AND Job.FileSetId=DelCandidates.FileSetId)";
 
 /* Select Jobs from the DelCandidates table that have a
@@ -152,10 +157,10 @@ const char *select_backup_del =
 const char *select_verify_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
-   "AND Job.Type='V' AND Job.Level='V' AND Job.JobStatus='T' "
+   "AND Job.Type='V' AND Job.Level='V' AND Job.JobStatus IN ('T','W') "
    "AND Job.FileSetId=DelCandidates.FileSetId)";
 
 
@@ -165,7 +170,7 @@ const char *select_verify_del =
 const char *select_restore_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='R')";
@@ -176,7 +181,7 @@ const char *select_restore_del =
 const char *select_admin_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='D')";
@@ -188,7 +193,7 @@ const char *select_admin_del =
 const char *select_migrate_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='g')";
@@ -200,7 +205,7 @@ const char *select_migrate_del =
 const char *select_copy_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobTdate<%s AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='C')";
@@ -212,10 +217,10 @@ const char *select_backup_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
    "WHERE (Job.JobId=DelCandidates.JobId AND ((DelCandidates.JobFiles=0) OR "
-   "(DelCandidates.JobStatus!='T'))) OR "
+   "(DelCandidates.JobStatus NOT IN ('T','W')))) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
-   "AND Job.Level='F' AND Job.JobStatus='T' AND Job.Type IN ('B','M') "
+   "AND Job.Level='F' AND Job.JobStatus IN ('T','W') AND Job.Type IN ('B','M') "
    "AND Job.FileSetId=DelCandidates.FileSetId)";
 
 /* Select Jobs from the DelCandidates table that have a
@@ -225,10 +230,10 @@ const char *select_backup_del =
 const char *select_verify_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
-   "AND Job.Type='V' AND Job.Level='V' AND Job.JobStatus='T' "
+   "AND Job.Type='V' AND Job.Level='V' AND Job.JobStatus IN ('T','W') "
    "AND Job.FileSetId=DelCandidates.FileSetId)";
 
 
@@ -238,7 +243,7 @@ const char *select_verify_del =
 const char *select_restore_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='R')";
@@ -249,7 +254,7 @@ const char *select_restore_del =
 const char *select_admin_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='D')";
@@ -261,7 +266,7 @@ const char *select_admin_del =
 const char *select_migrate_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='g')";
@@ -269,7 +274,7 @@ const char *select_migrate_del =
 const char *select_copy_del =
    "SELECT DISTINCT DelCandidates.JobId,DelCandidates.PurgedFiles "
    "FROM Job,DelCandidates "
-   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus!='T') OR "
+   "WHERE (Job.JobId=DelCandidates.JobId AND DelCandidates.JobStatus NOT IN ('T','W')) OR "
    "(Job.JobTDate>%s "
    "AND Job.ClientId=%s "
    "AND Job.Type='C')";
@@ -285,9 +290,15 @@ const char *uar_count_files =
 const char *uar_list_jobs =
    "SELECT JobId,Client.Name as Client,StartTime,Level as "
    "JobLevel,JobFiles,JobBytes "
-   "FROM Client,Job WHERE Client.ClientId=Job.ClientId AND JobStatus='T' "
+   "FROM Client,Job WHERE Client.ClientId=Job.ClientId AND JobStatus IN ('T','W') "
    "AND Type='B' ORDER BY StartTime DESC LIMIT 20";
 
+const char *uar_print_jobs =  
+   "SELECT DISTINCT JobId,Level,JobFiles,JobBytes,StartTime,VolumeName"
+   " FROM Job JOIN JobMedia USING (JobId) JOIN Media USING (MediaId) "
+   " WHERE JobId IN (%s) "
+   " ORDER BY StartTime ASC";
+
 /*
  * Find all files for a particular JobId and insert them into
  *  the tree during a restore.
@@ -305,8 +316,8 @@ const char *uar_last_full =
    "INSERT INTO temp1 SELECT Job.JobId,JobTdate "
    "FROM Client,Job,JobMedia,Media,FileSet WHERE Client.ClientId=%s "
    "AND Job.ClientId=%s "
-   "AND Job.StartTime<'%s' "
-   "AND Level='F' AND JobStatus='T' AND Type='B' "
+   "AND Job.StartTime < '%s' "
+   "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' "
    "AND JobMedia.JobId=Job.JobId "
    "AND Media.Enabled=1 "
    "AND JobMedia.MediaId=Media.MediaId "
@@ -320,7 +331,7 @@ const char *uar_full =
    "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes,"
    "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime "
    "FROM temp1,Job,JobMedia,Media WHERE temp1.JobId=Job.JobId "
-   "AND Level='F' AND JobStatus='T' AND Type='B' "
+   "AND Level='F' AND JobStatus IN ('T','W') AND Type='B' "
    "AND Media.Enabled=1 "
    "AND JobMedia.JobId=Job.JobId "
    "AND JobMedia.MediaId=Media.MediaId";
@@ -336,7 +347,7 @@ const char *uar_dif =
    "AND JobMedia.JobId=Job.JobId "
    "AND Media.Enabled=1 "
    "AND JobMedia.MediaId=Media.MediaId "
-   "AND Job.Level='D' AND JobStatus='T' AND Type='B' "
+   "AND Job.Level='D' AND JobStatus IN ('T','W') AND Type='B' "
    "AND Job.FileSetId=FileSet.FileSetId "
    "AND FileSet.FileSet='%s' "
    "%s"
@@ -353,7 +364,7 @@ const char *uar_inc =
    "AND Media.Enabled=1 "
    "AND JobMedia.JobId=Job.JobId "
    "AND JobMedia.MediaId=Media.MediaId "
-   "AND Job.Level='I' AND JobStatus='T' AND Type='B' "
+   "AND Job.Level='I' AND JobStatus IN ('T','W') AND Type='B' "
    "AND Job.FileSetId=FileSet.FileSetId "
    "AND FileSet.FileSet='%s' "
    "%s";
@@ -399,6 +410,7 @@ const char *uar_jobid_fileindex =
    "AND Job.ClientId=Client.ClientId "
    "AND Path.PathId=File.PathId "
    "AND Filename.FilenameId=File.FilenameId "
+   "AND JobStatus IN ('T','W') AND Type='B' "
    "ORDER BY Job.StartTime DESC LIMIT 1";
 
 const char *uar_jobids_fileindex =
@@ -438,6 +450,165 @@ const char *uar_jobid_fileindex_from_table =
 #include "bacula.h"
 #include "cats.h"
 
+/* Get the list of the last recent version with a given jobid list 
+ * This is a tricky part because with SQL the result of 
+ *
+ * SELECT MAX(A), B, C, D FROM... GROUP BY (B,C)
+ *
+ * doesn't give the good result (for D).
+ *
+ * With PostgreSQL, we can use DISTINCT ON(), but with Mysql or Sqlite,
+ * we need an extra join using JobTDate. 
+ */
+const char *select_recent_version_with_basejob[4] = {
+ /* MySQL */
+"SELECT FileId, Job.JobId AS JobId, FileIndex, File.PathId AS PathId, "
+       "File.FilenameId AS FilenameId, LStat, MD5 "
+"FROM Job, File, ( "
+    "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId "
+      "FROM ( "
+        "SELECT JobTDate, PathId, FilenameId "   /* Get all normal files */
+          "FROM File JOIN Job USING (JobId) "    /* from selected backup */
+         "WHERE File.JobId IN (%s) "
+          "UNION ALL "
+        "SELECT JobTDate, PathId, FilenameId "   /* Get all files from */ 
+          "FROM BaseFiles "                      /* BaseJob */
+               "JOIN File USING (FileId) "
+               "JOIN Job  ON    (BaseJobId = Job.JobId) "
+         "WHERE BaseFiles.JobId IN (%s) "        /* Use Max(JobTDate) to find */
+       ") AS tmp GROUP BY PathId, FilenameId "   /* the latest file version */
+    ") AS T1 "
+"WHERE (Job.JobId IN ( "  /* Security, we force JobId to be valid */
+        "SELECT DISTINCT BaseJobId FROM BaseFiles WHERE JobId IN (%s)) "
+        "OR Job.JobId IN (%s)) "
+  "AND T1.JobTDate = Job.JobTDate " /* Join on JobTDate to get the orginal */
+  "AND Job.JobId = File.JobId "     /* Job/File record */
+  "AND T1.PathId = File.PathId "
+  "AND T1.FilenameId = File.FilenameId",
+
+  /* Postgresql */    /* The DISTINCT ON () permits to avoid extra join */
+ "SELECT DISTINCT ON (FilenameId, PathId) StartTime, JobId, FileId, "
+         "FileIndex, PathId, FilenameId, LStat, MD5 "
+   "FROM "
+       "(SELECT FileId, JobId, PathId, FilenameId, FileIndex, LStat, MD5 "
+          "FROM File WHERE JobId IN (%s) "
+         "UNION ALL "
+        "SELECT File.FileId, File.JobId, PathId, FilenameId, "
+               "File.FileIndex, LStat, MD5 "
+          "FROM BaseFiles JOIN File USING (FileId) "
+         "WHERE BaseFiles.JobId IN (%s) "
+        ") AS T JOIN Job USING (JobId) "
+   "ORDER BY FilenameId, PathId, StartTime DESC ",
+
+  /* SQLite */              /* See Mysql section for doc */
+"SELECT FileId, Job.JobId AS JobId, FileIndex, File.PathId AS PathId, "
+       "File.FilenameId AS FilenameId, LStat, MD5 "
+"FROM Job, File, ( "
+    "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId "
+      "FROM ( "
+        "SELECT JobTDate, PathId, FilenameId "
+          "FROM File JOIN Job USING (JobId) "
+         "WHERE File.JobId IN (%s) "
+          "UNION ALL "
+        "SELECT JobTDate, PathId, FilenameId "
+          "FROM BaseFiles "
+               "JOIN File USING (FileId) "
+               "JOIN Job  ON    (BaseJobId = Job.JobId) "
+         "WHERE BaseFiles.JobId IN (%s) "
+       ") AS tmp GROUP BY PathId, FilenameId "
+    ") AS T1 "
+"WHERE (Job.JobId IN ( "
+       "SELECT DISTINCT BaseJobId FROM BaseFiles WHERE JobId IN (%s)) "
+       "OR Job.JobId IN (%s)) "
+  "AND T1.JobTDate = Job.JobTDate "
+  "AND Job.JobId = File.JobId "
+  "AND T1.PathId = File.PathId "
+  "AND T1.FilenameId = File.FilenameId",
+
+ /* SQLite3 */              /* See Mysql section for doc */
+"SELECT FileId, Job.JobId AS JobId, FileIndex, File.PathId AS PathId, "
+       "File.FilenameId AS FilenameId, LStat, MD5 "
+"FROM Job, File, ( "
+    "SELECT MAX(JobTDate) AS JobTDate, PathId, FilenameId "
+      "FROM ( "
+        "SELECT JobTDate, PathId, FilenameId "
+          "FROM File JOIN Job USING (JobId) "
+         "WHERE File.JobId IN (%s) "
+          "UNION ALL "
+        "SELECT JobTDate, PathId, FilenameId "
+          "FROM BaseFiles "
+               "JOIN File USING (FileId) "
+               "JOIN Job  ON    (BaseJobId = Job.JobId) "
+         "WHERE BaseFiles.JobId IN (%s) "
+       ") AS tmp GROUP BY PathId, FilenameId "
+    ") AS T1 "
+"WHERE (Job.JobId IN ( "
+         "SELECT DISTINCT BaseJobId FROM BaseFiles WHERE JobId IN (%s)) "
+        "OR Job.JobId IN (%s)) "
+  "AND T1.JobTDate = Job.JobTDate "
+  "AND Job.JobId = File.JobId "
+  "AND T1.PathId = File.PathId "
+  "AND T1.FilenameId = File.FilenameId"
+};
+
+/* Get the list of the last recent version with a given BaseJob jobid list */
+const char *select_recent_version[4] = {
+   /* MySQL */
+   "SELECT j1.JobId AS JobId, f1.FileId AS FileId, f1.FileIndex AS FileIndex, "
+          "f1.PathId AS PathId, f1.FilenameId AS FilenameId, "
+          "f1.LStat AS LStat, f1.MD5 AS MD5 "
+     "FROM ( "     /* Choose the last version for each Path/Filename */
+       "SELECT max(JobTDate) AS JobTDate, PathId, FilenameId "
+         "FROM File JOIN Job USING (JobId) "
+        "WHERE File.JobId IN (%s) "
+       "GROUP BY PathId, FilenameId "
+     ") AS t1, Job AS j1, File AS f1 "
+    "WHERE t1.JobTDate = j1.JobTDate "
+      "AND j1.JobId IN (%s) "
+      "AND t1.FilenameId = f1.FilenameId "
+      "AND t1.PathId = f1.PathId "
+      "AND j1.JobId = f1.JobId",
+
+   /* Postgresql */
+   "SELECT DISTINCT ON (FilenameId, PathId) StartTime, JobId, FileId, "
+          "FileIndex, PathId, FilenameId, LStat, MD5 "
+     "FROM File JOIN Job USING (JobId) "
+    "WHERE JobId IN (%s) "
+    "ORDER BY FilenameId, PathId, StartTime DESC ",
+
+   /* SQLite */
+   "SELECT j1.JobId AS JobId, f1.FileId AS FileId, f1.FileIndex AS FileIndex, "
+          "f1.PathId AS PathId, f1.FilenameId AS FilenameId, "
+          "f1.LStat AS LStat, f1.MD5 AS MD5 "
+     "FROM ( "
+       "SELECT max(JobTDate) AS JobTDate, PathId, FilenameId "
+         "FROM File JOIN Job USING (JobId) "
+        "WHERE File.JobId IN (%s) "
+       "GROUP BY PathId, FilenameId "
+     ") AS t1, Job AS j1, File AS f1 "
+    "WHERE t1.JobTDate = j1.JobTDate "
+      "AND j1.JobId IN (%s) "
+      "AND t1.FilenameId = f1.FilenameId "
+      "AND t1.PathId = f1.PathId "
+      "AND j1.JobId = f1.JobId",
+
+   /* SQLite3 */
+   "SELECT j1.JobId AS JobId, f1.FileId AS FileId, f1.FileIndex AS FileIndex, "
+          "f1.PathId AS PathId, f1.FilenameId AS FilenameId, "
+          "f1.LStat AS LStat, f1.MD5 AS MD5 "
+     "FROM ( "
+       "SELECT max(JobTDate) AS JobTDate, PathId, FilenameId "
+         "FROM File JOIN Job USING (JobId) "
+        "WHERE File.JobId IN (%s) "
+       "GROUP BY PathId, FilenameId "
+     ") AS t1, Job AS j1, File AS f1 "
+    "WHERE t1.JobTDate = j1.JobTDate "
+      "AND j1.JobId IN (%s) "
+      "AND t1.FilenameId = f1.FilenameId "
+      "AND t1.PathId = f1.PathId "
+      "AND j1.JobId = f1.JobId"
+};
+
 /* ====== ua_prune.c */
 
 /* List of SQL commands to create temp table and indicies  */
@@ -481,7 +652,7 @@ const char *uar_file[4] = {
    "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
    "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' "
    "AND Client.ClientId=Job.ClientId "
-   "AND Job.JobId=File.JobId "
+   "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
    "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId "
    "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20",
    /* Postgresql */
@@ -490,7 +661,7 @@ const char *uar_file[4] = {
    "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
    "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' "
    "AND Client.ClientId=Job.ClientId "
-   "AND Job.JobId=File.JobId "
+   "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
    "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId "
    "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20",
    /* SQLite */
@@ -499,7 +670,7 @@ const char *uar_file[4] = {
    "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
    "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' "
    "AND Client.ClientId=Job.ClientId "
-   "AND Job.JobId=File.JobId "
+   "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
    "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId "
    "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20",
    /* SQLite3 */
@@ -508,7 +679,7 @@ const char *uar_file[4] = {
    "StartTime,Type as JobType,JobStatus,JobFiles,JobBytes "
    "FROM Client,Job,File,Filename,Path WHERE Client.Name='%s' "
    "AND Client.ClientId=Job.ClientId "
-   "AND Job.JobId=File.JobId "
+   "AND Job.JobId=File.JobId AND File.FileIndex > 0 "
    "AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId "
    "AND Filename.Name='%s' ORDER BY StartTime DESC LIMIT 20"};
 
@@ -631,3 +802,26 @@ const char *uar_jobid_fileindex_from_dir[4] = {
    "AND Path.PathId=File.Pathid "
    "AND Filename.FilenameId=File.FilenameId "
    "GROUP BY File.FileIndex "};
+
+const char *sql_get_max_connections[4] = {
+   /* Mysql */
+   "SHOW VARIABLES LIKE 'max_connections'",
+   /* Postgresql */
+   "SHOW max_connections",
+   /* SQLite */
+   "SELECT 0",
+   /* SQLite3 */
+   "SELECT 0"
+};
+
+/* Row number of the max_connections setting */
+const uint32_t sql_get_max_connections_index[4] = {
+    /* Mysql */
+   1,
+   /* Postgresql */
+   0,
+   /* SQLite */
+   0,
+   /* SQLite3 */
+   0
+};