comparison src/main/kotlin/name/blackcap/passman/ExportSubcommand.kt @ 16:7a74ae668665

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