public Connection getConnection() {
   try {
     if (sqlite) {
       // To avoid concurrency problem with SQLite, we will just use one connection. Cf :
       // constructor above for SQLite
       synchronized (SQLiteConn) {
         SQLiteConn =
             DriverManager.getConnection(
                 "jdbc:sqlite:"
                     + BAT.getInstance().getDataFolder().getAbsolutePath()
                     + File.separator
                     + "bat_database.db");
         return SQLiteConn;
       }
     }
     return ds.getConnection();
   } catch (final SQLException e) {
     BAT.getInstance()
         .getLogger()
         .severe(
             "BAT can't etablish connection with the database. Please report this and include the following lines :");
     if (e.getCause() instanceof CommunicationsException) {
       BAT.getInstance().getLogger().severe(e.getCause().getMessage());
     }
     if (BAT.getInstance().getConfiguration().isDebugMode()) {
       e.printStackTrace();
     }
     return null;
   }
 }
 /** Constructor used for SQLite */
 public DataSourceHandler() {
   /*
    * As SQLite supports concurrency pretty badly (locked database which causes problem), we're gonna get a connection from the DriverManager each time
    * we need to acces to the database. In the contrary of BoneCP with mysql in which we saved connection to optimize perfomance, it's not necessary with SQLite.
    * FYI, here are the results of test : execute 1000 insert request using SQLite, with or without using the same connection :
    * - Using the same connection it took : 22820 ms
    * - Getting another connection each time (DriverManager.getConnection), it took : 24186 ms
    * The difference is only 1366 ms for 1000 request, that means on average additional 1.3 ms, which is insignificant as we are executing almost every query async.
    * To the people who read that, all these calculations can seem a little overrated, but I really like to improve perfomance at the most and I'm pretty curious :p
    */
   sqlite = true;
   try {
     SQLiteConn =
         DriverManager.getConnection(
             "jdbc:sqlite:"
                 + BAT.getInstance().getDataFolder().getAbsolutePath()
                 + File.separator
                 + "bat_database.db");
     SQLiteConn.close();
   } catch (SQLException e) {
     BAT.getInstance()
         .getLogger()
         .severe(
             "BAT encounters a problem during the initialization of the sqlite database connection.");
     if (e.getMessage() != null) {
       BAT.getInstance().getLogger().severe("Error message : " + e.getMessage());
     }
   }
 }
		@Override
		public void onCommand(CommandSender sender, String[] args, boolean confirmedCmd)
				throws IllegalArgumentException {
			final ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]);
			final String reason = Utils.getFinalArg(args, 1);
			if(target == null){
				if(!confirmedCmd && Core.getPlayerIP(args[0]).equals("0.0.0.0")){
					mustConfirmCommand(sender, getName() + " " + Joiner.on(' ').join(args),
							_("operationUnknownPlayer", new String[] {args[0]}));
					return;
				}
			}
			
			if(sender instanceof ProxiedPlayer){
				checkArgument(PermissionManager.canExecuteAction(Action.WARN , sender, ((ProxiedPlayer)sender).getServer().getInfo().getName()),
						_("noPerm"));
			}
	          checkArgument(comment.hasLastcommentCooledDown(args[0]), _("cooldownUnfinished"));
			comment.insertComment(args[0], reason, Type.WARNING, sender.getName());
			if(target != null){
			  target.sendMessage(__("wasWarnedNotif", new String[] {reason}));
			}
			  
			BAT.broadcast(_("warnBroadcast", new String[]{args[0], sender.getName(), reason}), Action.WARN_BROADCAST.getPermission());
			return;
		}
 // Useful methods
 public static String handleException(final SQLException e) {
   BAT.getInstance()
       .getLogger()
       .severe(
           "BAT encounters a problem with the database. Please report this and include the following lines :");
   e.printStackTrace();
   return "An error related to the database occured. Please check the log.";
 }
  /**
   * Constructor used for MySQL
   *
   * @param host
   * @param port
   * @param database
   * @param username
   * @param password
   * @throws SQLException
   */
  public DataSourceHandler(
      final String host,
      final String port,
      final String database,
      final String username,
      final String password)
      throws SQLException {
    // Check database's informations and init connection
    this.host = Preconditions.checkNotNull(host);
    this.port = Preconditions.checkNotNull(port);
    this.database = Preconditions.checkNotNull(database);
    this.username = Preconditions.checkNotNull(username);
    this.password = Preconditions.checkNotNull(password);

    BAT.getInstance().getLogger().config("Initialization of HikariCP in progress ...");
    BasicConfigurator.configure(new NullAppender());
    ds = new HikariDataSource();
    ds.setJdbcUrl(
        "jdbc:mysql://"
            + this.host
            + ":"
            + this.port
            + "/"
            + this.database
            + "?useLegacyDatetimeCode=false&serverTimezone="
            + TimeZone.getDefault().getID());
    ds.setUsername(this.username);
    ds.setPassword(this.password);
    ds.addDataSourceProperty("cachePrepStmts", "true");
    ds.setMaximumPoolSize(8);
    try {
      final Connection conn = ds.getConnection();
      int intOffset =
          Calendar.getInstance().getTimeZone().getOffset(Calendar.getInstance().getTimeInMillis())
              / 1000;
      String offset =
          String.format("%02d:%02d", Math.abs(intOffset / 3600), Math.abs((intOffset / 60) % 60));
      offset = (intOffset >= 0 ? "+" : "-") + offset;
      conn.createStatement().executeQuery("SET time_zone='" + offset + "';");
      conn.close();
      BAT.getInstance().getLogger().config("BoneCP is loaded !");
    } catch (final SQLException e) {
      BAT.getInstance()
          .getLogger()
          .severe(
              "BAT encounters a problem during the initialization of the database connection."
                  + " Please check your logins and database configuration.");
      if (e.getCause() instanceof CommunicationsException) {
        BAT.getInstance().getLogger().severe(e.getCause().getMessage());
      }
      if (BAT.getInstance().getConfiguration().isDebugMode()) {
        BAT.getInstance().getLogger().log(Level.SEVERE, e.getMessage(), e);
      }
      throw e;
    }
    sqlite = false;
  }
 /** Starts a new async task and pump the inputstream */
 public void pump() {
   ProxyServer.getInstance()
       .getScheduler()
       .runAsync(
           BAT.getInstance(),
           new Runnable() {
             @Override
             public void run() {
               try {
                 pumpedLines = CharStreams.readLines(reader);
                 reader.close();
               } catch (final IOException e) {
                 BAT.getInstance()
                     .getLogger()
                     .severe(
                         "BAT encounter an error while reading the stream of subprocess. Please report this :");
                 e.printStackTrace();
               }
             }
           });
 }
		@Override
		public void onCommand(final CommandSender sender, final String[] args, final boolean confirmedCmd) throws IllegalArgumentException {
			if (args[0].equals("help")) {
				try {
					FormatUtils.showFormattedHelp(BAT.getInstance().getModules().getModule("comment").getCommands(),
							sender, "COMMENT");
				} catch (final InvalidModuleException e) {
					e.printStackTrace();
				}
				return;
			}
			if(args.length < 2){
				throw new IllegalArgumentException();
			}
			if(!confirmedCmd && Core.getPlayerIP(args[0]).equals("0.0.0.0")){
				mustConfirmCommand(sender, "bat " + getName() + " " + Joiner.on(' ').join(args),
						_("operationUnknownPlayer", new String[] {args[0]}));
				return;
			}
			
			checkArgument(comment.hasLastcommentCooledDown(args[0]), _("cooldownUnfinished"));
			comment.insertComment(args[0], Utils.getFinalArg(args, 1), Type.NOTE, sender.getName());
			sender.sendMessage(__("commentAdded"));
		}
		@Override
		public void onCommand(final CommandSender sender, final String[] args, final boolean confirmedCmd) throws IllegalArgumentException {
			sender.sendMessage(BAT.__(comment.clearComments(args[0], ((args.length == 2) ? Integer.parseInt(args[1]) : -1) )));
		}
 /**
  * Generate a backup of the BAT data in mysql database.
  *
  * @param path
  * @param onComplete
  * @throws RuntimeException if MySQL is not used or if the creation of the backup file failed
  */
 public void generateMysqlBackup(final Callback<String> onComplete) throws RuntimeException {
   ProxyServer.getInstance()
       .getScheduler()
       .runAsync(
           BAT.getInstance(),
           new Runnable() {
             @Override
             public void run() {
               try {
                 Process testProcess = Runtime.getRuntime().exec("mysqldump --help");
                 new StreamPumper(testProcess.getErrorStream()).pump();
                 new StreamPumper(testProcess.getInputStream()).pump();
                 int returnValue = testProcess.waitFor();
                 if (returnValue != 0) {
                   throw new Exception();
                 }
               } catch (final Exception e) {
                 onComplete.done(
                     "The backup can't be achieved because mysqldump is nowhere to be found.",
                     null);
                 return;
               }
               final File backupDirectory =
                   new File(
                       BAT.getInstance().getDataFolder().getAbsolutePath()
                           + File.separator
                           + "databaseBackups");
               backupDirectory.mkdir();
               File backupFile =
                   new File(
                       backupDirectory.getAbsolutePath()
                           + File.separator
                           + "backup"
                           + new SimpleDateFormat("dd-MMM-yyyy_HH'h'mm")
                               .format(Calendar.getInstance().getTime())
                           + ".sql");
               for (int i = 0; ; i++) {
                 if (!backupFile.exists()) {
                   break;
                 } else {
                   if (i == 0) {
                     backupFile =
                         new File(backupFile.getAbsolutePath().replace(".sql", "#" + i + ".sql"));
                   } else {
                     backupFile =
                         new File(
                             backupFile
                                 .getAbsolutePath()
                                 .replaceAll("#\\d+\\.sql$", "#" + i + ".sql"));
                   }
                 }
               }
               String backupCmd =
                   "mysqldump -u {user} -p --add-drop-database -r {path} {database} {tables}";
               final String tables =
                   Joiner.on(' ')
                       .join(
                           Arrays.asList(
                               SQLQueries.Ban.table,
                               SQLQueries.Mute.table,
                               SQLQueries.Watch.table,
                               SQLQueries.Kick.table,
                               SQLQueries.Comments.table,
                               SQLQueries.Core.table));
               String backupPath = backupFile.getAbsolutePath();
               if (backupPath.contains(" ")) {
                 backupPath = "\"" + backupPath + "\"";
               }
               backupCmd =
                   backupCmd
                       .replace("{user}", username)
                       .replace("{database}", database)
                       .replace("{path}", backupPath)
                       .replace("{tables}", tables);
               if (password.equals("")) {
                 backupCmd = backupCmd.replace("-p", "");
               } else {
                 backupCmd = backupCmd.replace("-p", "--password="******"\\") ? "\\\\" : File.separator));
                   final String fileName = splittedPath[splittedPath.length - 1];
                   onComplete.done(
                       format("The backup file (%s) has been sucessfully generated.", fileName),
                       null);
                 } else {
                   onComplete.done(
                       "An error happens during the creation of the mysql backup. Please check the logs",
                       null);
                   BAT.getInstance()
                       .getLogger()
                       .severe(
                           "An error happens during the creation of the mysql backup. Please report :");
                   for (final String message : errorPumper.getLines()) {
                     BAT.getInstance().getLogger().severe(message);
                   }
                 }
               } catch (final Exception e) {
                 onComplete.done("An error happens during the creation of the mysql backup.", e);
                 e.printStackTrace();
               }
             }
           });
 }