Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Serealise / dump and restore a database

  • Loading branch information...
commit 9fc9b34a2dcf6dda626d02a360250f2752181bff 1 parent 1446ffa
@scravy authored
View
155 src/main/java/de/fu/mi/mssql/Cereal.java
@@ -0,0 +1,155 @@
+package de.fu.mi.mssql;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.rowset.serial.SerialArray;
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialException;
+
+class Cereal {
+
+ static final class Null implements Serializable {
+ static final long serialVersionUID = 1L;
+ static final Null NULL = new Null();
+ }
+
+ static final class Table implements Serializable {
+ static final long serialVersionUID = 1L;
+
+ final int numColumns;
+ final String tableName;
+ final int[] types;
+ final String[] names;
+ final boolean[] notNulls;
+
+ public Table(String name, ResultSet r) throws SQLException {
+ ResultSetMetaData m = r.getMetaData();
+
+ numColumns = m.getColumnCount();
+ tableName = name;
+ types = new int[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ types[i] = m.getColumnType(i);
+ }
+ names = new String[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ names[i] = m.getColumnName(i);
+ }
+ notNulls = new boolean[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ notNulls[i] = m.isNullable(i) == ResultSetMetaData.columnNoNulls;
+ }
+ }
+
+ public Table(String name) {
+ numColumns = 0;
+ tableName = name;
+ types = null;
+ names = null;
+ notNulls = null;
+ }
+ }
+
+ static Serializable makeSerializable(final Object o)
+ throws SerialException, SQLException {
+ if (o == null) {
+ return Null.NULL;
+ } else if (o instanceof Serializable) {
+ return (Serializable) o;
+ } else if (o instanceof Blob) {
+ return new SerialBlob((Blob) o);
+ } else if (o instanceof Clob) {
+ return new SerialClob((Clob) o);
+ } else if (o instanceof Array) {
+ return new SerialArray((Array) o);
+ }
+ return null;
+ }
+
+ public static void unserialize(InputStream in, Connection c, String q)
+ throws IOException, ClassNotFoundException, SQLException {
+
+ try (ObjectInputStream oi = new ObjectInputStream(in)) {
+ Table info;
+ while ((info = (Table) oi.readObject()) != null) {
+ if (info.numColumns > 0) {
+ String tableName = info.tableName;
+ StringBuilder b = new StringBuilder();
+ b.append(info.names[0]);
+ for (int i = 1; i < info.numColumns; i++) {
+ b.append(", ");
+ b.append(info.names[i]);
+ }
+ String columns = b.toString();
+ b.setLength(0);
+ b.append("?");
+ for (int i = 1; i < info.numColumns; i++) {
+ b.append(", ?");
+ }
+ PreparedStatement s = c.prepareStatement(
+ String.format(q, tableName, columns, b.toString()));
+
+ Object[] row;
+ while ((row = (Object[]) oi.readObject()) != null) {
+ for (int i = 0; i < row.length; i++) {
+ if (row[i] == null) {
+ s.setNull(i, info.types[i]);
+ } else {
+ s.setObject(i, row[i]);
+ }
+ }
+ s.executeUpdate();
+ }
+ }
+ }
+ }
+ }
+
+ public static void serialize(OutputStream out, Connection c, String q,
+ String... ts) throws SQLException, IOException {
+
+ try (ObjectOutputStream oo = new ObjectOutputStream(out)) {
+ for (String table : ts) {
+ try (final Statement s = c.createStatement()) {
+ ResultSet r = s.executeQuery(String.format(q, table));
+ serialize(r, table, oo);
+ }
+ }
+ oo.writeObject(null);
+ }
+ }
+
+ static void serialize(ResultSet r, String t, ObjectOutputStream oo)
+ throws SQLException, IOException {
+ if (r != null && r.next()) {
+ Table info = new Table(t, r);
+ oo.writeObject(t);
+ do {
+ Object[] row = new Object[info.numColumns];
+ for (int i = 0; i < info.numColumns; i++) {
+ Object o = r.getObject(i);
+ row[i] = r.wasNull() ? null : makeSerializable(o);
+ }
+ oo.writeObject(row);
+ } while (r.next());
+ } else {
+ oo.writeObject(new Table(t));
+ }
+ oo.writeObject(null);
+ }
+}
View
168 src/main/java/de/fu/mi/mssql/SQL.java
@@ -0,0 +1,168 @@
+package de.fu.mi.mssql;
+
+import java.sql.Types;
+
+import de.fu.mi.mssql.Cereal.Table;
+
+public enum SQL {
+
+ MYSQL(
+ types(
+ type(Types.BIGINT, "BIGINT"),
+ type(Types.BINARY, "BINARY"),
+ type(Types.BIT, "BIT"),
+ type(Types.BLOB, "BLOB"),
+ type(Types.BOOLEAN, "BOOLEAN"),
+ type(Types.CHAR, "CHAR"),
+ type(Types.CLOB, "CLOB"),
+ type(Types.DATE, "DATE"),
+ type(Types.DECIMAL, "DECIMAL"),
+ type(Types.DOUBLE, "DOUBLE"),
+ type(Types.FLOAT, "FLOAT"),
+ type(Types.INTEGER, "INTEGER"),
+ type(Types.LONGNVARCHAR, "LONGNVARCHAR"),
+ type(Types.LONGVARBINARY, "LONGVARBINARY"),
+ type(Types.LONGVARCHAR, "LONGVARCHAR"),
+ type(Types.NCHAR, "NCHAR"),
+ type(Types.NCLOB, "NCLOB"),
+ type(Types.NUMERIC, "NUMERIC"),
+ type(Types.NVARCHAR, "NVARCHAR"),
+ type(Types.REAL, "REAL"),
+ type(Types.SMALLINT, "SMALLINT"),
+ type(Types.SQLXML, "XML"),
+ type(Types.TIME, "TIME"),
+ type(Types.TIMESTAMP, "TIMESTAMP"),
+ type(Types.TINYINT, "TINYINT"),
+ type(Types.VARBINARY, "VARBINARY"),
+ type(Types.VARCHAR, "VARCHAR")
+ ),
+ "SELECT * FROM %s",
+ "INSERT INTO %s (%s) VALUES (%s)",
+ "CREATE TABLE %s (%s)"
+ ),
+
+ MSSQL(
+ types(
+ type(Types.BIGINT, "BIGINT"),
+ type(Types.BINARY, "BINARY"),
+ type(Types.BIT, "BIT"),
+ type(Types.BLOB, "BLOB"),
+ type(Types.BOOLEAN, "BOOLEAN"),
+ type(Types.CHAR, "CHAR"),
+ type(Types.CLOB, "CLOB"),
+ type(Types.DATE, "DATE"),
+ type(Types.DECIMAL, "DECIMAL"),
+ type(Types.DOUBLE, "DOUBLE"),
+ type(Types.FLOAT, "FLOAT"),
+ type(Types.INTEGER, "INTEGER"),
+ type(Types.LONGNVARCHAR, "LONGNVARCHAR"),
+ type(Types.LONGVARBINARY, "LONGVARBINARY"),
+ type(Types.LONGVARCHAR, "LONGVARCHAR"),
+ type(Types.NCHAR, "NCHAR"),
+ type(Types.NCLOB, "NCLOB"),
+ type(Types.NUMERIC, "NUMERIC"),
+ type(Types.NVARCHAR, "NVARCHAR"),
+ type(Types.REAL, "REAL"),
+ type(Types.SMALLINT, "SMALLINT"),
+ type(Types.SQLXML, "XML"),
+ type(Types.TIME, "TIME"),
+ type(Types.TIMESTAMP, "TIMESTAMP"),
+ type(Types.TINYINT, "TINYINT"),
+ type(Types.VARBINARY, "VARBINARY"),
+ type(Types.VARCHAR, "VARCHAR")
+ ),
+ "SELECT * FROM %s",
+ "INSERT INTO %s (%s) VALUES (%s)",
+ "CREATE TABLE %s (%s)"
+ ),
+
+ PGSQL(
+ types(
+ type(Types.BIGINT, "BIGINT"),
+ type(Types.BINARY, "BINARY"),
+ type(Types.BIT, "BIT"),
+ type(Types.BLOB, "BLOB"),
+ type(Types.BOOLEAN, "BOOLEAN"),
+ type(Types.CHAR, "CHAR"),
+ type(Types.CLOB, "CLOB"),
+ type(Types.DATE, "DATE"),
+ type(Types.DECIMAL, "DECIMAL"),
+ type(Types.DOUBLE, "DOUBLE"),
+ type(Types.FLOAT, "FLOAT"),
+ type(Types.INTEGER, "INTEGER"),
+ type(Types.LONGNVARCHAR, "LONGNVARCHAR"),
+ type(Types.LONGVARBINARY, "LONGVARBINARY"),
+ type(Types.LONGVARCHAR, "LONGVARCHAR"),
+ type(Types.NCHAR, "NCHAR"),
+ type(Types.NCLOB, "NCLOB"),
+ type(Types.NUMERIC, "NUMERIC"),
+ type(Types.NVARCHAR, "NVARCHAR"),
+ type(Types.REAL, "REAL"),
+ type(Types.SMALLINT, "SMALLINT"),
+ type(Types.SQLXML, "XML"),
+ type(Types.TIME, "TIME"),
+ type(Types.TIMESTAMP, "TIMESTAMP"),
+ type(Types.TINYINT, "TINYINT"),
+ type(Types.VARBINARY, "VARBINARY"),
+ type(Types.VARCHAR, "VARCHAR")
+ ),
+ "SELECT * FROM %s",
+ "INSERT INTO %s (%s) VALUES (%s)",
+ "CREATE TABLE %s (%s)"
+ );
+
+ Type[] types;
+ String select;
+ String insert;
+ String create;
+
+ SQL(Type[] types, String select, String insert, String create) {
+ int max = 0;
+ for (int i = 0; i < types.length; i++) {
+ max = Math.max(types[i].type, max);
+ }
+ this.types = new Type[max];
+ for (int i = 0; i < types.length; i++) {
+ this.types[types[i].type] = types[i];
+ }
+ this.select = select;
+ this.insert = insert;
+ this.create = create;
+ }
+
+ static class Type {
+ int type;
+ String name;
+
+ Type(int type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+ }
+
+ static Type type(int type, String name) {
+ return new Type(type, name);
+ }
+
+ static Type[] types(Type... ts) {
+ return ts;
+ }
+
+ String createTableDDL(Table table) {
+ StringBuilder b = new StringBuilder("\n\t");
+
+ for (int i = 0; i < table.numColumns; i++) {
+ if (i > 0) {
+ b.append(",\n\t");
+ }
+ b.append(table.names[i]);
+ b.append(" ");
+ b.append(types[table.types[i]]);
+ if (table.notNulls[i]) {
+ b.append(" NOT NULL");
+ }
+ }
+
+ return String.format(create, table.tableName, b.toString());
+ }
+}
View
63 src/main/java/de/fu/mi/mssql/Test.java
@@ -0,0 +1,63 @@
+package de.fu.mi.mssql;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+public class Test {
+
+ public static void main(String... args) throws Exception {
+
+ File file = new File("archive.zip");
+ GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(file));
+
+ ZipOutputStream zip = new ZipOutputStream(out);
+ zip.setMethod(ZipOutputStream.DEFLATED);
+ zip.setLevel(9);
+
+ ZipEntry _ = new ZipEntry("_");
+ zip.putNextEntry(_);
+ ObjectOutputStream oo = new ObjectOutputStream(zip);
+ zip.closeEntry();
+
+ for (int i = 0; i < 10000; i++) {
+ ZipEntry e = new ZipEntry("e" + i);
+ zip.putNextEntry(e);
+
+ //oo.writeObject(Math.random() < 0.5
+ // ? new Integer(1337) : new Double(42.5));
+ oo.writeLong(Math.random() < 0.5 ? -1337 : 1655389);
+ //oo.writeBoolean(Math.random() < 0.5);
+ oo.writeObject(null);
+ oo.flush();
+ zip.closeEntry();
+ }
+ zip.finish();
+ oo.close();
+ out.close();
+
+ GZIPInputStream in = new GZIPInputStream(new FileInputStream(file));
+
+ ZipInputStream zipIn = new ZipInputStream(in);
+
+ zipIn.getNextEntry();
+ ObjectInputStream oi = new ObjectInputStream(zipIn);
+
+ ZipEntry e;
+ while ((e = zipIn.getNextEntry()) != null) {
+
+ System.out.println(e.getName());
+ System.out.println(oi.readLong());
+ System.out.println(oi.readObject());
+ //System.out.println(oi.readBoolean());
+ }
+ oi.close();
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.