简体   繁体   English

如何使用数据模型在sqlite.swift中创建外键

[英]How to create foreign key in sqlite.swift using Data Model

I am using sqlite.swift for database creation. 我正在使用sqlite.swift创建数据库。 I have created a class using with the help of this link http://masteringswift.blogspot.in/2015/09/create-data-access-layer-with.html . 我已经通过此链接http://masteringswift.blogspot.in/2015/09/create-data-access-layer-with.html创建了一个类。 I want to create a foreign key on teamID(column) in player table reference as team table teamID(column). 我想在玩家表参考中的teamID(column)上创建一个外键作为外表teamID(column)。

Here is the helper class for team and player table: 这是团队和球员表的助手类:

class TeamDataHelper: DataHelperProtocol {
static let TABLE_NAME = "Teams"

static let table = Table(TABLE_NAME)
static let teamId = Expression<Int64>("teamid")
static let city = Expression<String>("city")
static let nickName = Expression<String>("nickname")
static let abbreviation = Expression<String>("abbreviation")


typealias T = Team

static func createTable() throws {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    do {
        let _ = try DB.run( table.create(ifNotExists: true) {t in
            t.column(teamId, primaryKey: true)
            t.column(city)
            t.column(nickName)
            t.column(abbreviation)
            })

    } catch _ {
        // Error throw if table already exists
    }

}

static func insert(item: T) throws -> Int64 {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    if (item.city != nil && item.nickName != nil && item.abbreviation != nil) {
        let insert = table.insert(city <- item.city!, nickName <- item.nickName!, abbreviation <- item.abbreviation!)
        do {
            let rowId = try DB.run(insert)
            guard rowId > 0 else {
                throw DataAccessError.Insert_Error
            }
            return rowId
        } catch _ {
            throw DataAccessError.Insert_Error
        }
    }
    throw DataAccessError.Nil_In_Data

}

static func delete (item: T) throws -> Void {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    if let id = item.teamId {
        let query = table.filter(teamId == id)
        do {
            let tmp = try DB.run(query.delete())
            guard tmp == 1 else {
                throw DataAccessError.Delete_Error
            }
        } catch _ {
            throw DataAccessError.Delete_Error
        }
    }
}

static func find(id: Int64) throws -> T? {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    let query = table.filter(teamId == id)
    let items = try DB.prepare(query)
    for item in  items {
        return Team(teamId: item[teamId] , city: item[city], nickName: item[nickName], abbreviation: item[abbreviation])
    }

    return nil

}

static func findAll() throws -> [T]? {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    var retArray = [T]()
    let items = try DB.prepare(table)
    for item in items {
        retArray.append(Team(teamId: item[teamId], city: item[city], nickName: item[nickName], abbreviation: item[abbreviation]))
    }

    return retArray

}
}



class PlayerDataHelper: DataHelperProtocol {
static let TABLE_NAME = "Players"

static let playerId = Expression<Int64>("playerid")
static let firstName = Expression<String>("firstName")
static let lastName = Expression<String>("lastName")
static let number = Expression<Int>("number")
static let teamId = Expression<Int64>("teamid")
static let position = Expression<String>("position")


static let table = Table(TABLE_NAME)

typealias T = Player

static func createTable() throws {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    do {
        _ = try DB.run( table.create(ifNotExists: true) {t in

            t.column(playerId, primaryKey: true)
            t.column(firstName)
            t.column(lastName)
            t.column(number)
            t.column(teamId)
            t.column(position)


            })
    } catch _ {
        // Error thrown when table exists
    }
}

static func insert(item: T) throws -> Int64 {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    if (item.firstName != nil && item.lastName != nil && item.teamId != nil && item.position != nil) {
        let insert = table.insert(firstName <- item.firstName!, number <- item.number!, lastName <- item.lastName!, teamId <- item.teamId!, position <- item.position!.rawValue)
        do {
            let rowId = try DB.run(insert)
            guard rowId >= 0 else {
                throw DataAccessError.Insert_Error
            }
            return rowId
        } catch _ {
            throw DataAccessError.Insert_Error
        }
    }
    throw DataAccessError.Nil_In_Data
}

static func delete (item: T) throws -> Void {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    if let id = item.playerId {
        let query = table.filter(playerId == id)
        do {
            let tmp = try DB.run(query.delete())
            guard tmp == 1 else {
                throw DataAccessError.Delete_Error
            }
        } catch _ {
            throw DataAccessError.Delete_Error
        }
    }

}

static func find(id: Int64) throws -> T? {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    let query = table.filter(playerId == id)
    let items = try DB.prepare(query)
    for item in  items {
        return Player(playerId: item[playerId], firstName: item[firstName], lastName: item[lastName], number: item[number], teamId: item[teamId], position: Positions(rawValue: item[position]))
    }

    return nil

}

static func findAll() throws -> [T]? {
    guard let DB = SQLiteDataStore.sharedInstance.BBDB else {
        throw DataAccessError.Datastore_Connection_Error
    }
    var retArray = [T]()
    let items = try DB.prepare(table)
    for item in items {
        retArray.append(Player(playerId: item[playerId], firstName: item[firstName], lastName: item[lastName], number: item[number], teamId: item[teamId], position: Positions(rawValue: item[position])))
    }

    return retArray
}
}

In above player table I want to create foreign key for teamID as reference team table teamID. 在上面的玩家表中,我想为teamID创建外键作为参考球队表teamID。 If I am creating foreign key like"t.foreignKey(teamID, on: TeamDataHelper.teamID)" it is giving error. 如果我正在创建外键,例如“ t.foreignKey(teamID,on:TeamDataHelper.teamID)”,则显示错误。

can anyone suggest me any help. 谁能建议我任何帮助。

1.Check your statement. 1.检查您的陈述。 For Swift 4 (and Xcode 9), It should be: 对于Swift 4(和Xcode 9),应为:

t.foreignKey(teamId, references: teamTable, teamId, delete: .setNull)
// FOREIGN KEY("teamid") REFERENCES "Team"("teamid") ON DELETE SET NULL

Put it in the DB.run in createTable() func in PlayerDataHelper class 将其放在PlayerDataHelper类的createTable()函数中的DB.run中

2.You also need following code in your PlayerDataHelper class 2.您还需要在PlayerDataHelper类中遵循以下代码

teamTable = Table("Team")

reference: SQLite.swift ~> 0.11.4 GitHub Documentation 参考: SQLite.swift〜> 0.11.4 GitHub文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM