comparison 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
comparison
equal deleted inserted replaced
10:cbe4c797c9a6 11:c69665ff37d0
1 package name.blackcap.passman
2
3 import org.apache.commons.cli.*
4 import kotlin.system.exitProcess
5
6 class RenameSubcommand(): Subcommand() {
7 private companion object {
8 const val FORCE = "force"
9 const val HELP = "help"
10 }
11 private lateinit var commandLine: CommandLine
12 private lateinit var source: String
13 private lateinit var destination: String
14 private lateinit var db: Database
15
16 override fun run(args: Array<String>) {
17 parseArguments(args)
18 db = Database.open()
19 renameIt()
20 }
21
22 private fun parseArguments(args: Array<String>) {
23 val options = Options().apply {
24 addOption("f", FORCE, false, "If destination exists exists, force overwrite.")
25 addOption("h", HELP, false, "Print this help message.")
26 }
27 try {
28 commandLine = DefaultParser().parse(options, args)
29 } catch (e: ParseException) {
30 die(e.message ?: "syntax error", 2)
31 }
32 if (commandLine.hasOption(HELP)) {
33 HelpFormatter().printHelp("$SHORTNAME rename [options] source destination", options)
34 exitProcess(0)
35 }
36 if (commandLine.args.size < 2) {
37 die("expecting source and destination", 2)
38 }
39 if (commandLine.args.size > 2) {
40 die("unexpected trailing arguments", 2)
41 }
42 source = commandLine.args[0]
43 destination = commandLine.args[1]
44 }
45
46 private fun renameIt(): Unit {
47 val sid = db.makeKey(source)
48 val did = db.makeKey(destination)
49
50 if(!recordExists(sid)) {
51 die("no record matches ${see(source)}")
52 }
53 if (recordExists(did)) {
54 if (commandLine.hasOption(FORCE)) {
55 deleteRecord(did)
56 } else {
57 die("record matching ${see(destination)} already exists")
58 }
59 }
60
61 db.connection.prepareStatement("select username, password, notes, created, modified, accessed from passwords where id = ?").use { sourceStmt ->
62 sourceStmt.setLong(1, did)
63 val result = sourceStmt.executeQuery()
64 result.next()
65 db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)").run {
66 setLong(1, did)
67 setEncryptedString(2, destination, db.encryption)
68 setBytes(3, result.getBytes(1))
69 setBytes(4, result.getBytes(2))
70 setBytesOrNull(5, result.getBytes(3))
71 setLong(6, result.getLong(4))
72 setLong(7, System.currentTimeMillis())
73 setLongOrNull(8, result.getLong(6))
74 executeUpdate()
75 }
76 }
77
78 deleteRecord(sid)
79 }
80
81 private fun recordExists(id: Long): Boolean {
82 db.connection.prepareStatement("select count(*) from passwords where id = ?").use {
83 it.setLong(1, id)
84 val result = it.executeQuery()
85 result.next()
86 return result.getInt(1) > 0
87 }
88 }
89
90 private fun deleteRecord(id: Long): Unit {
91 db.connection.prepareStatement("delete from passwords where id = ?").use {
92 it.setLong(1, id);
93 it.executeUpdate()
94 }
95 }
96 }