|
| 1 | +// |
| 2 | +// BYKeyValueStore.swift |
| 3 | +// brandyond |
| 4 | +// |
| 5 | +// Created by ysq on 14/12/5. |
| 6 | +// Copyright (c) 2014年 ysq. All rights reserved. |
| 7 | +// |
| 8 | + |
| 9 | +import UIKit |
| 10 | + |
| 11 | +class BYKeyValueItem:NSObject{ |
| 12 | + var itemId : String? |
| 13 | + var itemObject : AnyObject? |
| 14 | + var createdTime : NSDate? |
| 15 | + |
| 16 | + func description() -> String{ |
| 17 | + return "id=\(itemId), value=\(itemObject), timeStamp=\(createdTime)" |
| 18 | + } |
| 19 | + |
| 20 | +} |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +class BYKeyValueStore: NSObject { |
| 25 | + |
| 26 | + //文件夹路径 |
| 27 | + let PATH_OF_DOCUMENT : NSString = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as NSString |
| 28 | + |
| 29 | + private var dbQueue : FMDatabaseQueue? |
| 30 | + |
| 31 | + let DEFAULT_DB_NAME = "database.sqlite" |
| 32 | + let CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS %@ ( id TEXT NOT NULL, json TEXT NOT NULL, createdTime TEXT NOT NULL, PRIMARY KEY(id)) " |
| 33 | + let UPDATE_ITEM_SQL = "REPLACE INTO %@ (id, json, createdTime) values (?, ?, ?)" |
| 34 | + let QUERY_ITEM_SQL = "SELECT json, createdTime from %@ where id = ? Limit 1" |
| 35 | + let SELECT_ALL_SQL = "SELECT * from %@" |
| 36 | + let CLEAR_ALL_SQL = "DELETE from %@" |
| 37 | + let DELETE_ITEM_SQL = "DELETE from %@ where id = ?" |
| 38 | + let DELETE_ITEMS_SQL = "DELETE from %@ where id in ( %@ )" |
| 39 | + let DELETE_ITEMS_WITH_PREFIX_SQL = "DELETE from %@ where id like ? " |
| 40 | + |
| 41 | + |
| 42 | + class func checkTableName(tableName : NSString!)->Bool{ |
| 43 | + if(tableName.rangeOfString("").location != NSNotFound){ |
| 44 | + println("error, table name: %@ format error",tableName) |
| 45 | + return false |
| 46 | + } |
| 47 | + return true |
| 48 | + } |
| 49 | + |
| 50 | + override init(){ |
| 51 | + super.init() |
| 52 | + self.setupDB(DEFAULT_DB_NAME) |
| 53 | + } |
| 54 | + init(dbName : String!){ |
| 55 | + super.init() |
| 56 | + self.setupDB(dbName) |
| 57 | + } |
| 58 | + |
| 59 | + private func setupDB(dbName : String!){ |
| 60 | + let dbPath = PATH_OF_DOCUMENT.stringByAppendingPathComponent(dbName) |
| 61 | + if dbQueue != nil{ |
| 62 | + self.close() |
| 63 | + } |
| 64 | + dbQueue = FMDatabaseQueue(path: dbPath) |
| 65 | + } |
| 66 | + |
| 67 | + /** |
| 68 | + 创建表单 |
| 69 | + |
| 70 | + :param: tableName 表单名 |
| 71 | + */ |
| 72 | + func createTable(#tableName:String!){ |
| 73 | + if !BYKeyValueStore.checkTableName(tableName) { |
| 74 | + return |
| 75 | + } |
| 76 | + let sql = NSString(format: CREATE_TABLE_SQL, tableName) |
| 77 | + var result : Bool? |
| 78 | + dbQueue?.inDatabase({ (db) -> Void in |
| 79 | + result = db.executeUpdate(sql, withArgumentsInArray:nil) |
| 80 | + }) |
| 81 | + if !result! { |
| 82 | + println("error, failed to create table: %@",tableName) |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + /** |
| 87 | + 清除表单 |
| 88 | + |
| 89 | + :param: tableName 表单名 |
| 90 | + */ |
| 91 | + func clearTable(#tableName:String!){ |
| 92 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 93 | + return |
| 94 | + } |
| 95 | + let sql = NSString(format: CLEAR_ALL_SQL, tableName) |
| 96 | + var result : Bool? |
| 97 | + dbQueue?.inDatabase({ (db) -> Void in |
| 98 | + result = db.executeUpdate(sql, withArgumentsInArray:nil) |
| 99 | + }) |
| 100 | + if !result!{ |
| 101 | + println("error, failed to clear table: %@",tableName) |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + /** |
| 106 | + 加入数据 |
| 107 | + |
| 108 | + :param: object 数据 |
| 109 | + :param: objectId 数据索引 |
| 110 | + :param: tableName 表单名 |
| 111 | + */ |
| 112 | + func putObject(object : AnyObject! , withId objectId: String! , intoTable tableName: String!){ |
| 113 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 114 | + return |
| 115 | + } |
| 116 | + var error : NSError? |
| 117 | + var data = NSJSONSerialization.dataWithJSONObject(object, options: NSJSONWritingOptions(0), error: &error) |
| 118 | + if error != nil { |
| 119 | + println("error, faild to get json data") |
| 120 | + return |
| 121 | + }else{ |
| 122 | + let jsonString = NSString(data: data!, encoding: NSUTF8StringEncoding) |
| 123 | + let createTime = NSDate() |
| 124 | + let sql = NSString(format: UPDATE_ITEM_SQL, tableName) |
| 125 | + var result : Bool? |
| 126 | + dbQueue?.inDatabase({ (db) -> Void in |
| 127 | + result = db.executeUpdate(sql, withArgumentsInArray:[objectId,jsonString!,createTime]) |
| 128 | + }) |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + |
| 133 | + /** |
| 134 | + 根据ID查找对象 |
| 135 | + |
| 136 | + :param: objectId 对象索引 |
| 137 | + :param: tableName 表单名 |
| 138 | + |
| 139 | + :returns: 对象数据 |
| 140 | + */ |
| 141 | + func getObjectById(objectId : String! , fromTable tableName : String! )->AnyObject?{ |
| 142 | + let item = self.getBYKeyValueItemById(objectId, fromTable: tableName) |
| 143 | + if item != nil { |
| 144 | + return item!.itemObject |
| 145 | + } |
| 146 | + return nil |
| 147 | + } |
| 148 | + |
| 149 | + /** |
| 150 | + 获取数据封装类型 |
| 151 | + |
| 152 | + :param: objectId 对象索引 |
| 153 | + :param: tableName 表单名 |
| 154 | + |
| 155 | + :returns: 对象数据 |
| 156 | + */ |
| 157 | + func getBYKeyValueItemById(objectId :String! , fromTable tableName : String! )->BYKeyValueItem?{ |
| 158 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 159 | + return nil |
| 160 | + } |
| 161 | + let sql = NSString(format: QUERY_ITEM_SQL, tableName) |
| 162 | + var json : String? = nil |
| 163 | + var createdTime : NSDate? = nil |
| 164 | + dbQueue?.inDatabase({ (db) -> Void in |
| 165 | + var rs : FMResultSet = db.executeQuery(sql, withArgumentsInArray: [objectId]) |
| 166 | + if rs.next() { |
| 167 | + json = rs.stringForColumn("json") |
| 168 | + createdTime = rs.dateForColumn("createdTime") |
| 169 | + } |
| 170 | + rs.close() |
| 171 | + }) |
| 172 | + if json != nil{ |
| 173 | + var error : NSError? |
| 174 | + var result: AnyObject? = NSJSONSerialization.JSONObjectWithData(json!.dataUsingEncoding(NSUTF8StringEncoding)!, options: NSJSONReadingOptions.AllowFragments, error: &error) |
| 175 | + if error != nil{ |
| 176 | + println("error, faild to prase to json") |
| 177 | + return nil |
| 178 | + } |
| 179 | + var item = BYKeyValueItem() |
| 180 | + item.itemId = objectId |
| 181 | + item.itemObject = result! |
| 182 | + item.createdTime = createdTime |
| 183 | + return item |
| 184 | + }else{ |
| 185 | + return nil |
| 186 | + } |
| 187 | + } |
| 188 | + |
| 189 | + |
| 190 | + /** |
| 191 | + 插入字符串 |
| 192 | + |
| 193 | + :param: string 字符串 |
| 194 | + :param: stringId 索引 |
| 195 | + :param: tableName 表单名 |
| 196 | + */ |
| 197 | + func putString(string : String! , withId stringId : String! , intoTable tableName:String!){ |
| 198 | + self.putObject([string], withId: stringId, intoTable: tableName) |
| 199 | + } |
| 200 | + |
| 201 | + /** |
| 202 | + 获取字符串 |
| 203 | + |
| 204 | + :param: stringId 索引 |
| 205 | + :param: tableName 表单名 |
| 206 | + |
| 207 | + :returns: 字符串 |
| 208 | + */ |
| 209 | + func getStringById(stringId : String! , fromTable tableName : String!)->String?{ |
| 210 | + let array : AnyObject? = self.getObjectById(stringId, fromTable: tableName) |
| 211 | + if let result = array as? NSArray { |
| 212 | + return result[0] as? String |
| 213 | + }else{ |
| 214 | + return nil |
| 215 | + } |
| 216 | + } |
| 217 | + |
| 218 | + /** |
| 219 | + 插入数字 |
| 220 | + |
| 221 | + :param: number 数字 |
| 222 | + :param: numberId 索引 |
| 223 | + :param: tableName 表单名 |
| 224 | + */ |
| 225 | + func putNumber(number : NSNumber! , withId numberId : String! , intoTable tableName : String!){ |
| 226 | + self.putObject([number], withId: numberId, intoTable: tableName) |
| 227 | + } |
| 228 | + |
| 229 | + /** |
| 230 | + 获取数字 |
| 231 | + |
| 232 | + :param: numberId 索引 |
| 233 | + :param: tableName 表单名 |
| 234 | + |
| 235 | + :returns: 数字 |
| 236 | + */ |
| 237 | + func getNumberById(numberId : String! , fromTable tableName : String!)->NSNumber?{ |
| 238 | + let array : AnyObject? = self.getObjectById(numberId, fromTable: tableName) |
| 239 | + if let result = array as? NSArray { |
| 240 | + return result[0] as? NSNumber |
| 241 | + }else{ |
| 242 | + return nil |
| 243 | + } |
| 244 | + } |
| 245 | + |
| 246 | + /** |
| 247 | + 获取表单的所有的数据 |
| 248 | + |
| 249 | + :param: tableName 表单名 |
| 250 | + |
| 251 | + :returns: 所有数据 |
| 252 | + */ |
| 253 | + func getAllItemsFromTable(tableName : String!)->[AnyObject]?{ |
| 254 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 255 | + return nil |
| 256 | + } |
| 257 | + let sql = NSString(format: SELECT_ALL_SQL, tableName) |
| 258 | + var result : [AnyObject] = [] |
| 259 | + dbQueue?.inDatabase({ (db) -> Void in |
| 260 | + var rs : FMResultSet = db.executeQuery(sql, withArgumentsInArray: nil) |
| 261 | + while(rs.next()){ |
| 262 | + var item = BYKeyValueItem() |
| 263 | + item.itemId = rs.stringForColumn("id") |
| 264 | + item.itemObject = rs.stringForColumn("json") |
| 265 | + item.createdTime = rs.dateForColumn("createdTime") |
| 266 | + result.append(item) |
| 267 | + } |
| 268 | + rs.close() |
| 269 | + }) |
| 270 | + var error : NSError? |
| 271 | + |
| 272 | + for i in 0..<result.count { |
| 273 | + var item: BYKeyValueItem = result[i] as BYKeyValueItem |
| 274 | + error = nil |
| 275 | + var object: AnyObject? = NSJSONSerialization.JSONObjectWithData(item.itemObject!.dataUsingEncoding(NSUTF8StringEncoding)!, options: NSJSONReadingOptions.AllowFragments, error: &error) |
| 276 | + if error != nil { |
| 277 | + println("error, faild to prase to json.") |
| 278 | + }else{ |
| 279 | + item.itemObject = object! |
| 280 | + result[i] = item |
| 281 | + } |
| 282 | + } |
| 283 | + |
| 284 | + return result |
| 285 | + } |
| 286 | + |
| 287 | + /** |
| 288 | + 根据所以删除数据 |
| 289 | + |
| 290 | + :param: objectId 索引 |
| 291 | + :param: tableName 表单名 |
| 292 | + */ |
| 293 | + func deleteObjectById(objectId : String! , fromTable tableName:String!){ |
| 294 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 295 | + return |
| 296 | + } |
| 297 | + let sql = NSString(format: DELETE_ITEM_SQL, tableName) |
| 298 | + var result : Bool? |
| 299 | + dbQueue?.inDatabase({ (db) -> Void in |
| 300 | + result = db.executeUpdate(sql, withArgumentsInArray:[objectId]) |
| 301 | + }) |
| 302 | + if !result! { |
| 303 | + println("error, failed to delete time from table: %@", tableName) |
| 304 | + } |
| 305 | + } |
| 306 | + |
| 307 | + /** |
| 308 | + 根据索引数组删除数据 |
| 309 | + |
| 310 | + :param: objectIdArray 索引数组 |
| 311 | + :param: tableName 表单名 |
| 312 | + */ |
| 313 | + func deleteObjectsByIdArray(objectIdArray:[AnyObject]! , fromTable tableName : String!){ |
| 314 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 315 | + return |
| 316 | + } |
| 317 | + var stringBuilder = NSMutableString() |
| 318 | + for objectId in objectIdArray{ |
| 319 | + var item = " '\(objectId)' " |
| 320 | + if stringBuilder.length == 0 { |
| 321 | + stringBuilder.appendString("item") |
| 322 | + }else{ |
| 323 | + stringBuilder.appendString(",") |
| 324 | + stringBuilder.appendString(item) |
| 325 | + } |
| 326 | + } |
| 327 | + let sql = NSString(format: DELETE_ITEMS_SQL, tableName,stringBuilder) |
| 328 | + var result : Bool? |
| 329 | + dbQueue?.inDatabase({ (db) -> Void in |
| 330 | + result = db.executeUpdate(sql, withArgumentsInArray:nil) |
| 331 | + }) |
| 332 | + if !result!{ |
| 333 | + println("error, failed to delete items by ids from table: %@",tableName) |
| 334 | + } |
| 335 | + } |
| 336 | + |
| 337 | + /** |
| 338 | + 根据索引前缀删除数据 |
| 339 | + |
| 340 | + :param: objectIdPrefix 索引前缀 |
| 341 | + :param: tableName 表单名 |
| 342 | + */ |
| 343 | + func deleteObjectsByIdPrefix(objectIdPrefix :String , fromTable tableName:String){ |
| 344 | + if !BYKeyValueStore.checkTableName(tableName){ |
| 345 | + return |
| 346 | + } |
| 347 | + let sql = NSString(format: DELETE_ITEMS_WITH_PREFIX_SQL, tableName) |
| 348 | + let prefixArgument = NSString(format: "%@%%", objectIdPrefix) |
| 349 | + var result : Bool? |
| 350 | + dbQueue?.inDatabase({ (db) -> Void in |
| 351 | + result = db.executeUpdate(sql, withArgumentsInArray:nil) |
| 352 | + }) |
| 353 | + if !result!{ |
| 354 | + println("error, failed to delete items by id prefix from table: %@",tableName) |
| 355 | + } |
| 356 | + } |
| 357 | + |
| 358 | + /** |
| 359 | + 关闭数据库 |
| 360 | + */ |
| 361 | + func close(){ |
| 362 | + dbQueue?.close() |
| 363 | + dbQueue = nil |
| 364 | + } |
| 365 | + |
| 366 | +} |
| 367 | + |
| 368 | + |
| 369 | + |
| 370 | + |
| 371 | + |
| 372 | + |
| 373 | + |
| 374 | + |
| 375 | + |
| 376 | + |
0 commit comments