package com.xqbase.metric;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class Migrate {
	private static final int BATCH = 100;
	private static final String[] DRIVERS = {
		"org.h2.Driver",
		"org.apache.derby.jdbc.EmbeddedDriver",
		"org.sqlite.JDBC",
		"org.postgresql.Driver",
		"com.mysql.jdbc.Driver",
	};

	private static SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");

	private static void log(String msg) {
		System.out.println(format.format(new Date()) + " " + msg);
	}

	public static void main(String[] args) throws SQLException {
		if (args == null || args.length < 2) {
			System.out.println("Migrate Usage: java -jar metric-migrate.jar <src.jdbc.url> <dst.jdbc.url>");
			return;
		}
		for (String driver : DRIVERS) {
			try {
				Class.forName(driver);
			} catch (ClassNotFoundException e) {
				System.err.println("" + e);
			}
		}
		try (
			Connection src = DriverManager.getConnection(args[0]);
			Statement stSrc = src.createStatement();
			Connection dst = DriverManager.getConnection(args[1]);
			Statement stDst = dst.createStatement();
		) {
			List<String> tables = new ArrayList<>();
			try (ResultSet rs = src.getMetaData().
					getTables(src.getCatalog(), src.getSchema(), null, null)) {
				while (rs.next()) {
					tables.add(rs.getString("TABLE_NAME").toLowerCase());
				}
			}
			for (String table : tables) {
				log("Begin migrating table " + table + " ...");
				stDst.execute("TRUNCATE TABLE " + table);
				try (ResultSet rs = stSrc.executeQuery("SELECT * FROM " + table)) {
					int columns = rs.getMetaData().getColumnCount();
					try (PreparedStatement ps = dst.prepareStatement("INSERT INTO "  + table +
							" VALUES (" + String.join(", ", Collections.nCopies(columns, "?")) + ")")) {
						int rows = 0;
						int batch = 0;
						while (rs.next()) {
							for (int i = 1; i <= columns; i ++) {
								ps.setObject(i, rs.getObject(i));
							}
							ps.addBatch();
							batch ++;
							if (batch == BATCH) {
								ps.executeBatch();
								rows += batch;
								log(rows + " rows inserted into table " + table);
								batch = 0;
							}
						}
						if (batch > 0) {
							ps.executeBatch();
							rows += batch;
							log(rows + " rows inserted into table " + table);
						}
					}
				}
				log("End migrating table " + table);
			}
		}
	}
}
@@ -1401,16 +1401,43 @@
 %0A%09%09) %7B%0D%0A
+%09%09%09src.setReadOnly(true);%0D%0A
 %09%09%09List%3C
@@ -1763,24 +1763,131 @@
 + %22 ...%22);%0D%0A
+%09%09%09%09if (args%5B1%5D.startsWith(%22jdbc:sqlite:%22)) %7B%0D%0A%09%09%09%09%09stDst.execute(%22DELETE FROM %22 + table);%0D%0A%09%09%09%09%7D else %7B%0D%0A%09
 %09%09%09%09stDst.ex
@@ -1917,24 +1917,31 @@
  + table);%0D%0A
+%09%09%09%09%7D%0D%0A
 %09%09%09%09try (Res

use `DELETE FROM ...` for SQLite