Symfoware

Symfowareについての考察blog

Android Matrixで画像の拡大・縮小

Androidで表示している画像を拡大する方法を調べてみます。


最初のサンプル



画像を拡大するには、「Matrix」を変更すれば良いようです。
Matrix

こんなサンプルを書いてみました。

・activity_main.xml


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     xmlns:app="http://schemas.android.com/apk/res-auto"
  5.     xmlns:tools="http://schemas.android.com/tools"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent"
  8.     tools:context="com.example.baranche.myapplication.MainActivity">
  9.     <Button
  10.         android:id="@+id/btn1"
  11.         android:layout_width="wrap_content"
  12.         android:layout_height="wrap_content"
  13.         android:text="拡大"
  14.         android:onClick="expansionClick"
  15.         app:layout_constraintTop_toTopOf="parent"
  16.         app:layout_constraintLeft_toRightOf="parent">
  17.     </Button>
  18.     <ImageView
  19.         android:id="@+id/imageView"
  20.         android:layout_width="match_parent"
  21.         android:layout_height="match_parent"
  22.         android:scaleType="center"
  23.         app:layout_constraintTop_toTopOf="@+id/btn1"
  24.         app:layout_constraintLeft_toRightOf="parent"
  25.         app:layout_constraintBottom_toBottomOf="parent"
  26.          />
  27. </android.support.constraint.ConstraintLayout>





・MainActivity.java


  1. import android.graphics.Matrix;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.ImageView;
  6. public class MainActivity extends AppCompatActivity {
  7.     private ImageView mImage;
  8.     @Override
  9.     protected void onCreate(Bundle savedInstanceState) {
  10.         super.onCreate(savedInstanceState);
  11.         setContentView(R.layout.activity_main);
  12.         mImage = (ImageView)findViewById(R.id.imageView);
  13.         mImage.setImageResource(R.mipmap.ic_launcher);
  14.     }
  15.     public void expansionClick(View view) {
  16.         // matrixを取得
  17.         Matrix m = mImage.getImageMatrix();
  18.         // matrixの値を取得
  19.         float[] values = new float[9];
  20.         m.getValues(values);
  21.         // Xの拡大率を表示
  22.         float scale = values[Matrix.MSCALE_X];
  23.         setTitle("MSCALE_X:" + Float.toString(scale));
  24.         // 一旦matrixをリセット
  25.         m.reset();
  26.         // XYの拡大率を2倍にして再表示
  27.         m.postScale(scale * 2.0f, scale * 2.0f);
  28.         mImage.invalidate();
  29.     }
  30. }





初期表示

795_01.png

ボタンを押したら画像サイズを2倍にする予定ですが、左上によってしまいます。

795_02.png


画像の水平、垂直移動も合わせて指定する必要がありそうです。


  1. import android.graphics.Matrix;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.ImageView;
  6. public class MainActivity extends AppCompatActivity {
  7.     private ImageView mImage;
  8.     @Override
  9.     protected void onCreate(Bundle savedInstanceState) {
  10.         super.onCreate(savedInstanceState);
  11.         setContentView(R.layout.activity_main);
  12.         mImage = (ImageView)findViewById(R.id.imageView);
  13.         mImage.setImageResource(R.mipmap.ic_launcher);
  14.     }
  15.     public void expansionClick(View view) {
  16.         // matrixを取得
  17.         Matrix m = mImage.getImageMatrix();
  18.         // matrixの値を取得
  19.         float[] values = new float[9];
  20.         m.getValues(values);
  21.         // Xの拡大率を表示
  22.         float scale = values[Matrix.MSCALE_X];
  23.         setTitle("MSCALE_X:" + Float.toString(scale));
  24.         float transx = values[Matrix.MTRANS_X];
  25.         float transy = values[Matrix.MTRANS_Y];
  26.         // 一旦matrixをリセット
  27.         m.reset();
  28.         // XYの拡大率を2倍にして再表示
  29.         m.postScale(scale * 2.0f, scale * 2.0f, -transx, -transy);
  30.         mImage.invalidate();
  31.     }
  32. }




795_03.png


postScaleを使用しないパターンはこちら。


  1. import android.graphics.Matrix;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.ImageView;
  6. public class MainActivity extends AppCompatActivity {
  7.     private ImageView mImage;
  8.     @Override
  9.     protected void onCreate(Bundle savedInstanceState) {
  10.         super.onCreate(savedInstanceState);
  11.         setContentView(R.layout.activity_main);
  12.         mImage = (ImageView)findViewById(R.id.imageView);
  13.         mImage.setImageResource(R.mipmap.ic_launcher);
  14.     }
  15.     public void expansionClick(View view) {
  16.         // matrixを取得
  17.         Matrix m = mImage.getImageMatrix();
  18.         // matrixの値を取得
  19.         float[] values = new float[9];
  20.         m.getValues(values);
  21.         // Xの拡大率を表示
  22.         float scale = values[Matrix.MSCALE_X];
  23.         setTitle("MSCALE_X:" + Float.toString(scale));
  24.         // XYの拡大率を2倍に変更
  25.         values[Matrix.MSCALE_X] = scale * 2.0f;
  26.         values[Matrix.MSCALE_Y] = scale * 2.0f;
  27.         // 一旦matrixをリセット
  28.         m.reset();
  29.         m.setValues(values);
  30.         mImage.invalidate();
  31.     }
  32. }



結果はpostScaleを使用した場合と同じになります。




中心を原点に拡大



画像を中央に表示したまま拡大してみます。
元画像 * 拡大サイズを計算し、中央座標に寄るようにXYの移動距離を求めます。


  1. import android.graphics.Matrix;
  2. import android.graphics.Rect;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.ImageView;
  7. public class MainActivity extends AppCompatActivity {
  8.     private ImageView mImage;
  9.     @Override
  10.     protected void onCreate(Bundle savedInstanceState) {
  11.         super.onCreate(savedInstanceState);
  12.         setContentView(R.layout.activity_main);
  13.         mImage = (ImageView)findViewById(R.id.imageView);
  14.         mImage.setImageResource(R.mipmap.ic_launcher);
  15.     }
  16.     public void expansionClick(View view) {
  17.         // matrixを取得
  18.         Matrix m = mImage.getImageMatrix();
  19.         // matrixの値を取得
  20.         float[] values = new float[9];
  21.         m.getValues(values);
  22.         // Xの拡大率を表示
  23.         float scale = values[Matrix.MSCALE_X];
  24.         setTitle("MSCALE_X:" + Float.toString(scale));
  25.         // XYの拡大率を2倍に変更
  26.         values[Matrix.MSCALE_X] *= 2.0f;
  27.         values[Matrix.MSCALE_Y] *= 2.0f;
  28.         // XY座標の移動位置を計算
  29.         calcTrans(values);
  30.         // 値を再設定
  31.         m.setValues(values);
  32.         mImage.invalidate();
  33.     }
  34.     private void calcTrans(float[] values) {
  35.         // 画像の描画領域
  36.         Rect rect = new Rect();
  37.         mImage.getDrawingRect(rect);
  38.         // 元画像のサイズ
  39.         int imgWidth = mImage.getDrawable().getIntrinsicWidth();
  40.         int imgHeight = mImage.getDrawable().getIntrinsicHeight();
  41.         // 拡大後の画像幅
  42.         int imgScaledWidth = Math.round(imgWidth * values[Matrix.MSCALE_X]);
  43.         // 拡大後の画像高さ
  44.         int imgScaledHeight = Math.round(imgHeight * values[Matrix.MSCALE_Y]);
  45.         // 表示位置中央X座標 - (拡大後の画像幅 / 2)がX移動距離
  46.         values[Matrix.MTRANS_X] = (rect.width() / 2) - (imgScaledWidth / 2);
  47.         // 表示位置中央Y座標 - (拡大後の画像高さ / 2)がY移動距離
  48.         values[Matrix.MTRANS_Y] = (rect.height() / 2) - (imgScaledHeight / 2);
  49.     }
  50. }




これで中央を原点に拡大してくれました。

795_04.png

795_05.png




中央を原点に縮小



縮小も拡大と同じ計算で良いはずです。


  1. import android.graphics.Matrix;
  2. import android.graphics.Rect;
  3. import android.support.v7.app.AppCompatActivity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.ImageView;
  7. public class MainActivity extends AppCompatActivity {
  8.     private ImageView mImage;
  9.     @Override
  10.     protected void onCreate(Bundle savedInstanceState) {
  11.         super.onCreate(savedInstanceState);
  12.         setContentView(R.layout.activity_main);
  13.         mImage = (ImageView)findViewById(R.id.imageView);
  14.         mImage.setImageResource(R.mipmap.ic_launcher);
  15.     }
  16.     // 拡大ボタン
  17.     public void expansionClick(View view) {
  18.         // matrixを取得
  19.         Matrix m = mImage.getImageMatrix();
  20.         // matrixの値を取得
  21.         float[] values = new float[9];
  22.         m.getValues(values);
  23.         // Xの拡大率を表示
  24.         float scale = values[Matrix.MSCALE_X];
  25.         setTitle("MSCALE_X:" + Float.toString(scale));
  26.         // XYの拡大率を2倍に変更
  27.         values[Matrix.MSCALE_X] *= 2.0f;
  28.         values[Matrix.MSCALE_Y] *= 2.0f;
  29.         // XY座標の移動位置を計算
  30.         calcTrans(values);
  31.         // 値を再設定
  32.         m.setValues(values);
  33.         mImage.invalidate();
  34.     }
  35.     // 縮小ボタン
  36.     public void reductionClick(View view) {
  37.         // matrixを取得
  38.         Matrix m = mImage.getImageMatrix();
  39.         // matrixの値を取得
  40.         float[] values = new float[9];
  41.         m.getValues(values);
  42.         // Xの拡大率を表示
  43.         float scale = values[Matrix.MSCALE_X];
  44.         setTitle("MSCALE_X:" + Float.toString(scale));
  45.         // XYの拡大率を2倍に変更
  46.         values[Matrix.MSCALE_X] /= 2.0f;
  47.         values[Matrix.MSCALE_Y] /= 2.0f;
  48.         // XY座標の移動位置を計算
  49.         calcTrans(values);
  50.         // 値を再設定
  51.         m.setValues(values);
  52.         mImage.invalidate();
  53.     }
  54.     private void calcTrans(float[] values) {
  55.         // 画像の描画領域
  56.         Rect rect = new Rect();
  57.         mImage.getDrawingRect(rect);
  58.         // 元画像のサイズ
  59.         int imgWidth = mImage.getDrawable().getIntrinsicWidth();
  60.         int imgHeight = mImage.getDrawable().getIntrinsicHeight();
  61.         // 拡大後の画像幅
  62.         int imgScaledWidth = Math.round(imgWidth * values[Matrix.MSCALE_X]);
  63.         // 拡大後の画像高さ
  64.         int imgScaledHeight = Math.round(imgHeight * values[Matrix.MSCALE_Y]);
  65.         // 表示位置中央X座標 - (拡大後の画像幅 / 2)がX移動距離
  66.         values[Matrix.MTRANS_X] = (rect.width() / 2) - (imgScaledWidth / 2);
  67.         // 表示位置中央Y座標 - (拡大後の画像高さ / 2)がY移動距離
  68.         values[Matrix.MTRANS_Y] = (rect.height() / 2) - (imgScaledHeight / 2);
  69.     }
  70. }




これで、中央を原点として画像の拡大と縮小が行えるようになりました。

795_06.png

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/09/03(日) 21:48:31|
  2. Java
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Linux inotifywait でファイルの更新を監視し、コマンドを実行する

apidocをDebian 9にインストールしました。
APIドキュメント生成ツール apidoc をDebian 9にインストール

ソースコードを更新したら自動的にドキュメントも更新して欲しい。



inotifywait



こちらが参考になりました。
inotifywait を使って,ファイルが作成されたらアクションを起こすスクリプトを書く

inotify-toolsをインストール


# apt install inotify-tools




更新管理用のスクリプトを作成します。


# vi /var/dev/api_watch.sh




内容は以下の通り。


#!/bin/bash
# required package: inotify-tools
api_dir=/var/dev/php
doc_dir=/var/dev/apidoc

events=(-e CREATE -e MODIFY -e DELETE)
while inotifywait ${events[@]} $api_dir; do
apidoc -i $api_dir -o $doc_dir
done




ソースフォルダ内、ファイルの「作成(CREATE)」「変更(MODIFY)」「削除(DELETE)」を監視。
イベントが発生したら、apidocコマンドを実行してドキュメントを更新します。


実行権限を付与して監視を実行。


# chmod +x api_watch.sh
# ./api_watch.sh
Setting up watches.
Watches established.





適当にphpのコメントを修正して保存します。


  1. <?php
  2. /**
  3. * @api {get} /user/:id Request User information
  4. * @apiName GetUser
  5. * @apiGroup User
  6. *
  7. * @apiParam {Number} id Users unique ID.
  8. *
  9. * @apiSuccess {String} firstname Firstname of the User.
  10. * @apiSuccess {String} lastname Lastname of the User.
  11. * @apiSuccess {String} tel tel number of the User.(ここを追加)
  12. */




ドキュメントが更新されました。

794_01.png





systemdによる自動実行



systemdに登録して、バックグラウンドで自動実行するようにしておきます。

過去記事のこちらを参考にしました。
Ubuntu Systemdでプログラムをサービス起動する(窓使いの憂鬱)


設定ファイルを作成。


# vi /etc/systemd/system/api_watch.service




内容は以下の通り。
生成したドキュメントをwebサーバーで公開する場合は、UserとGroupにwww-dataを指定すると良いかもしれません。


[Unit]
Description = apidoc create daemon

[Service]
ExecStart = /var/dev/api_watch.sh
Restart = always
Type = simple

# 実行ユーザーを指定する場合
#User=www-data
#Group=www-data

[Install]
WantedBy = multi-user.target





サービスとして認識されているか確認


# systemctl list-unit-files --type=service | grep api_watch
api_watch.service                     disabled




サービスを有効化


# systemctl enable api_watch




サービス開始


# systemctl start api_watch




サービスが起動しているか確認


# systemctl status api_watch




phpのコメントを変更して動作を確認します。

794_02.png

ちゃんと監視が行われているようです。

関連記事

テーマ:サーバ - ジャンル:コンピュータ

  1. 2017/09/03(日) 16:40:32|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

APIドキュメント生成ツール apidoc をDebian 9にインストール

APIドキュメント生成ツール「apidoc」
http://apidocjs.com/

Debian 9にインストールしてみます。
こちらを参考にしました。
PHPでのAPIドキュメント作成ツール(RESTful APIとソースコードドキュメント生成)



node,npmのインストール



node製のツールなので、nodejsとnpmをインストールします。

こちらを参考にしました。
How to Install Latest Nodejs & NPM on Debian 9/8/7


# apt install curl
# curl -sL https://deb.nodesource.com/setup_8.x | bash -
# apt install nodejs




node,npmともに最新版がインストールできました。


# node -v
v8.4.0

# npm -v
5.3.0







apidocのインストールとドキュメントの生成



npmの準備ができたら、apidocをインストールします。


# npm install apidoc -g




インストールできました。


# apidoc -h

Usage: /usr/bin/nodejs apidoc [options]






ドキュメントの生成コマンドは以下の通り


apidoc -i [ソースのディレクトリ] -o [ドキュメントの出力ディレクトリ]




/var/dev/php/sample.phpを作成。
以下の内容を記載しました。


  1. <?php
  2. /**
  3. * @api {get} /user/:id Request User information
  4. * @apiName GetUser
  5. * @apiGroup User
  6. *
  7. * @apiParam {Number} id Users unique ID.
  8. *
  9. * @apiSuccess {String} firstname Firstname of the User.
  10. * @apiSuccess {String} lastname Lastname of the User.
  11. */




APIドキュメント出力用のディレクトリを作成。


# mkdir -p /var/dev/apidoc




APIドキュメントを出力します。


# apidoc -i /var/dev/php -o /var/dev/apidoc




こんなファイルたちが生成されました。

793_01.png


index.htmlを開くと、APIドキュメントが閲覧できます。

793_02.png



※2017/9/3追記

ドキュメント生成の自動化はこちら。
Linux inotifywait でファイルの更新を監視し、コマンドを実行する




【参考URL】

http://apidocjs.com/
PHPでのAPIドキュメント作成ツール(RESTful APIとソースコードドキュメント生成)
How to Install Latest Nodejs & NPM on Debian 9/8/7

関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/09/03(日) 16:16:29|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

続:SwiftKueryMySQLを利用してMariaDBに接続

SwiftKueryMySQLを利用して、MariaDBに接続してみました。
Kitura SwiftKueryMySQLを利用してMariaDBに接続

簡単なselectを試しただけなので、データの登録なども試してみたいと思います。


プロジェクトの新規作成



復習も兼ねて、テスト用のプログラムを新規作成します。
実行可能プロジェクトの雛形を作成。


$ mkdir test
$ cd test/
$ swift package init --type executable
Creating executable package: test
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/




Package.swiftに依存関係を追記。


  1. // swift-tools-version:3.1
  2. import PackageDescription
  3. let package = Package(
  4.     name: "test",
  5.     dependencies: [
  6.         .Package(url: "https://github.com/IBM-Swift/SwiftKueryMySQL.git", majorVersion: 0, minor: 13)
  7.     ]
  8. )





main.swiftに検索プログラムを記載


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Select( t.id, t.value, from:t)
  27.                 .where( t.id == 1)
  28.     connection.execute(query: query) { queryResult in
  29.         if let resultSet = queryResult.asResultSet {
  30.             // 結果の取得
  31.             for row in resultSet.rows {
  32.                 for field in row {
  33.                     let val = field ?? ""
  34.                     print("\(val)")
  35.                 }
  36.             }
  37.         } else if let queryError = queryResult.asError {
  38.             print("queryError \(queryError)")
  39.         }
  40.     }
  41. }




ビルドと実行


$ swift build
$ .build/debug/test
1
test




これで前回までの処理に追いつきました。





フィールド名で値取得



ResultSetのtitlesにフィールド名が格納されています。
こんなコードで、[フィールド名:値]の辞書型に変換することができました。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. func fetchRow(_ resultSet:ResultSet, _ row:[Any?]) -> [String:Any?] {
  10.     var dictRow = [String:Any?]();
  11.     for (i, title) in resultSet.titles.enumerated() {
  12.         dictRow[title] = row[i]
  13.     }
  14.     return dictRow
  15. }
  16. let t = MyTable()
  17. // 接続情報
  18. let connection = MySQLConnection(
  19.     host: "localhost",
  20.     user: "admin",
  21.     password: "P@ssw0rd",
  22.     database: "sample",
  23.     port: 3306,
  24.     characterSet: "utf8mb4"
  25. )
  26. connection.connect() { error in
  27.     
  28.     if let error = error {
  29.         print("Error \(error)")
  30.         return
  31.     }
  32.     // クエリー実行
  33.     let query = Select( t.id, t.value, from:t)
  34.                 .where( t.id == 1)
  35.     connection.execute(query: query) { queryResult in
  36.         if let resultSet = queryResult.asResultSet {
  37.             
  38.             // 結果の取得
  39.             for row in resultSet.rows {
  40.                 let dictRow = fetchRow(resultSet, row)
  41.                 print(dictRow["id"] as! Int32)
  42.                 print(dictRow["value"] as! String)
  43.             }
  44.         } else if let queryError = queryResult.asError {
  45.             print("queryError \(queryError)")
  46.         }
  47.     }
  48. }






Iterator



もう少しスマートにIteratorでループするようにしてみます。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. func fetchRows(_ resultSet:ResultSet) -> AnyIterator<[String:Any?]> {
  10.     return AnyIterator<[String:Any?]> {
  11.         // 結果の取得
  12.         for row in resultSet.rows {
  13.             var dictRow = [String:Any?]()
  14.             for (i, title) in resultSet.titles.enumerated() {
  15.                 dictRow[title] = row[i]
  16.             }
  17.             return dictRow
  18.         }
  19.         return nil
  20.     }
  21. }
  22. let t = MyTable()
  23. // 接続情報
  24. let connection = MySQLConnection(
  25.     host: "localhost",
  26.     user: "admin",
  27.     password: "P@ssw0rd",
  28.     database: "sample",
  29.     port: 3306,
  30.     characterSet: "utf8mb4"
  31. )
  32. connection.connect() { error in
  33.     
  34.     if let error = error {
  35.         print("Error \(error)")
  36.         return
  37.     }
  38.     // クエリー実行
  39.     let query = Select( t.id, t.value, from:t)
  40.     connection.execute(query: query) { queryResult in
  41.         if let resultSet = queryResult.asResultSet {
  42.             let rows = fetchRows(resultSet)
  43.             while let row = rows.next() {
  44.                 print(row["id"] as! Int32)
  45.                 print(row["value"] as! String)
  46.             }
  47.         } else if let queryError = queryResult.asError {
  48.             print("queryError \(queryError)")
  49.         }
  50.     }
  51. }








Insert



データ登録のサンプルです。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Insert(into: t, rows: [[1, "apple"], [2, "apricot"], [4, "banana"]])
  27.     
  28.     connection.execute(query: query) { queryResult in
  29.         if let resultSet = queryResult.asResultSet {
  30.             print("query ok")
  31.         } else if let queryError = queryResult.asError {
  32.             print("queryError \(queryError)")
  33.         }
  34.     }
  35. }




実行後のテーブル


MariaDB [sample]> select * from test;
+------+---------+
| id | value |
+------+---------+
|    1 | apple |
|    2 | apricot |
|    4 | banana |
+------+---------+
3 rows in set (0.00 sec)







Update



データ更新のサンプルです。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Update(t, set: [(t.value, "apple-update")])
  27.                 .where(t.id == 1)
  28.     
  29.     connection.execute(query: query) { queryResult in
  30.         if let resultSet = queryResult.asResultSet {
  31.             print("query ok")
  32.         } else if let queryError = queryResult.asError {
  33.             print("queryError \(queryError)")
  34.         }
  35.     }
  36. }




MariaDB [sample]> select * from test;
+------+--------------+
| id | value        |
+------+--------------+
|    1 | apple-update |
|    2 | apricot     |
|    4 | banana     |
+------+--------------+
3 rows in set (0.00 sec)







Delete



削除のサンプルです。


  1. import SwiftKuery
  2. import SwiftKueryMySQL
  3. // 検索するテーブルの定義
  4. class MyTable : Table {
  5.     let id = Column("id")
  6.     let value = Column("value")
  7.     let tableName = "test"
  8. }
  9. let t = MyTable()
  10. // 接続情報
  11. let connection = MySQLConnection(
  12.     host: "localhost",
  13.     user: "admin",
  14.     password: "P@ssw0rd",
  15.     database: "sample",
  16.     port: 3306,
  17.     characterSet: "utf8mb4"
  18. )
  19. connection.connect() { error in
  20.     
  21.     if let error = error {
  22.         print("Error \(error)")
  23.         return
  24.     }
  25.     // クエリー実行
  26.     let query = Delete(from: t)
  27.                 .where(t.id == 1)
  28.     
  29.     connection.execute(query: query) { queryResult in
  30.         if let resultSet = queryResult.asResultSet {
  31.             print("query ok")
  32.         } else if let queryError = queryResult.asError {
  33.             print("queryError \(queryError)")
  34.         }
  35.     }
  36. }




MariaDB [sample]> select * from test;
+------+---------+
| id | value |
+------+---------+
|    2 | apricot |
|    4 | banana |
+------+---------+
2 rows in set (0.00 sec)









【参考URL】

Swiftでのenumerateの使い方
Explain Swift Iterators


関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/28(月) 00:10:07|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Kitura SwiftKueryMySQLを利用してMariaDBに接続

UbuntuにSwift 3.1をインストールし、KITURAを動かしてみました。
Web APIフレームワーク「KITURA」をUbuntu + Swift 3.1で動作させる


今回は、SwiftKueryMySQLを使用してMariaDBに接続してみます。
こちらを参考にしました。
Swift-Kueryを利用したMySQLへの接続
SwiftKueryMySQL



MariaDBサーバーの用意とヘッダーファイルのインストール



Swiftをインストールした端末にMariaDB 10.0をインストールしました。
Ubuntu Server 16.04にMariaDB 10.0をインストール

ここで作成したデータベース:sampleに接続してみます。

接続用のライブラリをインストール。


$ sudo apt install libmysqlclient-dev





つづいて、設定ファイルPackage.swiftにSwiftKueryMySQLの依存関係を追記します。


  1. // swift-tools-version:3.1
  2. import PackageDescription
  3. let package = Package(
  4.     name: "myFirstProject",
  5.     dependencies: [
  6.         .Package(url: "https://github.com/IBM-Swift/Kitura.git", majorVersion: 1, minor: 7),
  7.         .Package(url: "https://github.com/IBM-Swift/HeliumLogger.git", majorVersion: 1, minor: 7),
  8.         .Package(url: "https://github.com/IBM-Swift/SwiftKueryMySQL.git", majorVersion: 0, minor: 13)
  9.     ]
  10. )




とりあえず検索できたソースコードはこちら。


  1. import Kitura
  2. import SwiftyJSON
  3. import HeliumLogger
  4. import LoggerAPI
  5. import Foundation
  6. import SwiftKuery
  7. import SwiftKueryMySQL
  8. // 検索するテーブルの定義
  9. class MyTable : Table {
  10.     let id = Column("id")
  11.     let value = Column("value")
  12.     let tableName = "test"
  13. }
  14. // Initialize HeliumLogger
  15. let logger = HeliumLogger()
  16. // let logger = HeliumLogger(.warning)で、出力レベルの指定可能
  17. Log.logger = logger
  18. // Create a new router
  19. let router = Router()
  20. // bodyを解析
  21. // ※注意 router.postを設定する前に呼び出すこと
  22. router.all("/hello", middleware: BodyParser())
  23. // Handle HTTP GET requests to /
  24. router.post("/hello") { request, response, next in
  25.     let t = MyTable()
  26.     // 接続情報
  27.     let connection = MySQLThreadSafeConnection(
  28.         host: "localhost",
  29.         user: "admin",
  30.         password: "P@ssw0rd",
  31.         database: "sample",
  32.         port: 3306,
  33.         characterSet: "utf8mb4"
  34.     )
  35.     connection.connect() { error in
  36.         
  37.         if let error = error {
  38.             Log.info("Error \(error)")
  39.             return
  40.         }
  41.         // クエリー実行
  42.         let query = Select( t.id, t.value, from:t)
  43.                     .where( t.id == 1)
  44.         connection.execute(query: query) { queryResult in
  45.             if let resultSet = queryResult.asResultSet {
  46.                 // 結果の取得
  47.                 for row in resultSet.rows {
  48.                     for field in row {
  49.                         let val = field ?? ""
  50.                         Log.info("\(val)")
  51.                     }
  52.                 }
  53.             } else if let queryError = queryResult.asError {
  54.                 Log.info("queryError \(queryError)")
  55.             }
  56.         }
  57.     }
  58.     next()
  59.     
  60. }
  61. // テスト用のpublic/index.htmlを配信
  62. router.all("/static", middleware: StaticFileServer())
  63. // Add an HTTP server and connect it to the router
  64. Kitura.addHTTPServer(onPort: 8080, with: router)
  65. // Start the Kitura runloop (this call never returns)
  66. Kitura.run()




ビルドしてサーバーを起動


$ swift build
$ .build/debug/myFirstProject




/helloに適当な値をpostすると、ログに検索結果が表示されました。


ただ、この方法だと検索結果のフィールドに番号でアクセスすることになりそうです。
フィールド名でアクセスする方法を調べてみます。
関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/08/27(日) 23:15:06|
  2. swift
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
前のページ 次のページ