万年素人からHackerへの道

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

  • ・資産運用おすすめ
    10万円は1000円くらい利益
    • ・寄付お願いします
      YENTEN:YYzNPzdsZWqr5THWAdMrKDj7GT8ietDc2W
      BitZenny:ZfpUbVya8MWQkjjGJMjA7P9pPkqaLnwPWH
      c0ban:8KG95GXdEquNpPW8xJAJf7nn5kbimQ5wj1

    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'.

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