Mercurial > cgi-bin > hgweb.cgi > PassMan
diff src/main/kotlin/name/blackcap/passman/RenameSubcommand.kt @ 11:c69665ff37d0
Add merge subcommand (untested).
author | David Barts <n5jrn@me.com> |
---|---|
date | Sat, 21 Jan 2023 15:39:42 -0800 |
parents | |
children | 4dae7a15ee48 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/kotlin/name/blackcap/passman/RenameSubcommand.kt Sat Jan 21 15:39:42 2023 -0800 @@ -0,0 +1,96 @@ +package name.blackcap.passman + +import org.apache.commons.cli.* +import kotlin.system.exitProcess + +class RenameSubcommand(): Subcommand() { + private companion object { + const val FORCE = "force" + const val HELP = "help" + } + private lateinit var commandLine: CommandLine + private lateinit var source: String + private lateinit var destination: String + private lateinit var db: Database + + override fun run(args: Array<String>) { + parseArguments(args) + db = Database.open() + renameIt() + } + + private fun parseArguments(args: Array<String>) { + val options = Options().apply { + addOption("f", FORCE, false, "If destination exists exists, force overwrite.") + addOption("h", HELP, false, "Print this help message.") + } + try { + commandLine = DefaultParser().parse(options, args) + } catch (e: ParseException) { + die(e.message ?: "syntax error", 2) + } + if (commandLine.hasOption(HELP)) { + HelpFormatter().printHelp("$SHORTNAME rename [options] source destination", options) + exitProcess(0) + } + if (commandLine.args.size < 2) { + die("expecting source and destination", 2) + } + if (commandLine.args.size > 2) { + die("unexpected trailing arguments", 2) + } + source = commandLine.args[0] + destination = commandLine.args[1] + } + + private fun renameIt(): Unit { + val sid = db.makeKey(source) + val did = db.makeKey(destination) + + if(!recordExists(sid)) { + die("no record matches ${see(source)}") + } + if (recordExists(did)) { + if (commandLine.hasOption(FORCE)) { + deleteRecord(did) + } else { + die("record matching ${see(destination)} already exists") + } + } + + db.connection.prepareStatement("select username, password, notes, created, modified, accessed from passwords where id = ?").use { sourceStmt -> + sourceStmt.setLong(1, did) + val result = sourceStmt.executeQuery() + result.next() + db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)").run { + setLong(1, did) + setEncryptedString(2, destination, db.encryption) + setBytes(3, result.getBytes(1)) + setBytes(4, result.getBytes(2)) + setBytesOrNull(5, result.getBytes(3)) + setLong(6, result.getLong(4)) + setLong(7, System.currentTimeMillis()) + setLongOrNull(8, result.getLong(6)) + executeUpdate() + } + } + + deleteRecord(sid) + } + + private fun recordExists(id: Long): Boolean { + db.connection.prepareStatement("select count(*) from passwords where id = ?").use { + it.setLong(1, id) + val result = it.executeQuery() + result.next() + return result.getInt(1) > 0 + } + } + + private fun deleteRecord(id: Long): Unit { + db.connection.prepareStatement("delete from passwords where id = ?").use { + it.setLong(1, id); + it.executeUpdate() + } + } +} \ No newline at end of file