-
-
Notifications
You must be signed in to change notification settings - Fork 711
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
636 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import Foundation | ||
|
||
/// A format that prints one line per database row. | ||
/// | ||
/// On each line, database values are separated by a separator (`|` | ||
/// by default). Blob values are interpreted as UTF8 strings. | ||
/// | ||
/// For example: | ||
/// | ||
/// ```swift | ||
/// // Arthur|500 | ||
/// // Barbara|1000 | ||
/// // Craig|200 | ||
/// try db.dumpRequest(Player.all(), format: .debug()) | ||
/// ``` | ||
public struct ListDumpFormat { | ||
/// A boolean value indicating if column labels are printed as the first | ||
/// line of output. | ||
public var header: Bool | ||
|
||
/// The separator between values. | ||
public var separator: String | ||
|
||
/// The string to print for NULL values. | ||
public var nullValue: String | ||
|
||
private var firstRow = true | ||
|
||
/// Creates a `ListDumpFormat`. | ||
/// | ||
/// - Parameters: | ||
/// - header: A boolean value indicating if column labels are printed | ||
/// as the first line of output. | ||
/// - separator: The separator between values. | ||
/// - nullValue: The string to print for NULL values. | ||
public init( | ||
header: Bool = false, | ||
separator: String = "|", | ||
nullValue: String = "") | ||
{ | ||
self.header = header | ||
self.separator = separator | ||
self.nullValue = nullValue | ||
} | ||
} | ||
|
||
extension ListDumpFormat: DumpFormat { | ||
public mutating func writeRow( | ||
_ db: Database, | ||
statement: Statement, | ||
to stream: inout some TextOutputStream) | ||
{ | ||
if firstRow { | ||
firstRow = false | ||
if header { | ||
stream.writeln(statement.columnNames.joined(separator: separator)) | ||
} | ||
} | ||
|
||
let sqliteStatement = statement.sqliteStatement | ||
var first = true | ||
for index in 0..<sqlite3_column_count(sqliteStatement) { | ||
// Don't log GRDB columns | ||
let column = String(cString: sqlite3_column_name(sqliteStatement, index)) | ||
if column.starts(with: "grdb_") { continue } | ||
|
||
if first { | ||
first = false | ||
} else { | ||
stream.write(separator) | ||
} | ||
|
||
stream.write(formattedValue(db, in: sqliteStatement, at: index)) | ||
} | ||
stream.write("\n") | ||
} | ||
|
||
public mutating func finalize(_ db: Database, statement: Statement, to stream: inout some TextOutputStream) { | ||
firstRow = true | ||
} | ||
|
||
private func formattedValue(_ db: Database, in sqliteStatement: SQLiteStatement, at index: CInt) -> String { | ||
switch sqlite3_column_type(sqliteStatement, index) { | ||
case SQLITE_NULL: | ||
return nullValue | ||
|
||
case SQLITE_INTEGER: | ||
return Int64(sqliteStatement: sqliteStatement, index: index).description | ||
|
||
case SQLITE_FLOAT: | ||
return Double(sqliteStatement: sqliteStatement, index: index).description | ||
|
||
case SQLITE_BLOB, SQLITE_TEXT: | ||
return String(sqliteStatement: sqliteStatement, index: index) | ||
|
||
default: | ||
return "" | ||
} | ||
} | ||
} | ||
|
||
extension DumpFormat where Self == ListDumpFormat { | ||
/// A format that prints one line per database row. | ||
/// | ||
/// On each line, database values are separated by a separator (`|` | ||
/// by default). Blob values are interpreted as UTF8 strings. | ||
/// | ||
/// For example: | ||
/// | ||
/// ```swift | ||
/// // Arthur|500 | ||
/// // Barbara|1000 | ||
/// // Craig|200 | ||
/// try db.dumpRequest(Player.all(), format: .debug()) | ||
/// ``` | ||
/// | ||
/// - Parameters: | ||
/// - header: A boolean value indicating if column labels are printed | ||
/// as the first line of output. | ||
/// - separator: The separator between values. | ||
/// - nullValue: The string to print for NULL values. | ||
public static func list( | ||
header: Bool = false, | ||
separator: String = "|", | ||
nullValue: String = "") | ||
-> Self | ||
{ | ||
ListDumpFormat(header: header, separator: separator, nullValue: nullValue) | ||
} | ||
} |
Oops, something went wrong.