How to delete table or update column with SQLite.swift ? - ios

I need to re-create my table in my database. Is there anyway to update table's columns or delete table with SQLite.swift ?

Link to docs
Assuming you have your variable for the open database:
let db = Database("path/to/db.sqlite3")
// what table to drop and recreate
db.drop(table: yourTable, ifExists: true)
And for altering a table
db.alter(table: yourTable, add: suffix)

Swift 5
If you're willing to use sqlite.swift cocoa pods
Replace the path with the path to your database. This is the project's Documents directory.
Replace the "table" string with the name of your table.
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
let db = try Connection("\(path.first ?? "")/db.sqlite3")
let table = Table("table")
let drop = table.drop(ifExists: true)
try db.run(drop)

Related

Filtering Realm object returns nil when there is a 100% value

I am stucked in situation when I am trying to .filter Realm objects with predicate and it returns nil, but I do the same query in Realm studio and it DOES work there.
I can return idFolder, but can't query the object using it
folders = realm.objects(Folder.self)
currentFolder = String(describing: folders?.first?.idFolder)
My code of querying:
if let idFolder = currentFolder {
let folderName = folders?.filter("idFolder = '\(String(describing: idFolder))'").first?.name
let name = callAlert(title: "Add new well for folder \(String(describing: folderName))")
}
The problem is that folderName = nil
I double checked the value of currentFolder and it is equal to what I have in my Realm database. Here is a screenshot:
Realm database
Does anybody know what I am doing wrong?
I also tried to use new querying instead of chaining request, didn't work.
the problem is on the query
"idFolder = '\(String(describing: idFolder))'"
the correct one should be like that
update
"idFolder == \(idFolder)"

No such table error in Sqlite Database swift 4.2 after change from swift 3

I'm trying to retrieve a count of records in a table using SQLite.swift and Swift in a Cocoa macOS application.
All tables can try to get data from SQLite data only two tables is showing
no such table tablename (code:1)
My query for create table is
try db.run(table1.create(ifNotExists: true) {t in
t.column(c1,primaryKey: true)
t.column(c2)
})
try db.run(table2.create(ifNotExists: true) {t in
t.column(c1,primaryKey: true)
t.column(c2)
})
My query to select table count
var count = try db.scalar("SELECT COUNT(*) FROM table1 WHERE userid=?",userid) as! Int64
var count = try db.scalar("SELECT COUNT(*) FROM table2 WHERE userid=?",userid) as! Int64
although the same code ,it is not working for one table.
Anyone knows how to solve?
Thanks Advance.

FMDB update version number doesn't work

I know how to use FMDB for the basic functions like create database table etc.
When i want to update my table like add a new column i need to update the user version number.
FMDB has a userVersion property should be sqlite's user_version. I used below code:
if let db = DBManager.shared.database, db.userVersion == 0, db.open() {
addColumnsToSomeTable()
db.userVersion = 1
}
But run the project, the userVersion still 0. It should be 1 and this if block shouldn't be entered in.
Why the userVersion can't be upgraded?
I also tried:
let string = "PRAGMA user_version = 1"
do {
try db.executeUpdate(string, values: nil)
} catch {
}
Still the same problem.
I searched some tutorials, most of them has the fileExists check like below:
if !FileManager.default.fileExists(atPath: dbPath) {
database = FMDatabase(path: dbPath)
}
What's the sense here? If file exist what's the correct way to get it?
Not the same as : database = FMDatabase(path: dbPath) ?
I opened the sqlite software DB Browser for SQLite at the same time. Close it, then works fine.

How to read a multidimensional String Array from a plist in Swift?

I'm using the following code to save a 2D String array to a plist:
func saveFavourites(favouriteStops: [[String]]) {
let directories = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)
if let library = directories.first {
if let libraryUrl = URL(string: library) {
let favouritesUrl = libraryUrl.appendingPathComponent("favourites.plist")
// Write favourites to disk
let favsArray = favouriteStops as NSArray
print(favsArray)
favsArray.write(toFile: favouritesUrl.path, atomically: true)
}
}
}
The above snippet properly creates the .plist file (confirmed by looking at the simulator's filesystem in ~/Library/Developer/CoreServices). However, when I try reading it back to a NSArray with the following snippet, it results in nil:
let directories = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)
if let library = directories.first {
if let libraryUrl = URL(string: library) {
let favouritesUrl = libraryUrl.appendingPathComponent("favourites.plist")
// favsToLoad is nil
let favsToLoad = NSArray(contentsOf: favouritesUrl)
// Do stuff with favsToLoad, if it would load properly
}
}
You're doing two very basic things wrong.
First, never make a URL from a file path by saying URL(string); this is a file on disk, so you must use URL.fileURL.
Second, don't start with a file path at all! Obtain the directory as a URL right from the start.
(Also, though I do not know whether this is the source of the issue, do not read and write directly in the Library directory. Use the Documents directory, the Application Support directory, or similar.)
So, for example, I would write:
let fm = FileManager.default
let docsurl = try fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let favouritesurl = docsurl.appendingPathComponent("favourites.plist")
I see your problem. You misspelled "favorites". :)
But seriously...
Plists can only contain a very small set of "property list objects": (dictionaries, arrays, strings, numbers (integer and float), dates, binary data, and Boolean values).
If your array's "object graph" (the objects the array contains and any container objects inside the array recursively contain) contain anything other than the above types, the save will fail.
I don't honestly know what gets saved when it fails. Have you tried opening the plist file in a text editor and looking at it?
My guess is that something other than a string has snuck into your array, it's not one of the above types, and THAT'S why it's failing.

How to save multiple entries in table using YapDatabase for swift

I am using YapDatabase for storing my objects.Need how to store multiple entries in a table.
For example : I need to save all students information in Student table. So how can I do that with YapDatabase using Swift.
var paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)
let baseDir:String = paths.count > 0 ? paths[0] as String : NSTemporaryDirectory() as String
let path = baseDir.stringByAppendingString("Database.sqlite")
yapDB = YapDatabase(path: path)
yapDataBaseConection = yapDB?.newConnection()
yapDataBaseConection?.asyncReadWriteWithBlock({ transaction in
}, completionBlock: {
});
There are plenty of examples on YapDatabase Wiki
First of all you should make a proper class that represents your student. You can read about it in this article.
Then you should save an array of your students to database. asyncReadWriteWithBlock is okay.
for student in students {
transaction.setObject(student, forKey:student.uniqueID, inCollection:"students")
}
That is all!
Another comlex task is to sort all the students and to show them in a UITableView. To make it work you should read about View and Mappings
If you are looking for some swift examples - you can check my sample project. It is swift 2.3 compatible.
Hope it helps...

Resources