mirror of
				https://github.com/fabianonline/telegram_backup.git
				synced 2025-10-31 07:39:21 +00:00 
			
		
		
		
	Moved Dabase changes into their own class.
This commit is contained in:
		| @@ -47,8 +47,8 @@ import de.fabianonline.telegram_backup.mediafilemanager.FileManagerFactory; | |||||||
| public class Database { | public class Database { | ||||||
| 	private Connection conn; | 	private Connection conn; | ||||||
| 	private Statement stmt; | 	private Statement stmt; | ||||||
| 	private UserManager user_manager; | 	public UserManager user_manager; | ||||||
| 	private TelegramClient client; | 	public TelegramClient client; | ||||||
| 	 | 	 | ||||||
| 	public Database(UserManager user_manager, TelegramClient client) { | 	public Database(UserManager user_manager, TelegramClient client) { | ||||||
| 		this(user_manager, client, true); | 		this(user_manager, client, true); | ||||||
| @@ -81,176 +81,20 @@ public class Database { | |||||||
| 	 | 	 | ||||||
| 	private void init(boolean update_db) { | 	private void init(boolean update_db) { | ||||||
| 		if (!update_db) return; | 		if (!update_db) return; | ||||||
| 		 | 		DatabaseUpdates updates = new DatabaseUpdates(conn, this); | ||||||
| 		try { | 		updates.doUpdates(); | ||||||
| 			int version; |  | ||||||
| 			ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='database_versions'"); |  | ||||||
| 			rs.next(); |  | ||||||
| 			if (rs.getInt(1)==0) { |  | ||||||
| 				version = 0; |  | ||||||
| 			} else { |  | ||||||
| 				rs.close(); |  | ||||||
| 				rs = stmt.executeQuery("SELECT MAX(version) FROM database_versions"); |  | ||||||
| 				rs.next(); |  | ||||||
| 				version = rs.getInt(1); |  | ||||||
| 				rs.close(); |  | ||||||
| 			} |  | ||||||
| 			System.out.println("Database version: " + version); |  | ||||||
| 			 |  | ||||||
| 			if (version==0) { |  | ||||||
| 				System.out.println("  Updating to version 1..."); |  | ||||||
| 				stmt.executeUpdate("CREATE TABLE messages (" |  | ||||||
| 						+ "id INTEGER PRIMARY KEY ASC, " |  | ||||||
| 						+ "dialog_id INTEGER, " |  | ||||||
| 						+ "to_id INTEGER, " |  | ||||||
| 						+ "from_id INTEGER, " |  | ||||||
| 						+ "from_type TEXT, " |  | ||||||
| 						+ "text TEXT, " |  | ||||||
| 						+ "time TEXT, " |  | ||||||
| 						+ "has_media BOOLEAN, " |  | ||||||
| 						+ "sticker TEXT, " |  | ||||||
| 						+ "data BLOB," |  | ||||||
| 						+ "type TEXT)"); |  | ||||||
| 				stmt.executeUpdate("CREATE TABLE dialogs (" |  | ||||||
| 						+ "id INTEGER PRIMARY KEY ASC, " |  | ||||||
| 						+ "name TEXT, " |  | ||||||
| 						+ "type TEXT)"); |  | ||||||
| 				stmt.executeUpdate("CREATE TABLE people (" |  | ||||||
| 						+ "id INTEGER PRIMARY KEY ASC, " |  | ||||||
| 						+ "first_name TEXT, " |  | ||||||
| 						+ "last_name TEXT, " |  | ||||||
| 						+ "username TEXT, " |  | ||||||
| 						+ "type TEXT)"); |  | ||||||
| 				stmt.executeUpdate("CREATE TABLE database_versions (" |  | ||||||
| 						+ "version INTEGER)"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (1)"); |  | ||||||
| 				version = 1; |  | ||||||
| 			} |  | ||||||
| 			if (version==1) { |  | ||||||
| 				System.out.println("  Updating to version 2..."); |  | ||||||
| 				stmt.executeUpdate("ALTER TABLE people RENAME TO 'users'"); |  | ||||||
| 				stmt.executeUpdate("ALTER TABLE users ADD COLUMN phone TEXT"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (2)"); |  | ||||||
| 				version = 2; |  | ||||||
| 			} |  | ||||||
| 			if (version==2) { |  | ||||||
| 				System.out.println("  Updating to version 3..."); |  | ||||||
| 				stmt.executeUpdate("ALTER TABLE dialogs RENAME TO 'chats'"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (3)"); |  | ||||||
| 				version = 3; |  | ||||||
| 			} |  | ||||||
| 			if (version==3) { |  | ||||||
| 				System.out.println("  Updating to version 4..."); |  | ||||||
| 				stmt.executeUpdate("CREATE TABLE messages_new (id INTEGER PRIMARY KEY ASC, dialog_id INTEGER, to_id INTEGER, from_id INTEGER, from_type TEXT, text TEXT, time INTEGER, has_media BOOLEAN, sticker TEXT, data BLOB, type TEXT);"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO messages_new SELECT * FROM messages"); |  | ||||||
| 				stmt.executeUpdate("DROP TABLE messages"); |  | ||||||
| 				stmt.executeUpdate("ALTER TABLE messages_new RENAME TO 'messages'"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (4)"); |  | ||||||
| 				version = 4; |  | ||||||
| 			} |  | ||||||
| 			if (version==4) { |  | ||||||
| 				System.out.println("  Updating to version 5..."); |  | ||||||
| 				stmt.executeUpdate("CREATE TABLE runs (id INTEGER PRIMARY KEY ASC, time INTEGER, start_id INTEGER, end_id INTEGER, count_missing INTEGER)"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (5)"); |  | ||||||
| 				version = 5; |  | ||||||
| 			} |  | ||||||
| 			if (version==5) { |  | ||||||
| 				backupDatabase(5); |  | ||||||
| 				System.out.println("  Updating to version 6..."); |  | ||||||
| 				stmt.executeUpdate( |  | ||||||
| 					"CREATE TABLE messages_new (\n" + |  | ||||||
| 					"    id INTEGER PRIMARY KEY ASC,\n" + |  | ||||||
| 					"    message_type TEXT,\n" + |  | ||||||
| 					"    dialog_id INTEGER,\n" + |  | ||||||
| 					"    chat_id INTEGER,\n" + |  | ||||||
| 					"    sender_id INTEGER,\n" + |  | ||||||
| 					"    fwd_from_id INTEGER,\n" + |  | ||||||
| 					"    text TEXT,\n" + |  | ||||||
| 					"    time INTEGER,\n" + |  | ||||||
| 					"    has_media BOOLEAN,\n" + |  | ||||||
| 					"    media_type TEXT,\n" + |  | ||||||
| 					"    media_file TEXT,\n" + |  | ||||||
| 					"    media_size INTEGER,\n" + |  | ||||||
| 					"    media_json TEXT,\n" + |  | ||||||
| 					"    markup_json TEXT,\n" + |  | ||||||
| 					"    data BLOB)"); |  | ||||||
| 				LinkedHashMap<String, String> mappings = new LinkedHashMap<String, String>(); |  | ||||||
| 				mappings.put("id", "id"); |  | ||||||
| 				mappings.put("message_type", "type"); |  | ||||||
| 				mappings.put("dialog_id", "CASE from_type WHEN 'user' THEN dialog_id ELSE NULL END"); |  | ||||||
| 				mappings.put("chat_id",   "CASE from_type WHEN 'chat' THEN dialog_id ELSE NULL END"); |  | ||||||
| 				mappings.put("sender_id", "from_id"); |  | ||||||
| 				mappings.put("text", "text"); |  | ||||||
| 				mappings.put("time", "time"); |  | ||||||
| 				mappings.put("has_media", "has_media"); |  | ||||||
| 				mappings.put("data", "data"); |  | ||||||
| 				StringBuilder query = new StringBuilder("INSERT INTO messages_new\n("); |  | ||||||
| 				boolean first; |  | ||||||
| 				first = true; |  | ||||||
| 				for(String s : mappings.keySet()) { |  | ||||||
| 					if (!first) query.append(", "); |  | ||||||
| 					query.append(s); |  | ||||||
| 					first = false; |  | ||||||
| 				} |  | ||||||
| 				query.append(")\nSELECT \n"); |  | ||||||
| 				first = true; |  | ||||||
| 				for (String s : mappings.values()) { |  | ||||||
| 					if (!first) query.append(", "); |  | ||||||
| 					query.append(s); |  | ||||||
| 					first = false; |  | ||||||
| 				} |  | ||||||
| 				query.append("\nFROM messages"); |  | ||||||
| 				stmt.executeUpdate(query.toString()); |  | ||||||
| 				 |  | ||||||
| 				System.out.println("    Updating the data (this might take some time)..."); |  | ||||||
| 				rs = stmt.executeQuery("SELECT id, data FROM messages_new"); |  | ||||||
| 				PreparedStatement ps = conn.prepareStatement("UPDATE messages_new SET fwd_from_id=?, media_type=?, media_file=?, media_size=? WHERE id=?"); |  | ||||||
| 				while (rs.next()) { |  | ||||||
| 					ps.setInt(5, rs.getInt(1)); |  | ||||||
| 					TLMessage msg = bytesToTLMessage(rs.getBytes(2)); |  | ||||||
| 					if (msg==null || msg.getFwdFromId()==null || ! (msg.getFwdFromId() instanceof TLPeerUser)) { |  | ||||||
| 						ps.setNull(1, Types.INTEGER); |  | ||||||
| 					} else { |  | ||||||
| 						ps.setInt(1, ((TLPeerUser)msg.getFwdFromId()).getUserId()); |  | ||||||
| 					} |  | ||||||
| 					AbstractMediaFileManager f = FileManagerFactory.getFileManager(msg, user_manager, client); |  | ||||||
| 					if (f==null) { |  | ||||||
| 						ps.setNull(2, Types.VARCHAR); |  | ||||||
| 						ps.setNull(3, Types.VARCHAR); |  | ||||||
| 						ps.setNull(4, Types.INTEGER); |  | ||||||
| 					} else { |  | ||||||
| 						ps.setString(2, f.getName()); |  | ||||||
| 						ps.setString(3, f.getTargetFilename()); |  | ||||||
| 						ps.setInt(4, f.getSize()); |  | ||||||
| 					} |  | ||||||
| 					ps.addBatch(); |  | ||||||
| 				} |  | ||||||
| 				rs.close(); |  | ||||||
| 				conn.setAutoCommit(false); |  | ||||||
| 				ps.executeBatch(); |  | ||||||
| 				conn.commit(); |  | ||||||
| 				conn.setAutoCommit(true); |  | ||||||
| 				stmt.executeUpdate("DROP TABLE messages"); |  | ||||||
| 				stmt.executeUpdate("ALTER TABLE messages_new RENAME TO messages"); |  | ||||||
| 				stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (6)"); |  | ||||||
| 				version = 6; |  | ||||||
| 			} |  | ||||||
| 					 |  | ||||||
| 				 |  | ||||||
| 			 |  | ||||||
| 		} catch (SQLException e) { |  | ||||||
| 			System.out.println(e.getSQLState()); |  | ||||||
| 			throw new RuntimeException(e); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	private void backupDatabase(int currentVersion) { | 	public void backupDatabase(int currentVersion) { | ||||||
| 		String filename = String.format(Config.FILE_NAME_DB_BACKUP, currentVersion); | 		String filename = String.format(Config.FILE_NAME_DB_BACKUP, currentVersion); | ||||||
| 		System.out.println("  Creating a backup of your database as " + filename); | 		System.out.println("  Creating a backup of your database as " + filename); | ||||||
| 		try { | 		try { | ||||||
|  | 			String src = user_manager.getFileBase() + Config.FILE_NAME_DB; | ||||||
|  | 			String dst = user_manager.getFileBase() + filename; | ||||||
|  | 			Log.debug("Copying %s to %s", src, dst); | ||||||
| 			Files.copy( | 			Files.copy( | ||||||
| 				new File(user_manager.getFileBase() + Config.FILE_NAME_DB).toPath(), | 				new File(src).toPath(), | ||||||
| 				new File(user_manager.getFileBase() + filename).toPath(), | 				new File(dst).toPath(), | ||||||
| 				StandardCopyOption.REPLACE_EXISTING); | 				StandardCopyOption.REPLACE_EXISTING); | ||||||
| 		} catch (IOException e) { | 		} catch (IOException e) { | ||||||
| 			e.printStackTrace(); | 			e.printStackTrace(); | ||||||
|   | |||||||
| @@ -0,0 +1,296 @@ | |||||||
|  | package de.fabianonline.telegram_backup; | ||||||
|  |  | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.LinkedHashMap; | ||||||
|  | import java.util.LinkedList; | ||||||
|  | import java.sql.Connection; | ||||||
|  | import java.sql.SQLException; | ||||||
|  | import java.sql.Statement; | ||||||
|  | import java.sql.Types; | ||||||
|  | import java.sql.ResultSet; | ||||||
|  | import java.sql.PreparedStatement; | ||||||
|  | import com.github.badoualy.telegram.tl.api.*; | ||||||
|  | import de.fabianonline.telegram_backup.mediafilemanager.FileManagerFactory; | ||||||
|  | import de.fabianonline.telegram_backup.mediafilemanager.AbstractMediaFileManager; | ||||||
|  |  | ||||||
|  | public class DatabaseUpdates { | ||||||
|  | 	protected Connection conn; | ||||||
|  | 	protected Database db; | ||||||
|  | 	private static LinkedList<DatabaseUpdate> updates = new LinkedList<DatabaseUpdate>(); | ||||||
|  | 	 | ||||||
|  | 	public DatabaseUpdates(Connection conn, Database db) { | ||||||
|  | 		this.conn = conn; | ||||||
|  | 		this.db = db; | ||||||
|  | 		Log.debug("Registering Database Updates..."); | ||||||
|  | 		Log.up(); | ||||||
|  | 		register(new DB_Update_1(conn, db)); | ||||||
|  | 		register(new DB_Update_2(conn, db)); | ||||||
|  | 		register(new DB_Update_3(conn, db)); | ||||||
|  | 		register(new DB_Update_4(conn, db)); | ||||||
|  | 		register(new DB_Update_5(conn, db)); | ||||||
|  | 		register(new DB_Update_6(conn, db)); | ||||||
|  | 		Log.down(); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	public void doUpdates() { | ||||||
|  | 		try { | ||||||
|  | 			Statement stmt = conn.createStatement(); | ||||||
|  | 			ResultSet rs; | ||||||
|  | 			Log.debug("DatabaseUpdate.doUpdates running"); | ||||||
|  | 			Log.up(); | ||||||
|  | 			 | ||||||
|  | 			Log.debug("Getting current database version"); | ||||||
|  | 			Log.up(); | ||||||
|  | 			int version; | ||||||
|  | 			Log.debug("Checking if table database_versions exists"); | ||||||
|  | 			rs = stmt.executeQuery("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='database_versions'"); | ||||||
|  | 			rs.next(); | ||||||
|  | 			if (rs.getInt(1)==0) { | ||||||
|  | 				Log.debug("Table does not exist"); | ||||||
|  | 				version = 0; | ||||||
|  | 			} else { | ||||||
|  | 				Log.debug("Table exists. Checking max version"); | ||||||
|  | 				rs.close(); | ||||||
|  | 				rs = stmt.executeQuery("SELECT MAX(version) FROM database_versions"); | ||||||
|  | 				rs.next(); | ||||||
|  | 				version = rs.getInt(1); | ||||||
|  | 				rs.close(); | ||||||
|  | 			} | ||||||
|  | 			Log.debug("version: %d", version); | ||||||
|  | 			Log.down(); | ||||||
|  | 			System.out.println("Database version: " + version); | ||||||
|  | 			Log.debug("Max available database version is %d", getMaxPossibleVersion()); | ||||||
|  | 			 | ||||||
|  | 			if (version < getMaxPossibleVersion()) { | ||||||
|  | 				Log.debug("Update is necessary. %d => %d.", version, getMaxPossibleVersion()); | ||||||
|  | 				boolean backup = false; | ||||||
|  | 				for (int i=version+1; i<=getMaxPossibleVersion(); i++) { | ||||||
|  | 					if (getUpdateToVersion(i).needsBackup()) { | ||||||
|  | 						Log.debug("Update to version %d needs a backup", i); | ||||||
|  | 						backup=true; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if (backup) { | ||||||
|  | 					Log.debug("Performing backup"); | ||||||
|  | 					Log.up(); | ||||||
|  | 					db.backupDatabase(version); | ||||||
|  | 					Log.down(); | ||||||
|  | 				} | ||||||
|  | 				 | ||||||
|  | 				Log.debug("Applying updates"); | ||||||
|  | 				Log.up(); | ||||||
|  | 				try { | ||||||
|  | 					for (int i=version+1; i<=getMaxPossibleVersion(); i++) { | ||||||
|  | 						Log.up(); | ||||||
|  | 						getUpdateToVersion(i).doUpdate(); | ||||||
|  | 						Log.down(); | ||||||
|  | 					} | ||||||
|  | 				} catch (SQLException e) { throw new RuntimeException(e); } | ||||||
|  | 				Log.down(); | ||||||
|  | 			} else { | ||||||
|  | 				Log.debug("No update necessary."); | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			Log.down(); | ||||||
|  | 		} catch (SQLException e) { | ||||||
|  | 			throw new RuntimeException(e); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private DatabaseUpdate getUpdateToVersion(int i) { return updates.get(i); } | ||||||
|  | 	 | ||||||
|  | 	private int getMaxPossibleVersion() { | ||||||
|  | 		return updates.size(); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	private void register(DatabaseUpdate d) { | ||||||
|  | 		Log.debug("Registering %s as update to version %d", d.getClass().getName(), d.getVersion()); | ||||||
|  | 		if (d.getVersion() != updates.size()+1) { | ||||||
|  | 			throw new RuntimeException("Tried to register DB update to version " + d.getVersion() + ", but would need update to version " + (updates.size()+1)); | ||||||
|  | 		} | ||||||
|  | 		updates.add(d); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | abstract class DatabaseUpdate { | ||||||
|  | 	protected Connection conn; | ||||||
|  | 	protected Statement stmt; | ||||||
|  | 	protected Database db; | ||||||
|  | 	public DatabaseUpdate(Connection conn, Database db) { | ||||||
|  | 		this.conn = conn; | ||||||
|  | 		try { | ||||||
|  | 			stmt = conn.createStatement(); | ||||||
|  | 		} catch (SQLException e) { throw new RuntimeException(e); } | ||||||
|  | 		this.db = db; | ||||||
|  | 	 | ||||||
|  | 	} | ||||||
|  | 	public void doUpdate() throws SQLException { | ||||||
|  | 		Log.debug("Applying update to version %d", getVersion()); | ||||||
|  | 		System.out.println("  Updating to version " + getVersion() + "..."); | ||||||
|  | 		Log.up(); | ||||||
|  | 		_doUpdate(); | ||||||
|  | 		Log.down(); | ||||||
|  | 		Log.debug("Saving current database version to the db"); | ||||||
|  | 		stmt.executeUpdate("INSERT INTO database_versions (version) VALUES (" + getVersion() + ")"); | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	protected abstract void _doUpdate() throws SQLException; | ||||||
|  | 	public abstract int getVersion(); | ||||||
|  | 	public boolean needsBackup() { return false; } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class DB_Update_1 extends DatabaseUpdate { | ||||||
|  | 	public int getVersion() { return 1; } | ||||||
|  | 	public DB_Update_1(Connection conn, Database db) { super(conn, db); } | ||||||
|  | 	 | ||||||
|  | 	protected void _doUpdate() throws SQLException { | ||||||
|  | 		stmt.executeUpdate("CREATE TABLE messages (" | ||||||
|  | 			+ "id INTEGER PRIMARY KEY ASC, " | ||||||
|  | 			+ "dialog_id INTEGER, " | ||||||
|  | 			+ "to_id INTEGER, " | ||||||
|  | 			+ "from_id INTEGER, " | ||||||
|  | 			+ "from_type TEXT, " | ||||||
|  | 			+ "text TEXT, " | ||||||
|  | 			+ "time TEXT, " | ||||||
|  | 			+ "has_media BOOLEAN, " | ||||||
|  | 			+ "sticker TEXT, " | ||||||
|  | 			+ "data BLOB," | ||||||
|  | 			+ "type TEXT)"); | ||||||
|  | 		stmt.executeUpdate("CREATE TABLE dialogs (" | ||||||
|  | 			+ "id INTEGER PRIMARY KEY ASC, " | ||||||
|  | 			+ "name TEXT, " | ||||||
|  | 			+ "type TEXT)"); | ||||||
|  | 		stmt.executeUpdate("CREATE TABLE people (" | ||||||
|  | 			+ "id INTEGER PRIMARY KEY ASC, " | ||||||
|  | 			+ "first_name TEXT, " | ||||||
|  | 			+ "last_name TEXT, " | ||||||
|  | 			+ "username TEXT, " | ||||||
|  | 			+ "type TEXT)"); | ||||||
|  | 		stmt.executeUpdate("CREATE TABLE database_versions (" | ||||||
|  | 			+ "version INTEGER)");		 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class DB_Update_2 extends DatabaseUpdate { | ||||||
|  | 	public int getVersion() { return 2; } | ||||||
|  | 	public DB_Update_2(Connection conn, Database db) { super(conn, db); } | ||||||
|  | 	 | ||||||
|  | 	protected void _doUpdate() throws SQLException { | ||||||
|  | 		stmt.executeUpdate("ALTER TABLE people RENAME TO 'users'"); | ||||||
|  | 		stmt.executeUpdate("ALTER TABLE users ADD COLUMN phone TEXT"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class DB_Update_3 extends DatabaseUpdate { | ||||||
|  | 	public int getVersion() { return 3; } | ||||||
|  | 	public DB_Update_3(Connection conn, Database db) { super(conn, db); } | ||||||
|  | 	 | ||||||
|  | 	protected void _doUpdate() throws SQLException { | ||||||
|  | 		stmt.executeUpdate("ALTER TABLE dialogs RENAME TO 'chats'"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class DB_Update_4 extends DatabaseUpdate { | ||||||
|  | 	public int getVersion() { return 4; } | ||||||
|  | 	public DB_Update_4(Connection conn, Database db) { super(conn, db); } | ||||||
|  | 	 | ||||||
|  | 	protected void _doUpdate() throws SQLException { | ||||||
|  | 		stmt.executeUpdate("CREATE TABLE messages_new (id INTEGER PRIMARY KEY ASC, dialog_id INTEGER, to_id INTEGER, from_id INTEGER, from_type TEXT, text TEXT, time INTEGER, has_media BOOLEAN, sticker TEXT, data BLOB, type TEXT);"); | ||||||
|  | 		stmt.executeUpdate("INSERT INTO messages_new SELECT * FROM messages"); | ||||||
|  | 		stmt.executeUpdate("DROP TABLE messages"); | ||||||
|  | 		stmt.executeUpdate("ALTER TABLE messages_new RENAME TO 'messages'"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class DB_Update_5 extends DatabaseUpdate { | ||||||
|  | 	public int getVersion() { return 5; } | ||||||
|  | 	public DB_Update_5(Connection conn, Database db) { super(conn, db); } | ||||||
|  | 	 | ||||||
|  | 	protected void _doUpdate() throws SQLException { | ||||||
|  | 		stmt.executeUpdate("CREATE TABLE runs (id INTEGER PRIMARY KEY ASC, time INTEGER, start_id INTEGER, end_id INTEGER, count_missing INTEGER)"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class DB_Update_6 extends DatabaseUpdate { | ||||||
|  | 	public int getVersion() { return 6; } | ||||||
|  | 	public DB_Update_6(Connection conn, Database db) { super(conn, db); } | ||||||
|  | 	public boolean needsBackup() { return true; } | ||||||
|  | 	 | ||||||
|  | 	protected void _doUpdate() throws SQLException { | ||||||
|  | 		stmt.executeUpdate( | ||||||
|  | 			"CREATE TABLE messages_new (\n" + | ||||||
|  | 			"    id INTEGER PRIMARY KEY ASC,\n" + | ||||||
|  | 			"    message_type TEXT,\n" + | ||||||
|  | 			"    dialog_id INTEGER,\n" + | ||||||
|  | 			"    chat_id INTEGER,\n" + | ||||||
|  | 			"    sender_id INTEGER,\n" + | ||||||
|  | 			"    fwd_from_id INTEGER,\n" + | ||||||
|  | 			"    text TEXT,\n" + | ||||||
|  | 			"    time INTEGER,\n" + | ||||||
|  | 			"    has_media BOOLEAN,\n" + | ||||||
|  | 			"    media_type TEXT,\n" + | ||||||
|  | 			"    media_file TEXT,\n" + | ||||||
|  | 			"    media_size INTEGER,\n" + | ||||||
|  | 			"    media_json TEXT,\n" + | ||||||
|  | 			"    markup_json TEXT,\n" + | ||||||
|  | 			"    data BLOB)"); | ||||||
|  | 		LinkedHashMap<String, String> mappings = new LinkedHashMap<String, String>(); | ||||||
|  | 		mappings.put("id", "id"); | ||||||
|  | 		mappings.put("message_type", "type"); | ||||||
|  | 		mappings.put("dialog_id", "CASE from_type WHEN 'user' THEN dialog_id ELSE NULL END"); | ||||||
|  | 		mappings.put("chat_id",   "CASE from_type WHEN 'chat' THEN dialog_id ELSE NULL END"); | ||||||
|  | 		mappings.put("sender_id", "from_id"); | ||||||
|  | 		mappings.put("text", "text"); | ||||||
|  | 		mappings.put("time", "time"); | ||||||
|  | 		mappings.put("has_media", "has_media"); | ||||||
|  | 		mappings.put("data", "data"); | ||||||
|  | 		StringBuilder query = new StringBuilder("INSERT INTO messages_new\n("); | ||||||
|  | 		boolean first; | ||||||
|  | 		first = true; | ||||||
|  | 		for(String s : mappings.keySet()) { | ||||||
|  | 			if (!first) query.append(", "); | ||||||
|  | 			query.append(s); | ||||||
|  | 			first = false; | ||||||
|  | 		} | ||||||
|  | 		query.append(")\nSELECT \n"); | ||||||
|  | 		first = true; | ||||||
|  | 		for (String s : mappings.values()) { | ||||||
|  | 			if (!first) query.append(", "); | ||||||
|  | 			query.append(s); | ||||||
|  | 			first = false; | ||||||
|  | 		} | ||||||
|  | 		query.append("\nFROM messages"); | ||||||
|  | 		stmt.executeUpdate(query.toString()); | ||||||
|  | 		 | ||||||
|  | 		System.out.println("    Updating the data (this might take some time)..."); | ||||||
|  | 		ResultSet rs = stmt.executeQuery("SELECT id, data FROM messages_new"); | ||||||
|  | 		PreparedStatement ps = conn.prepareStatement("UPDATE messages_new SET fwd_from_id=?, media_type=?, media_file=?, media_size=? WHERE id=?"); | ||||||
|  | 		while (rs.next()) { | ||||||
|  | 			ps.setInt(5, rs.getInt(1)); | ||||||
|  | 			TLMessage msg = db.bytesToTLMessage(rs.getBytes(2)); | ||||||
|  | 			if (msg==null || msg.getFwdFromId()==null || ! (msg.getFwdFromId() instanceof TLPeerUser)) { | ||||||
|  | 				ps.setNull(1, Types.INTEGER); | ||||||
|  | 			} else { | ||||||
|  | 				ps.setInt(1, ((TLPeerUser)msg.getFwdFromId()).getUserId()); | ||||||
|  | 			} | ||||||
|  | 			AbstractMediaFileManager f = FileManagerFactory.getFileManager(msg, db.user_manager, db.client); | ||||||
|  | 			if (f==null) { | ||||||
|  | 				ps.setNull(2, Types.VARCHAR); | ||||||
|  | 				ps.setNull(3, Types.VARCHAR); | ||||||
|  | 				ps.setNull(4, Types.INTEGER); | ||||||
|  | 			} else { | ||||||
|  | 				ps.setString(2, f.getName()); | ||||||
|  | 				ps.setString(3, f.getTargetFilename()); | ||||||
|  | 				ps.setInt(4, f.getSize()); | ||||||
|  | 			} | ||||||
|  | 			ps.addBatch(); | ||||||
|  | 		} | ||||||
|  | 		rs.close(); | ||||||
|  | 		conn.setAutoCommit(false); | ||||||
|  | 		ps.executeBatch(); | ||||||
|  | 		conn.commit(); | ||||||
|  | 		conn.setAutoCommit(true); | ||||||
|  | 		stmt.executeUpdate("DROP TABLE messages"); | ||||||
|  | 		stmt.executeUpdate("ALTER TABLE messages_new RENAME TO messages"); | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user