万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

Boo Language Advent Calendar 2012 10日目 Title:「Sqlite+Boo連携! in Unity リベンジその1」

URL: http://atnd.org/events/34622

昨日のアドベントカレンダーでは失敗したので、再度トライ。

@atsushienoさんんがコメント下さいました。
ここでバグ報告されてます。
https://bugzilla.xamarin.com/show_bug.cgi?id=2128
Mono.Data.Sqliteは実装が古くて動かない部分がり、DataTableを使うと必ずバグるっぽいです。

薦めて下さった「sqlite-net」を試してみます!
github: https://github.com/praeclarum/sqlite-net

git clone https://github.com/praeclarum/sqlite-net

そして、SQLite.csを「Plugins」に突っ込む。
dllじゃないですね。多分これだけでOK?

書き換えたコードです。
しかしエラー出ます。わかりません。。。。

import System
import System.Data from System.Data
import SQLite;
#import Mono.Data.Sqlite

class SqliteTest (MonoBehaviour):

    def Awake ():
        Debug.Log('If this test works, you should get:')
        Debug.Log('Data 1: 5')

        Debug.Log('Data 2: Mono')
        Debug.Log('create SqliteConnection...')
#        dbcon as SqliteConnection = SqliteConnection()
#        connectionString as string = 'URI=file:SqliteTest.db'
        connectionString as string = 'SqliteTest.db'
        dbcon as SQLiteConnection = SQLiteConnection(connectionString, false)

#        connectionString as string = 'Data Source=file:SqliteTest.db'
        Debug.Log('setting ConnectionString using: ' + connectionString)
        #dbcon.ConnectionString = connectionString
        Debug.Log('open the connection...')
#        dbcon.Open()
        Debug.Log('create SqliteCommand to CREATE TABLE MONO_TEST')
#        dbcmd as SqliteCommand = SqliteCommand()
        dbcmd as SQLiteCommand = SQLiteCommand(dbcon)
#        dbcmd.Connection = dbcon
        dbcmd.CommandText = 'CREATE TABLE MONO_TEST ( ' + 'NID INT, ' + 'NDESC TEXT )'
        Debug.Log('execute command...')
        dbcmd.ExecuteNonQuery()
        Debug.Log('set and execute command to INSERT INTO MONO_TEST')
        dbcmd.CommandText = 'INSERT INTO MONO_TEST  ' + '(NID, NDESC )' + 'VALUES(5,\'Mono\')'
        dbcmd.ExecuteNonQuery()
        Debug.Log('set command to SELECT FROM MONO_TEST')
        dbcmd.CommandText = 'SELECT * FROM MONO_TEST'
#        reader as SqliteDataReader
        reader as IDataReader
        Debug.Log('execute reader...')
#        reader = dbcmd.ExecuteReader()
        reader = dbcmd.ExecuteQuery[of IDataReader]()
        Debug.Log('read and display data...')
        while reader.Read():
            Debug.Log('Data 1: ' + reader[0].ToString())
            Debug.Log('Data 2: ' + reader[1].ToString())

        Debug.Log('read and display data using DataAdapter...')
#        adapter as SqliteDataAdapter = SqliteDataAdapter('SELECT * FROM MONO_TEST', connectionString)
        dataset as DataSet = DataSet()
#        adapter.Fill(dataset)

        dbcon.CreateCommand('SELECT * FROM MONO_TEST', connectionString, dataset)
        for myTable as DataTable in dataset.Tables:
            for myRow as DataRow in myTable.Rows:
                for myColumn as DataColumn in myTable.Columns:
                    Debug.Log(myRow[myColumn])

        Debug.Log('clean up...')
        dataset.Dispose()
#        adapter.Dispose()
        dbcon.Dispose()
        reader.Close()
#        dbcmd.Dispose()
        dbcon.Close()
        Debug.Log('Done.')



ここから解説〜〜〜

まず、これがはまりました。

dbcon as SQLiteConnection = SQLiteConnection(connectionString, false)

第二引数をきちんと書かないといけません。
デフォルト引数がBooにないのか書かないとできませんでした。

internalでコンストラクタが書かれており、
http://msdn.microsoft.com/ja-jp/library/7c5ka91b(v=vs.80).aspx
によると、同じアセンブリしかアクセス出来ないみたいなので、
Booだと無理?かわからないが、

'SQLite.SQLiteCommand.constructor(SQLite.SQLiteConnection)' is inaccessible due to its protection level.

と怒られるので、
勝手にSQLiteCommandクラスのコンストラクタの型変えましたw

	public partial class SQLiteCommand
	{
		SQLiteConnection _conn;
		private List<Binding> _bindings;

		public string CommandText { get; set; }

//		internal SQLiteCommand (SQLiteConnection conn)
		public SQLiteCommand (SQLiteConnection conn)
		{
			_conn = conn;
			_bindings = new List<Binding> ();
			CommandText = "";
		}
connectionString as string = 'URI=file:SqliteTest.db'

これだと、ファイル名が「URI=file:SqliteTest.db」になってしまうので、「SqliteTest.db」だけにしました。

SQLiteCommandにDisposeはないのかな?

reader = dbcmd.ExecuteQuery[of IDataReader]()

の部分で、↓のエラーになります・・・

MissingMethodException: Cannot create an abstract class 'System.Data.IDataReader'.

時間がなくてできませんでした・・。次またリベンジします。