LoginSignup
6
10

More than 5 years have passed since last update.

Swift3.0でPostgreSQLに接続して結果をJSONで返してみた

Last updated at Posted at 2016-12-01

Qiitaでは初めまして。
SwiftでPostgreSQLに接続しようとして苦戦したのでそのメモを兼ねたサンプルです。

動作確認環境

バージョン
OS Ubuntu 16.04.1 LTS
Swift swift-3.0.1-RELEASE(公式のビルド済みファイルを使用)
PostgreSQL 9.5.5
バージョン
IBM-Swift/Kitura 1.2.2
Zewo/PostgreSQL 0.14.3

下準備

最低限、以下のコマンドを実行しておいてください。
sudo apt-get install clang libicu-dev libcurl4-openssl-dev libssl-dev libpq-dev

SwiftとPostgreSQL自体のセットアップは省略しますが、下記の状態と想定して話をします。

  • PostgreSQL
    • ロール(ユーザー)名
      • swiftsample
    • パスワード
      • swiftsample
    • データベース名
      • swiftsample
    • データベースサーバーのURL
      • localhost
  • Swift
    • PATH設定済み

そして、swiftsampleデータベース上で、以下のクエリが実行済みの状態です。

CREATE TABLE IF NOT EXISTS profiles (
  user_id INT NOT NULL PRIMARY KEY,
  name text NOT NULL
);
INSERT INTO profiles(user_id,name) VALUES
(1,'Taro Tanaka'),
(2,'Jiro Yamada'),
(3,'Saburo Kato'),
(4,'Shiro Sato'),
(5,'Goro Watanabe');

実際にやってみる

Swift Package Managerを利用するために、プロジェクトを作成したいディレクトリへ移動済みのターミナルで
swift package init --type executable
を実行。
実行したらそのディレクトリにPackage.swiftというファイルやSourceディレクトリなどが作成されます。
Package.swiftは下記のようにしてください。

Package.swift
import PackageDescription

let package = Package(
    name: "your package name",
    dependencies: [
        .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 2),
        .Package(url: "https://github.com/Zewo/PostgreSQL.git", majorVersion: 0, minor: 14)
    ]
)

Sourcesディレクトリに移動して、Data.swiftを作成し、次のように書いてみてください。

Data.swift
import SQL

import Foundation

enum SampleField: String, ModelField {
  case userId = "user_id"
  case name = "name"

  static let tableName: String = "profiles"
  static let primaryKey: SampleField = .userId
}

struct Sample {
  let userId:Int
  let name:String
}

extension Sample: ModelProtocol {
    typealias Field = SampleField
    typealias PrimaryKey = Int

    func serialize() -> [Field : ValueConvertible?] {
        return [
            .userId: userId,
            .name: name
        ]
    }

    init<Row: RowProtocol>(row: TableRow<Sample, Row>) throws {
        userId = try row.value(.userId)
        name = try row.value(.name)
    }
}

次に同じディレクトリにあるmain.swiftを次のように書き換えてみてください。

main.swift
import Kitura
import SQL
import PostgreSQL
import SwiftyJSON

import Foundation

let user = "swiftsample"
let password = "swiftsample"
let dbUrl = "localhost"
let dbName = "swiftsample"

enum SampleError: Error {
  case urlNilError // URLがnilだったとき
}

do{
  guard let url = URL(string: "postgres://\(user):\(password)@\(dbUrl):5432/\(dbName)") else {
    throw SampleError.urlNilError
  }
  let db = try PostgreSQL.Connection(info: .init(url))
  try db.open()
  let getDatabase:((RouterRequest,RouterResponse)->()) = { request,response in
    do{
      let fetch:[PersistedEntity<Sample>]
      if let id = request.parameters["id"] {
        fetch = try Entity<Sample>.fetch(where: SampleField.userId == id,connection: db)
      }else{
        fetch = try Entity<Sample>.fetchAll(connection: db)
      }
      var arr:[[String:Any]] = []
      fetch.forEach{ entity in
        let model = entity.model
        let id = model.userId
        let name = model.name
        arr.append([
          "user_id":id,
          "name":name
        ])
      }
      try response.send(json: JSON(arr)).end()
    }catch(let e){
      print("[エラーが発生したよ!]")
      print(e)
    }
  }
  let router = Router()
  router.get("/:id(\\d+)") { request, response, _ in
    getDatabase(request,response)
  }
  router.get("/") { request, response, _ in
    getDatabase(request,response)
  }
  Kitura.addHTTPServer(onPort: 8090, with: router)
  Kitura.run()
}catch(let e){
  print("[エラーが発生したよ!]")
  print(e)
}

あとはプロジェクトのルートディレクトリ(Package.swiftがあるディレクトリ)でビルドコマンドの
swift build -Xcc -I/usr/include/postgresql
を実行して、エラーがなく、正常にビルドされた場合は
(プロジェクトのルートディレクトリ)/.build/debug/(プロジェクト名)
を実行するとHTTPサーバーが8090番ポートで立ち上がります。
実際にアクセスしてみるとJSONが吐き出されるっていう感じになります。

以上です。

参考にしたページ

Zewoを用いてサーバサイドでSwiftを利用する

6
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
10