import Foundation
/**
1. 打开数据库
2. 如果没有数据表,需要首先创表
3. 数据操作
*/
class SQLite {
var db: COpaquePointer = nil
/// 打开数据库
///
/// :param: dbname 数据库名称
///
/// :returns: 是否打开成功
func openDatabase(dbname: String) -> Bool {
// UnsafePointer<Int8> UnsafePointer<CChar>
// 对应C语言中的 char*
// filename 必须是完整的路径名
let path = dbname.documentPath()
println(path)
// sqlite3_open 如果如果数据库不存在,会新建数据库文件
// 如果数据库文件已经存在,就直接打开,返回句柄,不会对数据有任何影响
if sqlite3_open(path, &db) == SQLITE_OK {
println("打开数据库成功")
// 本质上只需要运行一次就可以了
if createTable() {
println("创表成功")
// TODO: 测试查询数据
let sql = "SELECT id, DepartmentNo, Name FROM T_Department;"
recordSet(sql)
} else {
println("创表失败")
}
} else {
println("打开数据库失败")
}
return false
}
/// 创建数据表,将系统需要的数据表,一次性创建
private func createTable() -> Bool {
// 准备所有数据表的 SQL
// 1> 每一个 SQL 完成后都有一个 ;
// 2> 将所有创表 SQL 写在一起,每一个换行添加一个 \n
let sql = "CREATE TABLE \n" +
"IF NOT EXISTS T_Department (\n" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" +
"DepartmentNo CHAR(10) NOT NULL DEFAULT '',\n" +
"Name CHAR(50) NOT NULL DEFAULT '' \n" +
"); \n" +
"CREATE TABLE IF NOT EXISTS T_Employee ( \n" +
"'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \n" +
"'name' TEXT NOT NULL, \n" +
"'age' INTEGER NOT NULL, \n" +
"'department_id' INTEGER, \n" +
"CONSTRAINT 'FK_DEP_ID' FOREIGN KEY ('department_id') REFERENCES 'T_Department' ('id') \n" +
");"
return execSQL(sql)
}
/// 执行没有返回值的 SQL 语句
///
/// :param: sql SQL 字符串
///
/// :returns: 是否成功
func execSQL(sql: String) -> Bool {
/**
1. 数据库指针
2. SQL 字符串的 C 语言格式
3. 回调,执行完成 SQL 指令之后的函数回调,通常都是 nil
4. 回调的第一个参数的指针
5. 错误信息,通常也传入 nil
*/
return sqlite3_exec(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil) == SQLITE_OK
}
/// 执行 SQL 返回一个结果集(对象数组)
///
/// :param: sql SQL 字符串
func recordSet(sql: String) {
// 1. 准备语句
var stmt: COpaquePointer = nil
/**
1. 数据库句柄
2. SQL 的 C 语言的字符串
3. SQL 的 C 语言的字符串长度 strlen,-1 会自动计算
4. stmt 的指针
5. 通常传入 nil
*/
if sqlite3_prepare_v2(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, -1, &stmt, nil) == SQLITE_OK {
// 单步获取SQL执行的结果 -> sqlite3_setup 对应一条记录
while sqlite3_step(stmt) == SQLITE_ROW {
// 获取每一条记录的数据
recordData(stmt)
}
}
}
/// 获取每一条数据的记录
///
/// :param: stmt prepared_statement 对象
func recordData(stmt: COpaquePointer) {
// 获取到记录
var count = sqlite3_column_count(stmt)
println("获取到记录,共有多少列 \(count)")
// 遍历每一列的数据
for i in 0..<count {
let type = sqlite3_column_type(stmt, i)
// 根据字段的类型,提取对应列的值
switch type {
case SQLITE_INTEGER:
println("整数 \(sqlite3_column_int64(stmt, i))")
case SQLITE_FLOAT:
println("小树 \(sqlite3_column_double(stmt, i))")
case SQLITE_NULL:
println("空 \(NSNull())")
case SQLITE_TEXT:
let chars = UnsafePointer<CChar>(sqlite3_column_text(stmt, i))
let str = String(CString: chars, encoding: NSUTF8StringEncoding)!
println("字符串 \(str)")
case let type:
println("不支持的类型 \(type)")
}
}
}
}

swift中使用sqlite3的更多相关文章

  1. 在Swift中实现 oc与swift的混编

    在Swift中想要引用OC头文件(import),可采用混编的方法,这里以sqlite为例,采用OC-Swift桥的方式实现添加头文件1引入sqlite数据库的库文件 打开工程配置文件,在build ...

  2. swift 中关于open ,public ,fileprivate,private ,internal,修饰的说明

    关于 swift 中的open ,public ,fileprivate,private, internal的区别 以下按照修饰关键字的访问约束范围 从约束的限定范围大到小的排序进行说明 open,p ...

  3. 阿里巴巴最新开源项目 - [HandyJSON] 在Swift中优雅地处理JSON

    项目名称:HandyJSON 项目地址:https://github.com/alibaba/handyjson 背景 JSON是移动端开发常用的应用层数据交换协议.最常见的场景便是,客户端向服务端发 ...

  4. Swift中的可选链与内存管理(干货系列)

    干货之前:补充一下可选链(optional chain) class A { var p: B? } class B { var p: C? } class C { func cm() -> S ...

  5. 在Swift中实现单例方法

    在写Swift的单例方法之前可以温习一下Objective-C中单例的写法: + (instancetype)sharedSingleton{ static id instance; static d ...

  6. [翻译]理解Swift中的Optional

    原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...

  7. 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型

    有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...

  8. swift 中指针的使用UnsafeMutablePointer

    在swift中已经弱化了指针的使用,可以这么使用 let s: NSRange = NSMakeRange(, ) let at = UnsafeMutablePointer<NSRange&g ...

  9. swift 中数据类型那个的转换

    在swift中关于数据类型的转换,如果参数是可选类型? 那么打印或者转换的结果 会带有Optional 字样,,

随机推荐

  1. windows 修改鼠标滚轮自然滚动

    在mac 上玩习惯了,使用windows 时的鼠标实在觉得别扭,在网上百度了一下,找到一个方法,这里记录一下 1 打开windows 的控制面板,点击“硬件和声音” 2 点击“鼠标” 3 然后点击上面 ...

  2. Python 实现简单的登录注册界面

    Python 实现简单的登录注册界面 注意:编写代码之前需要导入很重要的包 import tkinter as tk import pickle from tkinter import message ...

  3. bzoj1145[CTSC2008]图腾

    传送门 虽然是远古时期的ctsc,但是果然还是ctsc啊 前置芝士:树状数组 这个题最开始的思路很好想,由于之前写过一个类似处理的题,所以这个题我一开始就想到了思路. 首先,我们可以尝试讲图腾表示为x ...

  4. docker Mac安装和使用

    1.安装docker brew cask install docker 2.安装后可以用命令查看版本 docker --version 3.build java 项目(jar) docker buil ...

  5. Codeforces Round #547 (Div. 3) D. Colored Boots

    链接:https://codeforces.com/contest/1141/problem/D 题意: 给连个n长度的字符串. 求两个字符串相同字符对应位置的对数,并挨个打印. 字符:?可以代替任何 ...

  6. OS 内存泄漏 导致 整个aix主机block

    问题 aix 主机 1.数据库主机使用vmstat 监控,隔几分钟 就是block 爆满. cpu 没有瓶颈,I/O 显示本地磁盘hdisk0和hdisk 1 是爆满. vmstat 同时显示大量pa ...

  7. 牛客网Java刷题知识点之什么是JSP的3大常用指令、JSP的6大哪些动作、JSP中include指令和include动作有什么区别

    不多说,直接上干货! JSP的3大常用指令 包含指令(Include directive):用来包含文件和合并文件内容到当前的页面. 页面指令(Page directive):用来定义JSP页面中特定 ...

  8. 说说JVM原理?内存泄漏与溢出的区别?何时产生内存泄漏?

    1.JVM原理 JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个java实现跨平台的最核心的部分,所有的Java程序会首先被编译为.class的类文件,这种类文件可以 ...

  9. JS小游戏

    捕鱼达人 飞机大战游戏 详解javaScript的深拷贝 http://www.cnblogs.com/penghuwan/p/7359026.html

  10. uvm_test——测试用例的起点

    在UVM平台验证中,所有的test cases都extends uvm_test,首先,来看源代码 //------------------------------------------------ ...