(※warapperDLL未使用)
はじめに
新しいMT4のエンコードを調べてみたら以下の通りとなりまいた。- MetaEditorが新規に作成するmq4,mqhは、ANSI(Shift_JIS)
- UNICODE(UTF-16BOM)で作成したmq4.mqhでもコンパイル出来た。
- 内部は、UNICODE(UTF-16BOM)
- logファイルは、ANSI(Shift_JIS)
流れとしては、mq4(ANSI or UNICODE)→MT4(UNICODE)→SQLite3(UTF-8)→MT4(UNICODE)→output(ANSI)となります。
また、MQL5フォームに『SQL and MQL5: Working with SQLite Database』という記事があったのですが、使用することができませんでした。そのため、この記事を参考にコンパクトな物を作ることにしました。
コード
ココからDLすることが出来ます。(sqlite3.mqh test.mq4 sqlite3.dll )//+------------------------------------------------------------------+ //| SQLite3.mqh | //+------------------------------------------------------------------+ #define PTR int //32bit:int 64bit:long? #define sqlite3_stmt PTR #define sqlite3 PTR #define PTRPTR PTR #define SQLITE_OK 0 /* Successful result */ #define SQLITE_ERROR 1 /* SQL error or missing database */ #define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ #define SQLITE_PERM 3 /* Access permission denied */ #define SQLITE_ABORT 4 /* Callback routine requested an abort */ #define SQLITE_BUSY 5 /* The database file is locked */ #define SQLITE_LOCKED 6 /* A table in the database is locked */ #define SQLITE_NOMEM 7 /* A malloc() failed */ #define SQLITE_READONLY 8 /* Attempt to write a readonly database */ #define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */ #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* The database disk image is malformed */ #define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */ #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ #define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ #define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ #define SQLITE_MISMATCH 20 /* Data type mismatch */ #define SQLITE_MISUSE 21 /* Library used incorrectly */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_ROW 100 /* sqlite_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite_step() has finished executing */ #import "sqlite3.dll" //int sqlite3_open(const uchar &filename[],sqlite3 &paDb); int sqlite3_open16(string filename,sqlite3 &paDb); int sqlite3_close(sqlite3 aDb); //int sqlite3_prepare(sqlite3 aDb,const char &sql[],int nByte,sqlite3_stmt &pStmt,PTRPTR pzTail); //int sqlite3_prepare16(sqlite3 aDb,string sql,int nByte,sqlite3_stmt &pStmt,PTRPTR pzTail); int sqlite3_prepare16_v2(sqlite3 aDb,string sql,int nByte,sqlite3_stmt &pStmt,PTRPTR pzTail); int sqlite3_exec(sqlite3 aDb,const char &sql[],PTR acallback,PTR apvoid,PTRPTR errmsg); int sqlite3_step(sqlite3_stmt apstmt); int sqlite3_finalize(sqlite3_stmt apstmt); int sqlite3_reset(sqlite3_stmt apstmt); int sqlite3_errcode(sqlite3 db); int sqlite3_extended_errcode(sqlite3 db); //const PTR sqlite3_errmsg(sqlite3 db); const string sqlite3_errmsg16(sqlite3 db); int sqlite3_bind_null(sqlite3_stmt apstmt,int icol); int sqlite3_bind_int(sqlite3_stmt apstmt,int icol,int a); int sqlite3_bind_int64(sqlite3_stmt apstmt,int icol,long a); int sqlite3_bind_double(sqlite3_stmt apstmt,int icol,double a); //int sqlite3_bind_text(sqlite3_stmt apstmt,int icol,char &a[],int len,PTRPTR destr); int sqlite3_bind_text16(sqlite3_stmt apstmt,int icol,string a,int len,PTRPTR destr); //int sqlite3_bind_blob(sqlite3_stmt apstmt,int icol,uchar &a[],int len,PTRPTR destr); const PTR sqlite3_column_name(sqlite3_stmt apstmt,int icol); int sqlite3_column_count(sqlite3_stmt apstmt); int sqlite3_column_type(sqlite3_stmt apstmt,int acol); int sqlite3_column_bytes(sqlite3_stmt apstmt,int acol); int sqlite3_column_int(sqlite3_stmt apstmt,int acol); long sqlite3_column_int64(sqlite3_stmt apstmt,int acol); double sqlite3_column_double(sqlite3_stmt apstmt,int acol); //const PTR sqlite3_column_text(sqlite3_stmt apstmt,int acol); string sqlite3_column_text16(sqlite3_stmt apstmt, int acol); const PTR sqlite3_column_blob(sqlite3_stmt apstmt,int acol); #import class CSQLite3{ public: sqlite3 sdb; sqlite3_stmt stmt; CSQLite3(){}; CSQLite3(string file_name); ~CSQLite3(){if(stmt){finalize(); sqlite3_close (sdb);}}; void db_set(string file_name); //ファイル名のセット int reset(); //ステートメントの初期化 int finalize(); //ステートメントの解放 void db_close(){sqlite3_close (sdb);} int execute(string sql); //入出力のないクエリーの実行 int prepare(string sql); //入出力のあるクエリーの実行 int col_count(); //列数の取得 bool next_row(); //次の行を取得(true:あり false:なし) int bind_text(int col,string txt); //文字データの入力 int bind_int(int col,int integer); //整数値の入力 int bind_double(int col, double dbl); //Doubule値の入力 int get_int(int col); //整数値の出力 double get_double(int col); //Doubule値の出力 string get_text(int col); //文字データの出力 void errmsg(); //エラーメッセージをプリント }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CSQLite3::CSQLite3(string file_name){ if(file_name != "")db_set(file_name); } void CSQLite3::db_set(string file_name){ int res = sqlite3_open16 (file_name, sdb); if (res != SQLITE_OK) errmsg(); } //+-----------------------------------------------------------------+ // int CSQLite3::reset(); // ※ステートメントのリセット //+-----------------------------------------------------------------+ int CSQLite3::reset(){ int ret = 0; if(stmt)ret = sqlite3_reset(stmt); return(ret); } //+-----------------------------------------------------------------+ // int CSQLite3::finalize(); // ※ステートメントの解放 //+-----------------------------------------------------------------+ int CSQLite3::finalize(){ int ret = 0; if(stmt){ ret = sqlite3_finalize (stmt); stmt = 0; } return(ret); } //+------------------------------------------------------------------+ // int CSQLite3::execute(string sql) // ※入出力のないクリエ―の実行 // sql : クエリー //+------------------------------------------------------------------+ int CSQLite3::execute(string sql){ int sq,res; uchar qr[]; sq = StringToCharArray(sql,qr); ArrayResize(qr,sq); if(stmt)reset(); res = sqlite3_exec (sdb, qr, NULL, NULL, NULL); return(res); } //+-----------------------------------------------------------------+ // int CSQLite3::prepare(string sql); // ※入出力のあるクリエーの実行。 // ※反復処理は、(next_row,get_col)を使用。 // ※finalize()を使用し解放をおこなう。 // sql : クエリー //+------------------------------------------------------------------+ int CSQLite3::prepare(string sql){ int res; if(stmt)finalize(); res = sqlite3_prepare16_v2(sdb, sql,StringLen(sql)*2 , stmt, NULL); return(res); } //+------------------------------------------------------------------+ // int CSQLite3::colum_count (); // ※列数を返す。 //+------------------------------------------------------------------+ int CSQLite3::col_count(){ return(sqlite3_column_count (stmt)); } //+------------------------------------------------------------------+ // bool CSQLite3::next_row (); // ※次の行を取得する 。(true:あり false:なし) //+------------------------------------------------------------------+ bool CSQLite3::next_row (){ if(!stmt)return(false); int ret = 0; ret = sqlite3_step (stmt); return (ret == SQLITE_ROW ? true : false); } //+------------------------------------------------------------------+ // bind_?? (); // ※値を入力 //+-------------------------------------------------------------------+ //文字データ int CSQLite3::bind_text(int col,string txt){ int ret = 0; ret = sqlite3_bind_text16(stmt,col,txt,StringLen(txt)*2,0); return (ret); } //整数値 int CSQLite3::bind_int(int col,int integer){ int ret = 0; ret = sqlite3_bind_int(stmt,col,integer); return (ret); } //double値 int CSQLite3::bind_double(int col, double dbl){ int ret = 0 ; ret = sqlite3_bind_double(stmt,col,dbl); return (ret); } //+------------------------------------------------------------------+ // column_?? (); // ※値を取得 //+-------------------------------------------------------------------+ //整数値 int CSQLite3::get_int(int col){ int date = 0 ; date = sqlite3_column_int (stmt, col); return (date); } //double値 double CSQLite3::get_double(int col){ double date = 0.0; date = sqlite3_column_double (stmt, col); return(date); } //文字データ string CSQLite3::get_text(int col){ string date = ""; date = sqlite3_column_text16(stmt, col); return(date); } //+------------------------------------------------------------------+ // Errmsg(); // ※エラーメッセージをプリント //+-------------------------------------------------------------------+ void CSQLite3::errmsg(){ Print(sqlite3_errmsg16(sdb)); }/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
使用例(サンプル)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//+------------------------------------------------------------------+ //| SQLite3test.mq4 | //| Copyright 2012, MetaQuotes Software Corp. | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright 2012, MetaQuotes Software Corp." #property link "http://www.metaquotes.net" #property show_inputs #include <sqlite3.mqh> input string dbns="C:\Testdb.db";//データベース名(フルパス) //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start(){ string sql = ""; int i; //インスタンス CSQLite3 sqlite(dbns); //テーブルの作成 sql = "CREATE TABLE IF NOT EXISTS `Test` (`id` INTEGER, `time` TEXT, `open_price` DOUBLE)"; if(sqlite.execute(sql)!= SQLITE_OK)sqlite.errmsg(); //入力 sql = "INSERT INTO 'Test' VALUES (?,?,?)"; //トランザクション if(sqlite.execute("BEGIN")!=SQLITE_OK)sqlite.errmsg(); for(i=0;i<Bars;i++){ if(sqlite.prepare(sql)!=SQLITE_OK)sqlite.errmsg(); if(sqlite.bind_int(1,Bars-i)!=SQLITE_OK)sqlite.errmsg(); if(sqlite.bind_text(2,TimeToStr(Time[i]))!=SQLITE_OK)sqlite.errmsg(); if(sqlite.bind_double(3,Open[i])!=SQLITE_OK)sqlite.errmsg(); sqlite.next_row(); } //トランザクション終了 if(sqlite.execute("COMMIT")!=SQLITE_OK)sqlite.errmsg(); //ステートメントの解法 sqlite.finalize(); //出力 sql = "SELECT COUNT(*) FROM 'Test'"; if(sqlite.prepare(sql)!=SQLITE_OK)sqlite.errmsg(); sqlite.next_row(); Print("Bars=",IntegerToString(Bars)," データベース内のデータ数=",sqlite.get_text(0)); //ステートメントの解法 sqlite.finalize(); //抽出 sql = "SELECT * FROM 'Test'" ; if(sqlite.prepare(sql)!=SQLITE_OK)sqlite.errmsg(); while(sqlite.next_row()){ Print(IntegerToString( sqlite.get_int(0))," : ", sqlite.get_text(1)," : ", DoubleToStr(sqlite.get_double(2),Digits)); } //ステートメントの解法 sqlite.finalize(); //データベースを閉じる。 sqlite.db_close(); return (0); }
まとめ
mq4(ANSI or UNICODE)→MT4(UNICODE)→SQLite3(UTF-8)→MT4(UNICODE)→output(ANSI)エンコードの統一ってできないものでしょうか(ー_ー)!!。。
0 件のコメント :
コメントを投稿