annotate src/main/kotlin/name/blackcap/passman/ExportSubcommand.kt @ 23:af86b8e0b88c

Clean up exit output.
author David Barts <n5jrn@me.com>
date Tue, 02 Jul 2024 18:18:29 -0700
parents 07406c4af4a5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
1 package name.blackcap.passman
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
2
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
3 import com.opencsv.CSVWriterBuilder
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
4 import com.opencsv.ICSVWriter
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
5 import java.io.FileOutputStream
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
6 import java.io.IOException
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
7 import java.io.OutputStreamWriter
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
8 import java.sql.ResultSet
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
9 import java.text.SimpleDateFormat
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
10 import java.util.*
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
11
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
12 class ExportSubcommand() : Subcommand() {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
13 private companion object {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
14 const val NULL = "null"
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
15 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
16 private lateinit var csvDateFormat: SimpleDateFormat
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
17 private lateinit var db: Database
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
18 private val options = ImportExportArguments()
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
19 private lateinit var csvFile: String
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
20
22
07406c4af4a5 More interactive mode stuff.
David Barts <n5jrn@me.com>
parents: 21
diff changeset
21 override fun run(args: Array<String>) {
16
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
22 parseArguments(args)
21
ea65ab890f66 More work to support interactive feature.
David Barts <n5jrn@me.com>
parents: 16
diff changeset
23 db = Database.default
16
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
24 try {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
25 doExport()
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
26 } catch (e: IOException) {
21
ea65ab890f66 More work to support interactive feature.
David Barts <n5jrn@me.com>
parents: 16
diff changeset
27 throw SubcommandException(message = e.message ?: "I/O error", cause = e)
16
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
28 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
29 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
30
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
31 private fun parseArguments(args: Array<String>) {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
32 val params = parseInto("export", args, options)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
33 when (params.size) {
21
ea65ab890f66 More work to support interactive feature.
David Barts <n5jrn@me.com>
parents: 16
diff changeset
34 0 -> throw SubcommandException(message = "expecting CSV file name", status = 2)
16
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
35 1 -> csvFile = params[0]
21
ea65ab890f66 More work to support interactive feature.
David Barts <n5jrn@me.com>
parents: 16
diff changeset
36 else -> throw SubcommandException(message = "unexpected trailing arguments", status = 2)
16
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
37 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
38 csvDateFormat = SimpleDateFormat(options.format).apply {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
39 timeZone = TimeZone.getTimeZone(options.zone)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
40 isLenient = false
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
41 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
42 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
43
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
44 private fun doExport() {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
45 val csvWriter = CSVWriterBuilder(OutputStreamWriter(FileOutputStream(csvFile), options.charset))
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
46 .withEscapeChar(options.escape)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
47 .withQuoteChar(options.quote)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
48 .withSeparator(options.separator)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
49 .withLineEnd(ICSVWriter.RFC4180_LINE_END)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
50 .build()
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
51
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
52 try {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
53 db.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords").use {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
54 val results = it.executeQuery()
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
55 while (results.next()) {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
56 val entry = arrayOf<String>(
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
57 results.getDecryptedString(1, db.encryption)!!,
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
58 results.getDecryptedString(2, db.encryption)!!,
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
59 results.getDecryptedString(3, db.encryption)!!,
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
60 results.getDecryptedString(4, db.encryption) ?: NULL,
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
61 results.getTimeString(5),
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
62 results.getTimeString(6),
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
63 results.getTimeString(7)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
64 )
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
65 csvWriter.writeNext(entry)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
66 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
67 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
68 } finally {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
69 csvWriter.close()
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
70 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
71 }
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
72
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
73 private fun ResultSet.getTimeString(columnIndex: Int): String {
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
74 val value = getDate(columnIndex)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
75 return if (value == null) NULL else csvDateFormat.format(value)
7a74ae668665 Add export subcommand.
David Barts <n5jrn@me.com>
parents:
diff changeset
76 }
21
ea65ab890f66 More work to support interactive feature.
David Barts <n5jrn@me.com>
parents: 16
diff changeset
77 }