Comments (8)
Thanks, I will look into that.
from grdb.swift.
Sample code
The trails.sqlite file is unencrypted, so SQLCipher is not used.
import Foundation
import GRDB
import MapKit
import CSV
: :
// Table = 'trail'
struct Trail: Codable, FetchableRecord, PersistableRecord {
var id: Int
var title: String
var descr: String
var colour: String
}
// Table = 'coord'
struct Coord: Codable, FetchableRecord, PersistableRecord {
//var seqno: Int - auto-incremented primary key
var trailid: Int
var latitude: Double
var longitude: Double
var speed: Double
}
// Table = 'location'
struct Location: Codable, FetchableRecord, PersistableRecord {
var id: Int
var title: String
var descr: String
var colour: String
var longitude: Double
var latitude: Double
}
// If these 4 values are the same in 2 trails or 2 locations, then assume they are duplicates
// Although, theoretically the 2 trails could be different, it is exteremely unlikely
struct UniqFeature {
var title : String
var descr : String
var longitude : Double // first longitude in a trail
var latitude : Double // first latitude in a trail
}
// ***************************
init() throws {
let folder = MyUtils.getAppFolder("trails")
let filemgr = FileManager.default
var isDir = ObjCBool(true)
let exists = filemgr.fileExists(atPath: folder, isDirectory: &isDir)
if !exists {
// create folder and SQLite file
do {
try filemgr.createDirectory(atPath: folder, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
let str = "Unable to create trails directory: \(error.debugDescription)"
throw myError(str)
}
}
// Create SQLite file if it doesn't exist, else just connect ..
do {
let path = folder + "trails.sqlite"
//trailsDB = try Connection(folder + "trails.sqlite")
dbQueue = try DatabaseQueue(path: path)
MyUtils.Log(TAG, "Opened trails.sqlite (un-encrypted)")
} catch let error as NSError {
let str = "Unable to create trails SQLite file: \(error.debugDescription)"
throw myError(str)
}
// Create 'location' table if it doesn't exist
/*
let location = Table("location")
let id = Expression<Int>("id")
let title = Expression<String>("title")
let descr = Expression<String>("descr")
let colour = Expression<String>("colour")
let longitude = Expression<Double>("longitude")
let latitude = Expression<Double>("latitude")
*/
do {
try dbQueue!.write { db in
try db.create(table: "location", ifNotExists: true) { t in
t.column("id", .integer)
t.column("title", .text)
t.column("descr", .text)
t.column("longitude", .double)
t.column("latitude", .double)
t.primaryKey(["id"])
}
try db.execute(sql: "CREATE INDEX IF NOT EXISTS index_location_on_longitude_latitude ON location(longitude, latitude)")
}
} catch let error as NSError {
let str = "Unable to create 'location' table: \(error.debugDescription)"
throw myError(str)
}
// Add 'colour' table to hold RGB value
// Been tested on iPhone 7 - colour(TEXT) field is created.
do {
try dbQueue!.write { db in
try db.execute(sql: "ALTER TABLE location ADD COLUMN colour text")
}
} catch let error as NSError {
let str = "Unable to add 'colour' column to 'location' table: \(error.debugDescription)"
MyUtils.Log(TAG, str)
}
// Create 'trail' and 'coord' tables if they don't exist
/*
let trail = Table("trail")
let id = Expression<Int>("id")
let title = Expression<String>("title")
let descr = Expression<String>("descr")
*/
do {
try dbQueue!.write { db in
try db.create(table: "trail", ifNotExists: true) { t in
t.column("id", .integer)
t.column("title", .text)
t.column("descr", .text)
t.primaryKey(["id"])
}
}
/*
try trailsDB.run(trail.create(ifNotExists: true) { t in
t.column(id, primaryKey: true) // "id" INTEGER PRIMARY KEY NOT NULL,
t.column(title)
t.column(descr)
}) */
} catch let error as NSError {
let str = "Unable to create 'trail' table: \(error.debugDescription)"
throw myError(str)
//return
}
// Add 'colour' to trail
do {
try dbQueue!.write { db in
try db.execute(sql: "ALTER TABLE trail ADD COLUMN colour text")
}
} catch let error as NSError {
let str = "Unable to add 'colour' column to 'trail' table: \(error.debugDescription)"
MyUtils.Log(TAG, str)
}
/*
let coord = Table("coord")
let seqno = Expression<Int>("seqno")
let trailid = Expression<Int>("trailid")
let speed = Expression<Double>("speed")
*/
do {
try dbQueue!.write { db in
try db.create(table: "coord", ifNotExists: true) { t in
t.autoIncrementedPrimaryKey("seqno")
t.column("trailid", .integer)
t.column("latitude", .double)
t.column("longitude", .double)
t.column("speed", .double)
}
try db.execute(sql: "CREATE INDEX IF NOT EXISTS index_coord_on_trailid ON coord(trailid)")
}
/*
try trailsDB.run(coord.create(ifNotExists: true) { t in
t.column(seqno, primaryKey: .autoincrement) // "seqno" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
t.column(trailid)
t.column(latitude)
t.column(longitude)
t.column(speed)
})
try trailsDB.run(coord.createIndex(trailid, ifNotExists: true))
*/
} catch let error as NSError {
let str = "Unable to create 'coord' table: \(error.debugDescription)"
throw myError(str)
}
}
// ***************************
// ***************************
func readTrails(trails: inout [trailGPS], idStart: Int, idFinish: Int) throws -> Int {
// Read IDs between idStart and idFinish inclusive
if (dbQueue == nil) {return -1}
/*
let trail = Table("trail")
let id = Expression<Int>("id")
let coord = Table("coord")
let trailid = Expression<Int>("trailid")
let seqno = Expression<Int>("seqno")
let title = Expression<String>("title")
let descr = Expression<String>("descr")
let speed = Expression<Double>("speed")
let latitude = Expression<Double>("latitude")
let longitude = Expression<Double>("longitude")
*/
// Read data - one SELECT statement
var oldid: Int = 0
var coords: Int = 0
var trailGps: trailGPS!
do {
try dbQueue!.read { db in
// Fetch database rows - always build SQL in DB Browser for Sqlite
let rows = try Row.fetchCursor(db, sql: """
SELECT * FROM trail
INNER JOIN coord on trail.id = coord.trailid
WHERE id>=? AND id<=?
ORDER BY id, seqno
""", arguments: [idStart, idFinish])
while let row = try rows.next() {
// If CSV has 'colour' column, then get colour as TrailColour
var color = TrailColour.MAGENTA
if let colr = row["colour"] {
color = TrailColour(rawValue: colr as! String) ?? .MAGENTA
}
//print("id: \(user[id]), email: \(user[email]), name: \(user[name])")
if oldid == 0 || oldid != row["id"] {
if oldid != 0 {
// append complete trail to array
trails.append(trailGps)
}
// next trail ..
trailGps = trailGPS(trailid: row["id"])
trailGps.title = row["title"]
trailGps.descr = row["descr"]
trailGps.colour = color
}
coords += 1
trailGps.add(coord: CLLocationCoordinate2D(
latitude: row["latitude"], longitude: row["longitude"]),
speed: row["speed"])
oldid = row["id"]
}
}
// LAST trail read (unless database is empty) ..
if oldid != 0 {trails.append(trailGps)}
} catch let error as NSError {
let str = "Unable to read trails from SQLite: \(error.debugDescription)"
throw myError(str)
//return
}
MyUtils.getSQLiteTableCount(dbQueue: dbQueue!, tablename: "trail")
MyUtils.getSQLiteTableCount(dbQueue: dbQueue!, tablename: "coord")
return coords
}
// ***************************
from grdb.swift.
I'm facing the same problem.
My app crashes when I try to write data into db.
from grdb.swift.
Hello @Tybion,
I'm sorry for those crashes.
There's insufficient information in your report:
- The crashlytics report looks mutilated. If there is a crash, there must be some error code or message visible somewhere. It is your task to read the crash report and its context and share the information that is relevant to the issue. Pasting without reading is not enough.
- The pasted code in unrelated to the crashlytics excerpt. Again, it is your task to provide information that is relevant to the issue.
- You did not provide the results of your own inquiry.
from grdb.swift.
Thanks, Gwendal.
Sorry, yes, I accidentally pasted the wrong crashlytics report. I have attached this one for the readTrails() crash - this is the function where I have pasted the code above.
I picked this because 13 users at this stage have experienced this, so is quite representative. Crashlytics says 92% of these are running iOS 17.4.1. (5% 17.2.1, 2% 17.3.0)
Line 576 is ..
try dbQueue!.read { db in
.. so the that is not very useful - just means somewhere in the closure.
I am really under pressure at the moment and have to travel over the next 24 hours, which is really bad timing. Sorry, I do not have huge skills in this low level stuff, and I am in a team of one. When I created this ticket, I thought maybe I had done something dumb that you could point out, but sounds more serious than that.
from grdb.swift.
By the way, for a TestFlight app, I have upgraded to GRDB 6.24.1, but am still waiting for Apple to approve the build.
from grdb.swift.
Something is strange in the stack trace:
Crashed: GRDB.DatabaseQueue
0 libsqlite3.dylib 0x9a10c sqlite3_sourceid + 36940
1 libsqlite3.dylib 0x52a7c sqlite3_column_type + 104
sqlite3_column_type
does not call sqlite3_sourceid
. And sqlite3_sourceid
returns a static C string: it can't crash. Either Crashlytics symbolication is wrong, either we're witnessing a big linker mess.
Could it be that your application is linked against two different and competing SQLite libraries? For example, did you introduce a new framework in your app? The problem would not be with GRDB, but with the way Xcode deals with the interaction of GRDB with this framework. I unfortunately don't have a straight answer to this kind of linker problem.
from grdb.swift.
@Tybion please reopen if anything new happens.
from grdb.swift.
Related Issues (20)
- Privacy Manifest: Entry missing for accessing file timestamps via creationDate API HOT 4
- When transaction updating multiple records in the database, if one of the records does not exist, it leads to update failure. HOT 4
- Avoid conflict with other SPM packages by renaming the CSQLite SPM target
- ValueObservation.tracking called on the updating thread HOT 5
- GRDB does not seem to copy over all rows when inserting within a migration HOT 4
- Unable to decode database NULL value as Swift nil value of type Int? when using ScopeAdapter built from splittingRowAdapters HOT 13
- PlayerRequest.swift is identical in GRDBAsyncDemo and GRDBCombineDemo HOT 4
- Library fails to compile when targeting Linux using a SQLite library that doesn't support snapshots HOT 3
- 0xdead10cc prevention — `checkForSuspensionViolation` on every `Statement.step` HOT 6
- Weird db read issue HOT 7
- Error for query count grouped HOT 4
- GRDB 6 missing DatabasePool/DatabaseQueue interchangeability HOT 3
- Thread running at User-initiated quality-of-service class waiting on a thread without a QoS class specified (base priority 0). Investigate ways to avoid priority inversions HOT 1
- [best practices] How can insert a same type of record into 2 tables HOT 8
- Using experimental CTE
- How to store database connection HOT 5
- How to temporarily disable observing changes? HOT 5
- Does cancelling a ValueObservation guarantee that it will never notify any more value?
- Async task with `AsyncStream` in command line app exits early without error during writing HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from grdb.swift.