Symfoware

Symfowareについての考察blog

Windows Server 2012 R2にインストールしたFirebird 2.5の外部接続許可手順

Windows Server 2012 R2にFirebird 2.5.2をインストールしました。
Windows Server 2012 R2にFirebird 2.5.2をインストールする

別の端末から接続して、データベースにアクセスしてみます。


ファイアウォールの設定



Firebirdはデフォルトで3050番ポートで通信を待ち受けます。
3050番ポートに外部から接続できるよう、ファイアウォールの設定を変更します。

サーバーマネージャーの「ツール」 - 「セキュリティが強化されたWindows ファイアウォール」を選択。

356_01.png


右側の「新しい規則」をクリックします。

356_02.png


「新規の受信の規則ウィザード」が始まります。
「ポート」を選択して次へ。

356_03.png


規則の適用は「TCP」。
特定のローカルポートは「3050」を入力します。

356_04.png


「接続を許可する」を選択して次へ。

356_05.png


「ドメイン」「プライベート」「パブリック」全てにチェックがついた状態で次へ。

356_06.png


作成する規則に名前を付けます。
今回は「Firebird」としました。

356_07.png


ルールが追加されました。

356_08.png


これで設定完了です。





外部からの接続確認



別の端末から、こんなPythonのプログラムを実行してみました。


  1. # -*- coding:utf-8 -*-
  2. import fdb
  3. # コネクション作成
  4. con = fdb.connect(
  5.     dsn='192.168.1.104:C:\data\sample.fdb',
  6.     user='sysdba',
  7.     password='masterkey',
  8.     charset='UTF8'
  9. )
  10. # カーソル取得
  11. cur = con.cursor()
  12. # データの登録
  13. cur.execute("INSERT INTO test (id, name) VALUES(? ,?)", [2, 'pythonから登録'])
  14. con.commit()
  15. # データの検索
  16. cur.execute("SELECT * FROM test")
  17. for row in cur:
  18.     print("%s, %s" % (row))
  19. cur.close()
  20. con.close()




ちゃんとデータの登録、検索が行えました。


$ python sample.py
1, test_value
2, pythonから登録




テーマ:データベース - ジャンル:コンピュータ

  1. 2014/03/08(土) 21:59:30|
  2. Firebird
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Windows Server 2012 R2にFirebird 2.5.2をインストールする

Windows Server 2012 R2にFirebird 2.5.2 64bit版をインストールしてみます。


インストーラーのダウンロード



こちらからインストーラーをダウンロードします。
http://www.firebirdsql.org/en/firebird-2-5-2-upd1/

「64-bit Classic, Superclassic & Superserver」にある
「Firebird-2.5.2.26540_0_x64.exe」をダウンロードしました。

355_01.png




インストール



ダウンロードした「Firebird-2.5.2.26540_0_x64.exe」を実行します。
基本的にデフォルト設定のままインストールしました。
スクリーンショットを貼っておきます。

355_02.png

355_03.png


「I accept the agreement」を選択してNext。

355_04.png

355_05.png

355_06.png

355_07.png

355_08.png

355_09.png

355_10.png

355_11.png


「After Installation - What Next?」のチェックを外してFinish。

355_12.png

これでインストール完了です。





isqlコマンドによるデータベース作成



isqlコマンドでデータベースを作成してみます。

こちらでやったことを参考にしています。
FreeBSD 10.0 + Firebird 2.5.2 データベースファイルを作成する


デフォルトでFirebirdのインストール先は
「C:\Program Files\Firebird\Firebird_2_5」
になります。

この中の「bin」にisql等のコマンド群がありますので、
作業しやすくするためパスを通しておくと便利です。


コマンドプロンプトを起動して、パスを通します。


C:\> SET PATH=%PATH%;C:\Program Files\Firebird\Firebird_2_5\bin




isqlコマンドを実行


c:\>isql
Use CONNECT or CREATE DATABASE to specify a database




create databaseでデータベースを作成。


SQL> create database 'C:\data\sample.fdb'
CON> user 'sysdba'
CON> password 'masterkey'
CON> default character set utf8;
SQL> commit;




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


SQL> connect 'C:\data\sample.fdb'
CON> user 'sysdba'
CON> password 'masterkey';
Database: 'C:\data\test.fdb', User: sysdba




適当にテーブルを作成してデータを登録


SQL> create table test (id int, name varchar(100));
SQL> insert into test(id,name) values (1, 'test_value');
SQL> commit;




登録したデータを検索してみます。


SQL> select * from test;

         ID NAME
============ =====================
         1 test_value




quitでisqlを終了します。


SQL> quit;
C:\>





実行している様子はこんな感じです。

355_13.png


日本語文字列を登録しようとしたのですが、
データベース:UTF8
コマンドプロンプト:MS932
と文字コードが異なるためか、登録時にエラーになりました。


テーマ:データベース - ジャンル:コンピュータ

  1. 2014/03/08(土) 21:37:09|
  2. Firebird
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Firebird 2.5.2にPHPから接続する(PDO_FIREBIRD)

FreeBSD 10.0にインストールしたPHP 5からFirebirdに接続できるようにしてみます。


事前準備



FreeBSDにApacheやPHP、Firebirdをインストールしておきます。

FreeBSDのインストール
FreeBSD 10.0-RELEASEを仮想環境(UbuntuのKVM)にインストールする

Apache 2.4のインストール
FreeBSD 10.0にApache 2.4をインストールする(pkg install使用)

PHP 5のインストール(ports使用)
FreeBSD 10.0にphp5をインストールする(ports使用)

PHP 5拡張のインストール方法
FreeBSD 10.0のPHP5からMariaDBに接続する

Firebirdのインストール
FreeBSD 10.0にFirebird 2.5.2をインストールする(pkg install使用)





PHP拡張(PDO_FIREBIRD)のインストール



こちらを参考にしました。
http://www.php.net/manual/ja/ref.pdo-firebird.php

Apache, PHP 5, Firebirdがインストールしてある状態から
作業を始めました。

portsからPHP 5のインストールを行います。
/usr/ports/lang/php5-extensions/に移動して、make config実行。


# cd /usr/ports/lang/php5-extensions/
# make config




「PDO_FIREBIRD」を有効にします。

354_01.png


既にphp-extentionをインストールしたことがあるなら、一回アンインストールします。


# make clean
# make deinstall




make、make installでPHP拡張をインストールします。


# make
# make install




extensions.iniを表示して、「pdo_firebird.so」が有効になっていることを確認。


# cat /usr/local/etc/php/extensions.ini
(略)
extension=pdo_firebird.so




Apacheを再起動します。


# service apache24 restart




phpinfoを表示して「PDO_FIREBIRD」が有効になっていれば設定完了です。

354_02.png





接続テスト




ちゃんと接続できるかテストしてみます。


  1. <?php
  2. try {
  3.     // ローカルのデータベース「test.fdb」に
  4.     // ユーザー名「sysdba」、パスワード「masterkey」で接続
  5.     $db = new PDO ('firebird:dbname=localhost:/usr/local/firebird/test.fdb;charset=UTF8', 'sysdba', 'masterkey');
  6.     
  7.     echo 'Firebirdと接続成功';
  8.     // 切断
  9.     unset($db);
  10. } catch (PDOException $e) {
  11.     echo $e->getMessage();
  12. }





そっけないですが、ちゃんと接続できているようです。

354_03.png




検索サンプル



データを検索するサンプルはこんな感じになりました。


  1. <?php
  2. // ローカルのデータベース「test.fdb」に
  3. // ユーザー名「sysdba」、パスワード「masterkey」で接続
  4. $db = new PDO ('firebird:dbname=localhost:/usr/local/firebird/test.fdb;charset=UTF8', 'sysdba', 'masterkey');
  5. $stmt = $db->query('SELECT * FROM test');
  6. $rs = $stmt->fetchAll();
  7. foreach ($rs as $row) {
  8.     echo $row['ID'];
  9.     echo ':';
  10.     echo $row['NAME'];
  11.     echo '<br/>';
  12. }
  13. // 切断
  14. unset($db);




データはPythonから登録したものです。
文字化けなしでちゃんと取得できているようです。

354_04.png






名前付きパラメータを使用した検索



プリペアドステートメントを使ってみます。


  1. <?php
  2. // ローカルのデータベース「test.fdb」に
  3. // ユーザー名「sysdba」、パスワード「masterkey」で接続
  4. $db = new PDO ('firebird:dbname=localhost:/usr/local/firebird/test.fdb;charset=UTF8', 'sysdba', 'masterkey');
  5. $stmt = $db->prepare('SELECT * FROM test WHERE id = :id');
  6. $stmt->execute(array(':id' => 2));
  7. $rs = $stmt->fetchAll();
  8. foreach ($rs as $row) {
  9.     echo $row['ID'];
  10.     echo ':';
  11.     echo $row['NAME'];
  12.     echo '<br/>';
  13. }
  14. // 切断
  15. unset($db);




ちゃんと検索出来ました。

354_05.png





データの追加、更新



データの追加や更新を試してみます。


  1. <?php
  2. // ローカルのデータベース「test.fdb」に
  3. // ユーザー名「sysdba」、パスワード「masterkey」で接続
  4. $db = new PDO ('firebird:dbname=localhost:/usr/local/firebird/test.fdb;charset=UTF8', 'sysdba', 'masterkey');
  5. // データを追加
  6. $db->exec("INSERT INTO test (id, name) VALUES (3, 'テストデータ3')");
  7. // データの更新
  8. $db->exec("UPDATE test SET name = 'テスト2更新' WHERE id = 2");
  9. // 更新結果を確認
  10. $stmt = $db->query('SELECT * FROM test');
  11. $rs = $stmt->fetchAll();
  12. foreach ($rs as $row) {
  13.     echo $row['ID'];
  14.     echo ':';
  15.     echo $row['NAME'];
  16.     echo '<br/>';
  17. }
  18. // 切断
  19. unset($db);





ちゃんと追加や更新が行えました。

354_06.png





名前付きパラメータを使用した追加、更新



名前付きパラメーターを使用して、データの追加や更新を行なってみます。


  1. <?php
  2. // ローカルのデータベース「test.fdb」に
  3. // ユーザー名「sysdba」、パスワード「masterkey」で接続
  4. $db = new PDO ('firebird:dbname=localhost:/usr/local/firebird/test.fdb;charset=UTF8', 'sysdba', 'masterkey');
  5. // データを追加
  6. $stmt = $db->prepare("INSERT INTO test (id, name) VALUES (:id, :name)");
  7. $stmt->execute(array(':id' => 4, ':name' => 'テストデータ4'));
  8. // データの更新
  9. $stmt = $db->prepare("UPDATE test SET name = :name WHERE id = :id");
  10. $stmt->execute(array(':id' => 2, ':name' => 'テスト2再更新'));
  11. // 更新結果を確認
  12. $stmt = $db->query('SELECT * FROM test');
  13. $rs = $stmt->fetchAll();
  14. foreach ($rs as $row) {
  15.     echo $row['ID'];
  16.     echo ':';
  17.     echo $row['NAME'];
  18.     echo '<br/>';
  19. }
  20. // 切断
  21. unset($db);




狙い通りの結果が得られました。

354_07.png


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

  1. 2014/03/08(土) 20:48:08|
  2. Firebird
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Firebird 2.5.2にPythonから接続する(fdb使用)

FreeBSDにFirebirdをインストールしてみました。
FreeBSD 10.0にFirebird 2.5.2をインストールする(pkg install使用)

Ubuntu + Pythonから接続してみます。


fdbパッケージ



以前はkinterbasdbというパッケージを使用しました。
Debian FirebirdにPythonで接続する(kinterbasdb)

公式ホームページを見てみると、kinterbasdbはobsolete(廃止)されたようです。
Python Driver

代わりに、fdbパッケージを使用すれば良いようです。
https://pypi.python.org/pypi/fdb/

こちらを参考に進めていきます。
http://pythonhosted.org/fdb/



fdbパッケージのインストール



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


$ sudo easy_install fdb




pythonコンソールで、import fdbしてエラーが出なければ
インストール成功です。


$ python
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import fdb
>>>







データベースへの接続




データベースに接続し、テーブルを作成。
適当なサンプルデータを登録して、データを検索してみます。


  1. # -*- coding:utf-8 -*-
  2. import fdb
  3. # コネクション作成
  4. con = fdb.connect(
  5.     dsn='192.168.1.101:/usr/local/firebird/test.fdb',
  6.     user='sysdba',
  7.     password='masterkey',
  8.     charset='UTF8'
  9. )
  10. # カーソル取得
  11. cur = con.cursor()
  12. # サンプルテーブル作成
  13. cur.execute("CREATE TABLE fb_test(id INT, name VARCHAR(100), entry TIMESTAMP)")
  14. con.commit()
  15. # データの登録
  16. cur.execute("INSERT INTO fb_test(id, name, entry) VALUES(1, 'テスト1', '2001/02/03 04:05')")
  17. cur.execute("INSERT INTO fb_test(id, name, entry) VALUES(2, 'テスト2', current_timestamp)")
  18. con.commit()
  19. # 検索
  20. cur.execute("SELECT * FROM fb_test")
  21. for row in cur:
  22.     print("%s, %s, %s" %(row))
  23. ur.close()
  24. con.close()




テーブルを作成した後、一旦commitしないと、INSERT時「Table unknown」の
エラーが発生します。

日付型は、Pythonのdatetimeに変換してくれるようです。
また、現在時刻の指定には「current_timestamp」が使用出来ます。




プレースフォルダ



プレースフォルダを使用しての登録や検索を試してみます。


  1. # -*- coding:utf-8 -*-
  2. import fdb
  3. import datetime
  4. # コネクション作成
  5. con = fdb.connect(
  6.     dsn='192.168.1.101:/usr/local/firebird/test.fdb',
  7.     user='sysdba',
  8.     password='masterkey',
  9.     charset='UTF8'
  10. )
  11. # カーソル取得
  12. cur = con.cursor()
  13. # データの削除
  14. cur.execute("DELETE FROM fb_test")
  15. # データの登録
  16. id = 1
  17. name = 'テストデータ'
  18. entry = datetime.datetime(2010, 1, 2, 3, 4)
  19. cur.execute("INSERT INTO fb_test(id, name, entry) VALUES (?, ?, ?)", (id, name, entry))
  20. id = 2
  21. name = 'テストデータ2'
  22. entry = '2013-04-05 12:34'
  23. cur.execute("INSERT INTO fb_test(id, name, entry) VALUES (?, ?, ?)", (id, name, entry))
  24. # 検索
  25. cur.execute("SELECT * FROM fb_test")
  26. for row in cur:
  27.     print("%s, %s, %s" %(row))
  28. cur.close()
  29. con.close()




日付型はdatetimeをそのまま渡しても良いし、文字列を渡してもよいようです。





結果を辞書型で取得



結果の行を辞書型で取得したい場合は、fetchonemapを使用すれば良いようです。
FDB Reference


  1. # -*- coding:utf-8 -*-
  2. import fdb
  3. import datetime
  4. # コネクション作成
  5. con = fdb.connect(
  6.     dsn='192.168.1.101:/usr/local/firebird/test.fdb',
  7.     user='sysdba',
  8.     password='masterkey',
  9.     charset='UTF8'
  10. )
  11. # カーソル取得
  12. cur = con.cursor()
  13. # データの削除
  14. cur.execute("DELETE FROM fb_test")
  15. # データの登録
  16. id = 1
  17. name = 'テストデータ'
  18. entry = datetime.datetime(2010, 1, 2, 3, 4)
  19. cur.execute("INSERT INTO fb_test(id, name, entry) VALUES (?, ?, ?)", (id, name, entry))
  20. id = 2
  21. name = 'テストデータ2'
  22. entry = '2013-04-05 12:34'
  23. cur.execute("INSERT INTO fb_test(id, name, entry) VALUES (?, ?, ?)", (id, name, entry))
  24. # 検索
  25. cur.execute("SELECT * FROM fb_test")
  26. row = cur.fetchonemap()
  27. while row:
  28.     print("%s, %s, %s" % (row['ID'], row['NAME'], row['ENTRY']))
  29.     row = cur.fetchonemap()
  30. cur.close()
  31. con.close()








BLOBへ画像登録



BLOB列を持つテープルを作成し、画像データを登録してみます。
こちらを参考にしました。
Stream BLOBs


事前に登録用のテーブルを作成しておきます。


CREATE TABLE fb_test(image BLOB SUB_TYPE BINARY)




プログラムはこうなりました。
insert時、ファイルストリームを直接渡せば良いようです。


  1. # -*- coding:utf-8 -*-
  2. import fdb
  3. import datetime
  4. # コネクション作成
  5. con = fdb.connect(
  6.     dsn='192.168.1.101:/usr/local/firebird/test.fdb',
  7.     user='sysdba',
  8.     password='masterkey',
  9.     charset='UTF8'
  10. )
  11. # カーソル取得
  12. cur = con.cursor()
  13. # データの削除
  14. cur.execute("DELETE FROM fb_test")
  15. # 画像データの登録
  16. f = open('Lenna.jpg', 'rb')
  17. cur.execute('INSERT INTO fb_test (image) values (?)',[f])
  18. f.close()
  19. # 検索して復元
  20. cur.execute("SELECT image FROM fb_test")
  21. img = cur.fetchone()[0]
  22. f = open('result.jpg', 'wb')
  23. f.write(img)
  24. f.close()
  25. cur.close()
  26. con.close()





実行してみると、ちゃんと登録した画像が復元出来ました。

353_01.png

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

  1. 2014/03/08(土) 18:57:55|
  2. Firebird
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Firebird embedded 2.5.2で接続した時のアクセス権メモ

Firebirdサーバーをインストールしたり、embedded版を触ってみたりしました。

FreeBSD 10.0にFirebird 2.5.2をインストールする(pkg install使用)
Firebird embeddedにJava1.7 + Jaybird + Ubuntuで接続する
WindowsでFirebird embeddedにJava1.7 + Jaybirdから接続する

良い機会なので、embedded版で接続した時のアクセス権について調べてみました。



環境



現在の手持ちの環境は、

FreeBSD + Firebird Server
Ubuntu + Firebird embedded
Windows + Firebird embedded

の3つです。

「FreeBSD」でデータベースファイルを作成して、そのファイルを他の環境で使ってみます。




データベースの作成(FreeBSD)



FreeBSDで、データベースファイルの作成を行います。
合わせて、「freebsd」というテーブルを作成してデータを入れておきました。

isql-fbで作業します。


# isql-fb
Use CONNECT or CREATE DATABASE to specify a database

SQL> create database '/usr/local/firebird/test.fdb'
CON> user 'sysdba'
CON> password 'masterkey'
CON> default character set utf8;
SQL> commit;

SQL> connect '/usr/local/firebird/test.fdb'
CON> user 'sysdba'
CON> password 'masterkey';
Database: '/usr/local/firebird/test.fdb', User: sysdba

SQL> create table freebsd (id int, name varchar(100));
SQL> commit;

SQL> insert into freebsd (id,name) values (1, 'freebsd');
SQL> commit;

SQL> quit;




出来上がったtest.fdbをUbuntuにコピーしました。






Ubuntu embeddedからの操作



Ubuntuにコピーしたtest.fdbに接続し、テーブルを検索してみます。


  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. public class FBEmbedded {
  6.     
  7.     public static void main(String[] args) throws Exception {
  8.         
  9.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  10.         
  11.         try (Connection con = DriverManager.getConnection(url);
  12.                 Statement stmt = con.createStatement()) {
  13.                         
  14.             // データを検索
  15.             ResultSet rs = stmt.executeQuery("select * from freebsd");
  16.             
  17.             while(rs.next()) {
  18.                 System.out.println(rs.getString("name"));
  19.             }
  20.         }
  21.     }
  22. }





実行すると、こんなエラーが発生しました。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544352.
no permission for read/select access to TABLE FREEBSD
    at org.firebirdsql.jdbc.AbstractStatement.executeQuery(AbstractStatement.java:228)
    at sample.FBEmbedded.main(FBEmbedded.java:18)
Caused by: org.firebirdsql.gds.GDSException: no permission for read/select access to TABLE FREEBSD
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_dsql_prepare(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscDsqlPrepare(BaseGDSImpl.java:576)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscDsqlPrepare(Unknown Source)
    at org.firebirdsql.gds.impl.GDSHelper.prepareStatement(GDSHelper.java:190)
    at org.firebirdsql.jdbc.AbstractStatement.prepareFixedStatement(AbstractStatement.java:1441)
    at org.firebirdsql.jdbc.AbstractStatement.internalExecute(AbstractStatement.java:1423)
    at org.firebirdsql.jdbc.AbstractStatement.executeQuery(AbstractStatement.java:219)
    ... 1 more




embeddedで接続するときは、IDとパスワードは不要なはずです。
Serverで作成したデータベースに接続するときには必要なのかと思い、
ユーザー名:SYSDBA、パスワード:masterkeyを指定して接続しようとするとこんなエラー。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544653.
cannot attach to password database
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:123)
    at org.firebirdsql.jdbc.AbstractDriver.connect(AbstractDriver.java:126)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at sample.FBEmbedded.main(FBEmbedded.java:14)
Caused by: org.firebirdsql.gds.GDSException: cannot attach to password database
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_attach_database(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscAttachDatabase(BaseGDSImpl.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscAttachDatabase(Unknown Source)
    at org.firebirdsql.jca.FBManagedConnection.<init>(FBManagedConnection.java:105)
    at org.firebirdsql.jca.FBManagedConnectionFactory.createManagedConnection(FBManagedConnectionFactory.java:490)
    at org.firebirdsql.jca.FBStandAloneConnectionManager.allocateConnection(FBStandAloneConnectionManager.java:69)
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:120)
    ... 4 more




パスワードデータベースに接続できないとのこと。

調べてみると、こんなページを見つけました。
no permission for read/select access to table RDB$XXXX by user SYSDBA

なるほど、作成したテーブルに権限をつければいいのか。

FreeBSDに戻って、作成したテーブルにPUBLICなアクセス権を付与します。


SQL> GRANT ALL ON freebsd TO PUBLIC;
SQL> commit;




test.fdbファイルをUbuntuに再度コピーして、以下のプログラムを実行します。


  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. public class FBEmbedded {
  6.     
  7.     public static void main(String[] args) throws Exception {
  8.         
  9.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  10.         
  11.         try (Connection con = DriverManager.getConnection(url);
  12.                 Statement stmt = con.createStatement()) {
  13.             // データを登録
  14.             stmt.execute("insert into freebsd(id, name) values (2, 'from ubuntu')");
  15.             
  16.             // データを検索
  17.             ResultSet rs = stmt.executeQuery("select * from freebsd");
  18.             
  19.             while(rs.next()) {
  20.                 System.out.println(rs.getString("name"));
  21.             }
  22.             
  23.             // テーブルを作成
  24.             stmt.execute("create table ubuntu(id int, name varchar(100))");
  25.             
  26.             // 作成したテーブルにデータ登録
  27.             stmt.execute("insert into ubuntu(id, name) values (1, 'from ubuntu')");
  28.             
  29.             // データを検索
  30.             rs = stmt.executeQuery("select * from ubuntu");
  31.             
  32.             while(rs.next()) {
  33.                 System.out.println(rs.getString("name"));
  34.             }
  35.             
  36.         }
  37.     }
  38. }




ちゃんと登録、検索が行えました。
また、新規テーブルの作成が行えることも確認出来ました。






Windows embeddedからの操作



Ubuntuでデータの登録やテーブルの作成を行ったtest.fdbファイルを
Windowsにコピーします。

こんなプログラムを作成して実行してみました。



  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. public class Sample {
  6.     
  7.     public static void main(String... args) throws Exception {
  8.         String url = "jdbc:firebirdsql:embedded:C:\\Develop\\fbemb\\test.fdb?encoding=UTF8";
  9.         
  10.         try (Connection con = DriverManager.getConnection(url);
  11.                 Statement stmt = con.createStatement()) {
  12.             
  13.         
  14.         // FreeBSDで作成したテーブルにデータを登録
  15.         stmt.execute("insert into freebsd(id, name) values (3, 'from windows')");
  16.         
  17.         // FreeBSDで作成したテーブルのデータを検索
  18.         ResultSet rs = stmt.executeQuery("select * from freebsd");
  19.         
  20.         while(rs.next()) {
  21.             System.out.println(rs.getString("name"));
  22.         }
  23.         
  24.         
  25.         // Ubuntuで作成したテーブルにデータを登録
  26.         stmt.execute("insert into ubuntu(id, name) values (2, 'from windows')");
  27.         
  28.         // Ubuntuで作成したテーブルのデータを検索
  29.         rs = stmt.executeQuery("select * from ubuntu");
  30.         
  31.         while(rs.next()) {
  32.             System.out.println(rs.getString("name"));
  33.         }
  34.         
  35.         }
  36.     }
  37.     
  38. }





実行してみると、FreeBSDで作成したテーブルには
データの追加、検索が行えますが、
Ubuntuで作成したテーブルへのアクセスでエラーになります。


from freebsd
from windows
from ubuntu
Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544352.
no permission for insert/write access to TABLE UBUNTU
        at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:869)
        at Sample.main(Sample.java:27)
Caused by: org.firebirdsql.gds.GDSException: no permission for insert/write access to TABLE UBUNTU
        at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_dsql_prepare(Native Method)
        at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscDsqlPrepare(BaseGDSImpl.java:576)
        at org.firebirdsql.gds.impl.GDSHelper.prepareStatement(GDSHelper.java:190)
        at org.firebirdsql.jdbc.AbstractStatement.prepareFixedStatement(Abstract
Statement.java:1441)
        at org.firebirdsql.jdbc.AbstractStatement.internalExecute(AbstractStatement.java:1423)
        at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:867)
        ... 1 more





embeddedで接続して作成したテーブルは、他の端末のembedded接続でも
操作できるだろと思っていたのですが、そうではない様子。

Ubuntuで作成したテーブルにアクセス権を付与します。


  1. package sample;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class FBEmbedded {
  7.     
  8.     public static void main(String[] args) throws Exception {
  9.         
  10.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  11.         
  12.         try (Connection con = DriverManager.getConnection(url);
  13.                 Statement stmt = con.createStatement()) {
  14.             
  15.             // アクセス権付与
  16.             stmt.execute("GRANT ALL ON ubuntu TO PUBLIC");
  17.             
  18.         }
  19.     }
  20. }




改めてWindowsで実行すると、ちゃんとubuntuテーブルに対しても
データの登録、検索が行えました。






スキーマの変更



再びUbuntuに戻ります。
今度はデータの登録、検索ではなくテーブルに対して列の追加を行なってみます。


  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.Statement;
  4. public class FBEmbedded {
  5.     
  6.     public static void main(String[] args) throws Exception {
  7.         
  8.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  9.         
  10.         try (Connection con = DriverManager.getConnection(url);
  11.                 Statement stmt = con.createStatement()) {
  12.             
  13.             // FreeBSDで作成したテーブルに列追加
  14.             stmt.execute("ALTER TABLE freebsd ADD ubuntu_col VARCHAR(25)");
  15.         }
  16.     }
  17. }




こんなエラーが発生しました。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544351. unsuccessful metadata update
can't format message 8:29 -- message file /opt/firebird/firebird.msg not found
null
no permission for control access to TABLE FREEBSD
    at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:869)
    at sample.FBEmbedded.main(FBEmbedded.java:17)
Caused by: org.firebirdsql.gds.GDSException: unsuccessful metadata update
can't format message 8:29 -- message file /opt/firebird/firebird.msg not found
null
no permission for control access to TABLE FREEBSD
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_dsql_execute2(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscDsqlExecute2(BaseGDSImpl.java:447)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscDsqlExecute2(Unknown Source)
    at org.firebirdsql.gds.impl.GDSHelper.executeStatement(GDSHelper.java:227)
    at org.firebirdsql.jdbc.AbstractStatement.internalExecute(AbstractStatement.java:1424)
    at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:867)
    ... 1 more





ここがヒントになりました。
Alter Table Of Other User in Firebird


A table can be altered by its creator, the SYSDBA user,
and any users with operating system superuser privileges.




ひょっとして、rootになって実行すればいいのでは?
こんなコマンドで試してみました。


$ sudo -s
# cd workspace/fbsample/
# export LD_LIBRARY_PATH=/home/baranche/workspace/fbsample/embed
# java -cp .:./bin:./lib/jaybird-full-2.2.4.jar -Djava.library.path=/home/baranche/workspace/fbsample/lib sample.FBEmbedded




エラー無しで処理終了。
これでFreeBSDで作成したテーブルにUbuntu + embeddedな接続から
カラムの追加が行えました。



でも、rootでfdbファイルに接続した後、通常ユーザーで接続しようとすると、
こんなエラーになります。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544373.
operating system directive open failed
null
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:123)
    at org.firebirdsql.jdbc.AbstractDriver.connect(AbstractDriver.java:126)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:243)
    at sample.FBEmbedded.main(FBEmbedded.java:14)
Caused by: org.firebirdsql.gds.GDSException: operating system directive open failed
null
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_attach_database(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscAttachDatabase(BaseGDSImpl.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscAttachDatabase(Unknown Source)
    at org.firebirdsql.jca.FBManagedConnection.<init>(FBManagedConnection.java:105)
    at org.firebirdsql.jca.FBManagedConnectionFactory.createManagedConnection(FBManagedConnectionFactory.java:490)
    at org.firebirdsql.jca.FBStandAloneConnectionManager.allocateConnection(FBStandAloneConnectionManager.java:69)
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:120)
    ... 4 more





test.fdbファイルのアクセス権が変わった?と思ったのですが変化なし。

随分ハマったのですが、embeddedで接続した時どうやら、ロックファイルが作成されるようです。
Operating System Directive Open failed -- Permission denied

調べてみると、
「/tmp/firebird/fb_init」
というそれらしいファイルがありました。


$ sudo rm -fr /tmp/firebird/fb_init



としてファイルを削除すると、再び通常ユーザーでのアクセスが可能になりました。






Windowsでの動作



WindowsではAdministrator権限で実行すればOKと思ったのですがエラーになります。


no permission for control access to TABLE FREEBSD




改めてこちらを見てみます。
Alter Table Of Other User in Firebird

「RDB$ADMIN」というキーワードーが出てきました。


Security Hardening

No SYSDBA Auto-mapping (Windows)の項目を見てみると、


ALTER ROLE RDB$ADMIN SET AUTO ADMIN MAPPING



を実行すれば良さそうです。


FreeBSDに戻り、クエリを実行します。


SQL> ALTER ROLE RDB$ADMIN DROP AUTO ADMIN MAPPING;
SQL> commit;




FreeBSDにあるtest.fdbファイルをWindowsにコピーしてプログラムを
再度実行してみたのですがやはりエラーになります。

なにかオペレーションが足りないんだと思いますが、解決できませんでした。






まとめ



Firebird Serverで作成したテーブルをEmbeddedで読み書きしたい時は、


GRANT ALL ON [テーブル名] TO PUBLIC



を作成元で忘れず実行しておく。


スキーマの変更はrootユーザーで実行する。
その時、tmpにロックファイルがroot権限で作成されるので
rootユーザーでアクセス後は忘れず権限を戻すかロックファイル自体を削除する。

テーマ:データベース - ジャンル:コンピュータ

  1. 2014/03/06(木) 23:18:04|
  2. Firebird
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ