• ベストアンサー

sqliteの構造体

SQLiteを使ったメールソフトを作っています。 sqliteの構造体 sqlite3_stmt の宣言は見つかるのですが 構造体の内容の定義してあるものが見つかりません。 sqlite3.h, sqlite3.c を探したのですが見つかりませんでした。  この構造体が見つからないと そこに登録してある値が使えません。 それとも、 この構造体は定義されていなくて これを当てにしないで プログラムを組まなくてはいけないのでしょうか? 使わなくても動かせそうですか。。。 お分かりの方、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.5

sqlite3_column_ で始まっているルーチン郡は、クエリーの結果セットに関する情報を取り出すのに使います。 って書いてるけど。。 http://hp.vector.co.jp/authors/VA002803/sqlite/capi3-ja.htm だから、書き込みの時に使っても意味なくて、下記のように使うのでは? sqlite3_prepare(db, "select * from blobtest;", -1, &plineInfo, NULL); while(sqlite3_step(plineInfo) == SQLITE_ROW) {  int N = sqlite3_column_count(plineInfo);  printf("N=%d\n", N); } 参考:http://blogs.wankuma.com/episteme/articles/56144.aspx

koinobori7
質問者

補足

動きました。参考にしたeatblob.cを以下のように修正したら 予定通りに動きました。 ありがとうございました。 int main(int argc, char **argv){ sqlite3 *db; char *zErrMsg = 0; char sqtext[256]; int rc; sqlite3_stmt *plineInfo = 0; char *line = NULL; FILE * fp; int n; long buflen = 0, totread = 0; char *buf = NULL, *pbuf = NULL; rc = sqlite3_open("image.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } rc = sqlite3_exec(db, "create table blobtest (des varchar(80), blen INTEGER, b blob);", callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } if ((fp = fopen("sample.jpg", "rb"))==NULL ) { fprintf(stderr, "Can't open data: %s\n", "sample.jpg"); return 1; } while (buflen - totread - 1 < 1024) buflen = addmem(&buf, buflen); pbuf = buf; totread = 0; while ((n = fread(pbuf, sizeof(char), 1024, fp)) > 0) { totread += n; pbuf[n] = '\0'; // This is for printing test while (buflen - totread - 1 < 1024) buflen = addmem(&buf, buflen); pbuf = &buf[totread]; } fclose(fp); sprintf(sqtext,"insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);", totread); rc = sqlite3_prepare(db,sqtext , -1, &plineInfo, 0); if (rc == SQLITE_OK && plineInfo != NULL) { printf( "SQLITE_OK\n"); sqlite3_bind_blob(plineInfo, 1, buf, totread, free); while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) { } rc = sqlite3_finalize(plineInfo); } printf("eatblob:%d> ", sqlite3_total_changes(db)); rc = sqlite3_prepare(db, "select * from blobtest;", -1, &plineInfo, 0); while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) { for (int i = 0; i < sqlite3_column_count(plineInfo); ++i){ print_col(plineInfo, i); } printf("\n"); } rc = sqlite3_finalize(plineInfo); rc = sqlite3_exec(db, "select * from blobtest;", callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } sqlite3_close(db); return 0; }

その他の回答 (4)

  • i-kujou
  • ベストアンサー率50% (13/26)
回答No.4

テーブルの定義と現在の状態が不明のためあてずっぽうになってしまいますが、 > insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?); が失敗している可能性はないですか? desやblenがユニーク指定されているカラムだと、二回目以降はインサートに失敗してDBに対して影響を与えなかった為、sqlite3_column_countが0を返すことがあると思います。

koinobori7
質問者

補足

お世話になっています。 開発は、 OS Win2000 コンパイラ VC++2005 VC++6.0の二つ sqlite3.c を修正して、うえのコンパイラの統合環境で 動くようにしました。(sqlite2.cppと名前をつけました) 1回目で動くかどうか デバッガで確認してみます。  データベースを削除してから 動かせばよろしいでしょうか?

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

ん~。SQLiteを使ったプログラミングの話にシフトしてしまったので、 これからは知っている人の回答に期待、ですが、 提示されたコードだけでは、情報が少なすぎるのではないかと直感的に思います。 開発環境と、下記のコードの補足をお願いします。 ・データベースの作成(オープン) ・テーブルの作成 ・レコードの追加 こちらで時々ご回答されている、epistemeさんの記事が参考になるでしょうか。 http://codezine.jp/a/article/aid/1252.aspx?p=2

koinobori7
質問者

お礼

ありがとうございます。 教えていただいたURLのサンプルと sqlite3.c を修正して、vc++2005の統合環境で 動くようにした sqlite2.cppを組み合わせたら、 サンプルは正常に動きました。 それと、画像データは 複数回格納できます。  また、plineInfoからの 情報は取り出せないんですが、 代わりの情報(サイズ、名前)をデータベースに登録しておくと データベースから画像ファイルを取り出せます。  列数は固定でもかまわないので 使えることは使えるのですが BLOBデータの場合は面倒です。 ほかに、お気づきの点がありましたらよろしくお願いします。

koinobori7
質問者

補足

int main(int argc, char **argv){ sqlite3 *db; char *zErrMsg = 0; char sqtext[256]; int rc; sqlite3_stmt *plineInfo = 0; char *line = NULL; FILE * fp; int n; long buflen = 0, totread = 0; char *buf = NULL, *pbuf = NULL; rc = sqlite3_open("image.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } rc = sqlite3_exec(db, "create table blobtest (des varchar(80), blen INTEGER, b blob);", callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } if ((fp = fopen("sample.jpg", "rb"))==NULL ) { fprintf(stderr, "Can't open data: %s\n", "sample.jpg"); return 1; } while (buflen - totread - 1 < 1024) buflen = addmem(&buf, buflen); pbuf = buf; totread = 0; while ((n = fread(pbuf, sizeof(char), 1024, fp)) > 0) { totread += n; pbuf[n] = '\0'; // This is for printing test while (buflen - totread - 1 < 1024) buflen = addmem(&buf, buflen); pbuf = &buf[totread]; } fclose(fp); sprintf(sqtext,"insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);", totread); rc = sqlite3_prepare(db,sqtext , -1, &plineInfo, 0); if (rc == SQLITE_OK && plineInfo != NULL) { printf( "SQLITE_OK\n"); sqlite3_bind_blob(plineInfo, 1, buf, totread, free); while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) { for (int i = 0; i < sqlite3_column_count(plineInfo); ++i){ //ここに入らない。 print_col(plineInfo, i); } printf("\n"); } rc = sqlite3_finalize(plineInfo); } printf("eatblob:%d> ", sqlite3_total_changes(db)); rc = sqlite3_exec(db, "select * from blobtest;", callback, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } sqlite3_close(db); return 0; }

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

肝心の質問に答えていませんでした。 > これを当てにしないで > プログラムを組まなくてはいけないのでしょうか? > 使わなくても動かせそうですか。。。 はい、構造体の実フィールドは何か、ということは当てにせず、 http://www.sqlite.org/c3ref/stmt.html に書いてあるような、アクセス関数を操作すれば動かせそうです。 (変数の中身は何かしら、更新されるはず)。 実際にやってみたことがないので、恐縮ですが。 >この構造体が見つからないとそこに登録してある値が使えません。 この構造体を引数にして、必要な情報を返すアクセス関数を 探してみると良いかもしれません。

koinobori7
質問者

補足

sprintf(sqtext,"insert into blobtest (des,blen,b) values ('A test file: sample.jpg', %d, ?);", totread); rc = sqlite3_prepare(db,sqtext , -1, &plineInfo, 0); //ここで値が入るのが当然と思うが入らないのです。 if (rc == SQLITE_OK && plineInfo != NULL) { printf( "SQLITE_OK\n"); sqlite3_bind_blob(plineInfo, 1, buf, totread, free); while ((rc = sqlite3_step(plineInfo)) == SQLITE_ROW) { for (int i = 0; i < sqlite3_column_count(plineInfo); ++i){ print_col(plineInfo, i); } printf("\n"); } rc = sqlite3_finalize(plineInfo); } としても、 sqlite3_column_count(plineInfo); は、0を返します。 構造体の中身は変化しないのです。

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

お分かりでないので恐縮ですが、ちょっとgoogleで探してみました。 sqlite3_stmtの実体は隠蔽されていて(いわゆるオブジェクト) その実体にアクセスするために、以下のようなアクセス関数が 提供されているということではないでしょうか。 int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**); int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**); int sqlite3_finalize(sqlite3_stmt*); int sqlite3_reset(sqlite3_stmt*); バグの混入を防ぐ為に、sqlite3_stmtの内部構造は、直接ユーザーは 知りえない状態にしているように思います。 (いわゆるカプセル化) 外してたらすいません。

関連するQ&A