目次
・Perfectを使って、Swiftでサーバーサイドプログラミング1 - 導入
・Perfectを使って、Swiftでサーバーサイドプログラミング2 - Hello PerfectをWebページに表示
・Perfectを使って、Swiftでサーバーサイドプログラミング3 - MySQLに接続←イマココ
はじめに
前回、サーバー立ち上げて、サイトにHello Perfectを表示できたので、今回はローカルのMySQLに接続して、DBとTableの作成、データの読み込みと書き込みの部分をやりたいと思います。
MySQLプロジェクトを追加
メニューからFile > Add Filesを選択。
Perfectを使って、Swiftでサーバーサイドプログラミング1 - 導入でダウンロードしたPerfectLibの中にMySQLのプロジェクトが入っているので、選択して追加します。
HelloPerfectプロジェクトにMySQLを追加します。
MySQL設定
次にHost名やDB名などを設定します。
HelloPerfectHandler.swiftのPerfectServerModuleInit()メソッドの上あたりにでも以下をコピーしてhogeの値を書き換えてください。
private let DB_HOST = "127.0.0.1" //localhost
private let DB_USER = "hoge" // MySQLユーザー名
private let DB_PASSWORD = "hoge" // MySQLパスワード
private let DB_NAME = "hoge" // 新しく作成するDB名
private let DB_TABLE_NAME = "hoge" // 新しく作成するTable名
DBとTableを作成する
・Perfectを使って、Swiftでサーバーサイドプログラミング2 - Hello PerfectをWebページに表示で追加したHelloPerfectHandler.swift内のIndexHandlerクラスのhandleRequestメソッド内に以下のコードを記述。
let mysql = MySQL()
let connected = mysql.connect(DB_HOST, user: DB_USER, password: DB_PASSWORD)
guard connected else {
print(mysql.errorMessage())
return
}
defer {
mysql.close()
}
//DB,Tableがなければ作成する
var schemaExists = mysql.selectDatabase(DB_NAME)
if !schemaExists {
schemaExists = mysql.query("CREATE SCHEMA \(DB_NAME) DEFAULT CHARACTER SET utf8mb4;")
}
let tableSuccess = mysql.query("CREATE TABLE IF NOT EXISTS \(DB_TABLE_NAME) (id INT(11) AUTO_INCREMENT, Content varchar(255), PRIMARY KEY (id))")
guard schemaExists && tableSuccess else {
print(mysql.errorMessage())
return
}
http://0.0.0.0:8181/にアクセスした際にDBとTableが作成されてなければ、作成するようにしています。
DBにデータを追加する
次に、http://0.0.0.0:8181/post/投稿したい文字列にアクセスした際に「投稿したい文字列」をDBにInsertするために、PerfectServerModuleInitメソッド内にRoutingを追加します。
Routing.Routes["GET", "/post/{content}"] = { (_:WebResponse) in return PostHandler() }
urlの{content}の部分に入る文字列は、次に作成するPostHandlerメソッド内で
request.urlVariables["content"]
とすると取得できます。
では、http://0.0.0.0:8181/post/投稿したい文字列にアクセスした際のHandlerを作成しましょう。
HelloPerfectHandler.swift内に以下クラスを追加。
class PostHandler: RequestHandler {
func handleRequest(request: WebRequest, response: WebResponse) {
let reqData = request.urlVariables["content"]!
// MySQLに接続
let mysql = MySQL()
let connected = mysql.connect(DB_HOST, user: DB_USER, password: DB_PASSWORD)
guard connected else {
print(mysql.errorMessage())
response.setStatus(500, message: "Server Error")
response.requestCompletedCallback()
return
}
// DBを選択
mysql.selectDatabase(DB_NAME)
defer {
mysql.close()
}
// Insert query発行(DB_TABLE_NAMEのContentカラムにreqDataを追加)
let querySuccess = mysql.query("INSERT INTO \(DB_TABLE_NAME) (Content) VALUES ('\(reqData)')")
guard querySuccess else {
print(mysql.errorMessage())
response.setStatus(500, message: "Server Error")
response.requestCompletedCallback()
return
}
response.appendBodyString("Sccess!! Insert \(reqData)")
response.setStatus(201, message: "Created")
response.requestCompletedCallback()
}
}
これでDBに追加できます。処理が成功したら以下のように表示されるはずです。
DBからデータを読み込む
次に先ほど格納したデータを読み込んでみます。
http://0.0.0.0:8181/getにアクセスするために、PerfectServerModuleInitメソッド内にRoutingを追加します。
Routing.Routes["GET", "/get"] = { (_:WebResponse) in return GetHandler() }
次にHandlerを追加します。
class GetHandler: RequestHandler {
func handleRequest(request: WebRequest, response: WebResponse) {
// MySQL接続
let mysql = MySQL()
let connected = mysql.connect(DB_HOST, user: DB_USER, password: DB_PASSWORD)
guard connected else {
print(mysql.errorMessage())
response.setStatus(500, message: "Server Error")
response.requestCompletedCallback()
return
}
// DB選択
mysql.selectDatabase(DB_NAME)
defer {
mysql.close()
}
// SELECT query発行(DB_TABLE_NAMEのContentカラムから10件取得)
let querySuccess = mysql.query("SELECT Content FROM \(DB_TABLE_NAME) LIMIT 10")
guard querySuccess else {
print(mysql.errorMessage())
response.setStatus(500, message: "Server Error")
response.requestCompletedCallback()
return
}
// resultsのカウントが0件ならリターン
let results = mysql.storeResults()!
if results.numRows() == 0 {
print("no rows found")
response.setStatus(500, message: "Server Error")
response.requestCompletedCallback()
return
}
// 値を配列にする
var contents = [String]()
results.forEachRow { row in
contents.append(row[0])
}
//JSONを文字列にしてAppendBodyStringに追加
do {
let data = try NSJSONSerialization.dataWithJSONObject(["content": contents], options: .PrettyPrinted)
let string = NSString(data: data, encoding: NSUTF8StringEncoding)
response.appendBodyString(string as! String)
response.addHeader("Content-Type", value: "application/json")
response.setStatus(200, message: "OK")
} catch {
response.setStatus(500, message: "Server Error")
}
response.requestCompletedCallback()
}
}
処理がうまくいったらこんな感じで取得できます。
おわり
MySQLへのデータ取得、追加は思ったよりもシンプルにできた。
次はクライアント側の操作で取得、追加をしてみたい。