docs: private void dbUpgrade()
      {
          DbConn cnx = this.getConn();
          Map<String, Object> rs = null;
          int db_schema_version = 0;
          try
          {
              rs = cnx.runSelectSingleRow("version_select_latest");
              db_schema_version = (Integer) rs.get("VERSION_D1");
          }
          catch (Exception e)
          {
              // Database is to be created, so version 0 is OK.
          }
          cnx.rollback();
  
          if (SCHEMA_VERSION > db_schema_version)
          {
              jqmlogger.warn("Database is being upgraded from version {} to version {}", db_schema_version, SCHEMA_VERSION);
  
              // Upgrade scripts are named from_to.sql with 5 padding (e.g. 00000_00003.sql)
              // We try to find the fastest path (e.g. a direct 00000_00005.sql for creating a version 5 schema from nothing)
              // This is a simplistic and non-optimal algorithm as we try only a single path (no going back)
  
              int loop_from = db_schema_version;
              int to = db_schema_version;
              List<String> toApply = new ArrayList<>();
              toApply.addAll(adapter.preSchemaCreationScripts());
  
              while (to != SCHEMA_VERSION)
              {
                  boolean progressed = false;
                  for (int loop_to = SCHEMA_VERSION; loop_to > db_schema_version; loop_to--)
                  {
                      String migrationFileName = String.format("/sql/%05d_%05d.sql", loop_from, loop_to);
                      jqmlogger.debug("Trying migration script {}", migrationFileName);
                      if (Db.class.getResource(migrationFileName) != null)
                      {
                          toApply.add(migrationFileName);
                          to = loop_to;
                          loop_from = loop_to;
                          progressed = true;
                          break;
                      }
                  }
  
                  if (!progressed)
                  {
                      break;
                  }
              }
              if (to != SCHEMA_VERSION)
              {
                  throw new DatabaseException(
                          "There is no migration path from version " + db_schema_version + " to version " + SCHEMA_VERSION);
              }
  
              for (String s : toApply)
              {
                  jqmlogger.info("Running migration script {}", s);
                  ScriptRunner.run(cnx, s);
              }
              cnx.commit(); // Yes, really. For advanced DB!
  
              cnx.close(); // HSQLDB does not refresh its schema without this.
              cnx = getConn();
  
              cnx.runUpdate("version_insert", SCHEMA_VERSION, SCHEMA_COMPATIBLE_VERSION);
              cnx.commit();
              jqmlogger.info("Database is now up to date");
          }
          else
          {
              jqmlogger.info("Database is already up to date");
          }
          cnx.close();
      }