view src/main/kotlin/name/blackcap/passman/RenameSubcommand.kt @ 29:bf78f7f9dad3
default tip
Fix timestamp-matching bug.
author |
David Barts <n5jrn@me.com> |
date |
Mon, 30 Dec 2024 17:10:11 -0800 (3 weeks ago) |
parents |
ea65ab890f66 |
children |
|
line source
package name.blackcap.passman
import org.apache.commons.cli.*
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)
if (commandLine.hasOption(HELP)) {
return
}
db = Database.default
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) {
throw SubcommandException(message = e.message ?: "syntax error", status = 2, cause = e)
}
if (commandLine.hasOption(HELP)) {
HelpFormatter().printHelp("$SHORTNAME rename [options] source destination", options)
return
}
if (commandLine.args.size < 2) {
throw SubcommandException(message = "expecting source and destination", status = 2)
}
if (commandLine.args.size > 2) {
throw SubcommandException(message = "unexpected trailing arguments", status = 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)) {
throw SubcommandException(message = "no record matches ${see(source)}")
}
if (recordExists(did)) {
if (commandLine.hasOption(FORCE)) {
deleteRecord(did)
} else {
throw SubcommandException(message = "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, sid)
val result = sourceStmt.executeQuery()
result.next()
db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)").use {
it.setLong(1, did)
it.setEncryptedString(2, destination, db.encryption)
it.setBytes(3, result.getBytes(1))
it.setBytes(4, result.getBytes(2))
it.setBytesOrNull(5, result.getBytes(3))
it.setLong(6, result.getLong(4))
it.setLong(7, System.currentTimeMillis())
it.setDateOrNull(8, result.getLong(6))
it.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()
}
}
}