Mercurial > cgi-bin > hgweb.cgi > PassMan
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 } |