Files
UUVPN/iOS-SwiftUI-Code/GRDB.swift-6.29.3/Tests/Performance/GRDBProfiling/GRDBProfiling/AppDelegate.swift
T

460 lines
15 KiB
Swift

import Cocoa
import GRDB
let expectedRowCount = 100_000
let insertedRowCount = 20_000
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
try! parseDateComponents()
try! parseDates()
try! fetchValues()
try! fetchPositionalValues()
try! fetchNamedValues()
try! fetchStructs()
try! fetchCodables()
try! fetchRecords()
try! insertPositionalValues()
try! insertNamedValues()
try! insertStructs()
try! insertCodables()
try! insertRecords()
}
// MARK: -
func parseDateComponents() throws {
/// Selects many dates
let request = """
WITH RECURSIVE
cnt(x) AS (
SELECT 1
UNION ALL
SELECT x+1 FROM cnt
LIMIT 50000
)
SELECT '2018-04-20 14:47:12.345' FROM cnt;
"""
try DatabaseQueue().inDatabase { db in
let cursor = try DatabaseDateComponents.fetchCursor(db, sql: request)
while try cursor.next() != nil { }
}
}
func parseDates() throws {
/// Selects many dates
let request = """
WITH RECURSIVE
cnt(x) AS (
SELECT 1
UNION ALL
SELECT x+1 FROM cnt
LIMIT 50000
)
SELECT '2018-04-20 14:47:12.345' FROM cnt;
"""
try DatabaseQueue().inDatabase { db in
let cursor = try Date.fetchCursor(db, sql: request)
while try cursor.next() != nil { }
}
}
// MARK: -
func fetchValues() throws {
let databasePath = Bundle(for: type(of: self)).path(forResource: "ProfilingDatabase", ofType: "sqlite")!
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.read(_fetchValues)
}
func _fetchValues(_ db: Database) throws {
var count = 0
let cursor = try Int.fetchCursor(db, sql: "SELECT i0 FROM items")
while try cursor.next() != nil {
count += 1
}
assert(count == expectedRowCount)
}
// MARK: -
func fetchPositionalValues() throws {
let databasePath = Bundle(for: type(of: self)).path(forResource: "ProfilingDatabase", ofType: "sqlite")!
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.read(_fetchPositionalValues)
}
func _fetchPositionalValues(_ db: Database) throws {
var count = 0
let rows = try Row.fetchCursor(db, sql: "SELECT * FROM items")
while let row = try rows.next() {
let _: Int = row[0]
let _: Int = row[1]
let _: Int = row[2]
let _: Int = row[3]
let _: Int = row[4]
let _: Int = row[5]
let _: Int = row[6]
let _: Int = row[7]
let _: Int = row[8]
let _: Int = row[9]
count += 1
}
assert(count == expectedRowCount)
}
// MARK: -
func fetchNamedValues() throws {
let databasePath = Bundle(for: type(of: self)).path(forResource: "ProfilingDatabase", ofType: "sqlite")!
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.read(_fetchNamedValues)
}
func _fetchNamedValues(_ db: Database) throws {
var count = 0
let rows = try Row.fetchCursor(db, sql: "SELECT * FROM items")
while let row = try rows.next() {
let _: Int = row["i0"]
let _: Int = row["i1"]
let _: Int = row["i2"]
let _: Int = row["i3"]
let _: Int = row["i4"]
let _: Int = row["i5"]
let _: Int = row["i6"]
let _: Int = row["i7"]
let _: Int = row["i8"]
let _: Int = row["i9"]
count += 1
}
assert(count == expectedRowCount)
}
// MARK: -
func fetchStructs() throws {
let databasePath = Bundle(for: type(of: self)).path(forResource: "ProfilingDatabase", ofType: "sqlite")!
let dbQueue = try DatabaseQueue(path: databasePath)
let items = try dbQueue.read(_fetchStructs)
assert(items.count == expectedRowCount)
assert(items[0].i0 == 0)
assert(items[1].i1 == 1)
assert(items[expectedRowCount-1].i9 == expectedRowCount-1)
}
func _fetchStructs(_ db: Database) throws -> [ItemStruct] {
try ItemStruct.fetchAll(db)
}
// MARK: -
func fetchCodables() throws {
let databasePath = Bundle(for: type(of: self)).path(forResource: "ProfilingDatabase", ofType: "sqlite")!
let dbQueue = try DatabaseQueue(path: databasePath)
let items = try dbQueue.read(_fetchCodables)
assert(items.count == expectedRowCount)
assert(items[0].i0 == 0)
assert(items[1].i1 == 1)
assert(items[expectedRowCount-1].i9 == expectedRowCount-1)
}
func _fetchCodables(_ db: Database) throws -> [ItemCodable] {
try ItemCodable.fetchAll(db)
}
// MARK: -
func fetchRecords() throws {
let databasePath = Bundle(for: type(of: self)).path(forResource: "ProfilingDatabase", ofType: "sqlite")!
let dbQueue = try DatabaseQueue(path: databasePath)
let items = try dbQueue.read(_fetchRecords)
assert(items.count == expectedRowCount)
assert(items[0].i0 == 0)
assert(items[1].i1 == 1)
assert(items[expectedRowCount-1].i9 == expectedRowCount-1)
}
func _fetchRecords(_ db: Database) throws -> [ItemRecord] {
try ItemRecord.fetchAll(db)
}
// MARK: -
func insertPositionalValues() throws {
let databaseFileName = "GRDBPerformanceTests-\(ProcessInfo.processInfo.globallyUniqueString).sqlite"
let databasePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(databaseFileName)
_ = try? FileManager.default.removeItem(atPath: databasePath)
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.write { db in
try db.execute(sql: "CREATE TABLE items (i0 INT, i1 INT, i2 INT, i3 INT, i4 INT, i5 INT, i6 INT, i7 INT, i8 INT, i9 INT)")
}
try dbQueue.write(_insertPositionalValues)
try dbQueue.read { db in
assert(try! Int.fetchOne(db, sql: "SELECT COUNT(*) FROM items")! == insertedRowCount)
assert(try! Int.fetchOne(db, sql: "SELECT MIN(i0) FROM items")! == 0)
assert(try! Int.fetchOne(db, sql: "SELECT MAX(i9) FROM items")! == insertedRowCount - 1)
}
try FileManager.default.removeItem(atPath: databasePath)
}
func _insertPositionalValues(_ db: Database) throws {
let statement = try db.makeStatement(sql: "INSERT INTO items (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) VALUES (?,?,?,?,?,?,?,?,?,?)")
for i in 0..<insertedRowCount {
try statement.execute(arguments: [i, i, i, i, i, i, i, i, i, i])
}
}
// MARK: -
func insertNamedValues() throws {
let databaseFileName = "GRDBPerformanceTests-\(ProcessInfo.processInfo.globallyUniqueString).sqlite"
let databasePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(databaseFileName)
_ = try? FileManager.default.removeItem(atPath: databasePath)
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.write { db in
try db.execute(sql: "CREATE TABLE items (i0 INT, i1 INT, i2 INT, i3 INT, i4 INT, i5 INT, i6 INT, i7 INT, i8 INT, i9 INT)")
}
try dbQueue.write(_insertNamedValues)
try dbQueue.read { db in
assert(try! Int.fetchOne(db, sql: "SELECT COUNT(*) FROM items")! == insertedRowCount)
assert(try! Int.fetchOne(db, sql: "SELECT MIN(i0) FROM items")! == 0)
assert(try! Int.fetchOne(db, sql: "SELECT MAX(i9) FROM items")! == insertedRowCount - 1)
}
try FileManager.default.removeItem(atPath: databasePath)
}
func _insertNamedValues(_ db: Database) throws {
let statement = try db.makeStatement(sql: "INSERT INTO items (i0, i1, i2, i3, i4, i5, i6, i7, i8, i9) VALUES (:i0, :i1, :i2, :i3, :i4, :i5, :i6, :i7, :i8, :i9)")
for i in 0..<insertedRowCount {
try statement.execute(arguments: ["i0": i, "i1": i, "i2": i, "i3": i, "i4": i, "i5": i, "i6": i, "i7": i, "i8": i, "i9": i])
}
}
// MARK: -
func insertStructs() throws {
let databaseFileName = "GRDBPerformanceTests-\(ProcessInfo.processInfo.globallyUniqueString).sqlite"
let databasePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(databaseFileName)
_ = try? FileManager.default.removeItem(atPath: databasePath)
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.write { db in
try db.execute(sql: "CREATE TABLE items (i0 INT, i1 INT, i2 INT, i3 INT, i4 INT, i5 INT, i6 INT, i7 INT, i8 INT, i9 INT)")
}
try dbQueue.write(_insertStructs)
try dbQueue.read { db in
assert(try! Int.fetchOne(db, sql: "SELECT COUNT(*) FROM items")! == insertedRowCount)
assert(try! Int.fetchOne(db, sql: "SELECT MIN(i0) FROM items")! == 0)
assert(try! Int.fetchOne(db, sql: "SELECT MAX(i9) FROM items")! == insertedRowCount - 1)
}
try FileManager.default.removeItem(atPath: databasePath)
}
func _insertStructs(_ db: Database) throws {
for i in 0..<insertedRowCount {
try ItemStruct(i0: i, i1: i, i2: i, i3: i, i4: i, i5: i, i6: i, i7: i, i8: i, i9: i).insert(db)
}
}
// MARK: -
func insertCodables() throws {
let databaseFileName = "GRDBPerformanceTests-\(ProcessInfo.processInfo.globallyUniqueString).sqlite"
let databasePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(databaseFileName)
_ = try? FileManager.default.removeItem(atPath: databasePath)
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.write { db in
try db.execute(sql: "CREATE TABLE items (i0 INT, i1 INT, i2 INT, i3 INT, i4 INT, i5 INT, i6 INT, i7 INT, i8 INT, i9 INT)")
}
try dbQueue.write(_insertCodables)
try dbQueue.read { db in
assert(try! Int.fetchOne(db, sql: "SELECT COUNT(*) FROM items")! == insertedRowCount)
assert(try! Int.fetchOne(db, sql: "SELECT MIN(i0) FROM items")! == 0)
assert(try! Int.fetchOne(db, sql: "SELECT MAX(i9) FROM items")! == insertedRowCount - 1)
}
try FileManager.default.removeItem(atPath: databasePath)
}
func _insertCodables(_ db: Database) throws {
for i in 0..<insertedRowCount {
try ItemCodable(i0: i, i1: i, i2: i, i3: i, i4: i, i5: i, i6: i, i7: i, i8: i, i9: i).insert(db)
}
}
// MARK: -
func insertRecords() throws {
let databaseFileName = "GRDBPerformanceTests-\(ProcessInfo.processInfo.globallyUniqueString).sqlite"
let databasePath = (NSTemporaryDirectory() as NSString).appendingPathComponent(databaseFileName)
_ = try? FileManager.default.removeItem(atPath: databasePath)
let dbQueue = try DatabaseQueue(path: databasePath)
try dbQueue.write { db in
try db.execute(sql: "CREATE TABLE items (i0 INT, i1 INT, i2 INT, i3 INT, i4 INT, i5 INT, i6 INT, i7 INT, i8 INT, i9 INT)")
}
try dbQueue.write(_insertRecords)
try dbQueue.read { db in
assert(try! Int.fetchOne(db, sql: "SELECT COUNT(*) FROM items")! == insertedRowCount)
assert(try! Int.fetchOne(db, sql: "SELECT MIN(i0) FROM items")! == 0)
assert(try! Int.fetchOne(db, sql: "SELECT MAX(i9) FROM items")! == insertedRowCount - 1)
}
try FileManager.default.removeItem(atPath: databasePath)
}
func _insertRecords(_ db: Database) throws {
for i in 0..<insertedRowCount {
try ItemRecord(i0: i, i1: i, i2: i, i3: i, i4: i, i5: i, i6: i, i7: i, i8: i, i9: i).insert(db)
}
}
}
class ItemRecord : Record {
var i0: Int?
var i1: Int?
var i2: Int?
var i3: Int?
var i4: Int?
var i5: Int?
var i6: Int?
var i7: Int?
var i8: Int?
var i9: Int?
init(i0: Int?, i1: Int?, i2: Int?, i3: Int?, i4: Int?, i5: Int?, i6: Int?, i7: Int?, i8: Int?, i9: Int?) {
self.i0 = i0
self.i1 = i1
self.i2 = i2
self.i3 = i3
self.i4 = i4
self.i5 = i5
self.i6 = i6
self.i7 = i7
self.i8 = i8
self.i9 = i9
super.init()
}
override class var databaseTableName: String {
"items"
}
required init(row: GRDB.Row) throws {
i0 = row["i0"]
i1 = row["i1"]
i2 = row["i2"]
i3 = row["i3"]
i4 = row["i4"]
i5 = row["i5"]
i6 = row["i6"]
i7 = row["i7"]
i8 = row["i8"]
i9 = row["i9"]
try super.init(row: row)
}
override func encode(to container: inout PersistenceContainer) throws {
container["i0"] = i0
container["i1"] = i1
container["i2"] = i2
container["i3"] = i3
container["i4"] = i4
container["i5"] = i5
container["i6"] = i6
container["i7"] = i7
container["i8"] = i8
container["i9"] = i9
}
}
struct ItemStruct: FetchableRecord, PersistableRecord {
var i0: Int?
var i1: Int?
var i2: Int?
var i3: Int?
var i4: Int?
var i5: Int?
var i6: Int?
var i7: Int?
var i8: Int?
var i9: Int?
init(i0: Int?, i1: Int?, i2: Int?, i3: Int?, i4: Int?, i5: Int?, i6: Int?, i7: Int?, i8: Int?, i9: Int?) {
self.i0 = i0
self.i1 = i1
self.i2 = i2
self.i3 = i3
self.i4 = i4
self.i5 = i5
self.i6 = i6
self.i7 = i7
self.i8 = i8
self.i9 = i9
}
static let databaseTableName = "items"
init(row: GRDB.Row) {
i0 = row["i0"]
i1 = row["i1"]
i2 = row["i2"]
i3 = row["i3"]
i4 = row["i4"]
i5 = row["i5"]
i6 = row["i6"]
i7 = row["i7"]
i8 = row["i8"]
i9 = row["i9"]
}
func encode(to container: inout PersistenceContainer) {
container["i0"] = i0
container["i1"] = i1
container["i2"] = i2
container["i3"] = i3
container["i4"] = i4
container["i5"] = i5
container["i6"] = i6
container["i7"] = i7
container["i8"] = i8
container["i9"] = i9
}
}
struct ItemCodable : Codable, FetchableRecord, PersistableRecord {
var i0: Int?
var i1: Int?
var i2: Int?
var i3: Int?
var i4: Int?
var i5: Int?
var i6: Int?
var i7: Int?
var i8: Int?
var i9: Int?
static let databaseTableName = "items"
}