スポンサーリンク

AndroidアプリのSQLiteで,データベースの存在を判定する方法 (ローカルファイルにデータを永続化させる場合の,事前チェック処理)


あなたは,自分のブログに対して,腹が立った事はあるか。



私は先日,「AndroidでのDB(スキーマ)の存在を確認する方法」を調べようと思った。

そしてググった。


この有り様である。




「Android データベース "存在判定"」という検索キーワードの検索結果で,

なぜか上位4件が私のブログだった。

しかも全然関係ない情報のみ


表示されたのは,上から順に

  1. ポスグレのシステムテーブル
  2. JavaScriptのグローバル変数
  3. SeleniumでXPathを使う方法
  4. ある月の記事インデックス

のページ。



これは,何に怒りをぶつけたらよろしいか?

  • 私のブログ?
  • Googleの検索アルゴリズム?
  • 世間に存在する情報の量?

・・・。



こういう事は,よくあるのだ。

そのたびに何だかやるせなくなる。


もちろん検索キーワードを繰り返しいろいろ変えてみたが,

他の日本語の情報で手に入るのは,
「SQLiteOpenHelperを使えば,データベースの存在チェックをする必要はないよ。」
という件ばかり。

それはもう知っていて,それを知りたいんじゃあないのだが。。。

解決編


で結局,日本語の情報はスッパリあきらめて

英語圏でググれば一発で欲しい情報が得られた。


検索ワードは「Android check database exists」。


Androidで(テーブルではなく)データベースが存在するかどうか確認する方法:

Query if Android database exists!
http://stackoverflow.com/questions/33...

  • SQLiteDatabase.openDatabase()で例外が発生するかどうかチェックすればよい


Check if a database exist (android sqlite3_open_v2 failed)
http://www.itsalif.info/content/check...


Androidファイルシステム中で,SQLiteの特定のスキーマのデータファイルのファイルパスがどこなのかについては,下記URLを参照。

adb shellで,目視で「/data/data/パッケージ名/databases」内をlsして確認する。

raw Resources Android filepath
http://stackoverflow.com/questions/62...


How to find the path of Database file in Android Emulator?
http://stackoverflow.com/questions/11...


なお,データベースファイルは,Helperクラスをnew()してコンストラクタを呼んだだけでは作成されない。

ヘルパーに対して特定の読み書きのメソッドを呼び出して初めて,onCreate()が呼ばれて,そのタイミングでデータファイルが作成される。

なぜ,DBが存在しない状況でインスタンスを生成してもonCreate()が呼ばれないのか,それが謎ではまった。

SQLiteOpenHelper failing to call onCreate?
http://stackoverflow.com/questions/50...

  • It is only called if you try to open a database that does not exist. To open/create the database you need to add a call to one of these methods:
  • dBHelper.getWritableDatabase();


そこまでくれば,あとはonCreate()メソッド内でDDLとDMLを流し,初期データを投入するのみ。


データベースファイル自体をassetsフォルダ内に格納しておく方法もある。

Android あらかじめ作成した SQLite database をアプリに取り込む
http://y-anz-m.blogspot.com/2011/01/a...

  • アプリ(初回)実行時に SQLite データベースを作成してデータの追加や更新、削除などを行っているのがほとんどだが,あらかじめ作成しておいた SQLite database をアプリに仕込みたい場合もある。


なお,adb経由でsqliteを起動し,テーブル作成情報を確認する際,

sqliteコマンドの引数を間違えたせいで,テーブルの作成に失敗したかのように勘違いしてしまうケースがあった。


引数は,ローカルファイルのフルパスを指定する必要がある。

hoge.dbが存在する状況なら,/data/data/パッケージ名/databases をカレントディレクトリにしない限り「sqlite hoge.db」はうまくいかない。


にも関らず,sqliteコマンド自体は成功して,テーブルが何もない,という不思議な光景を目にする事になり,混乱は必須だ。

Androidからスキーマを作成したら「android_metadata」というメタテーブルが自動生成されるので,そのテーブルが存在しない時点で,何か間違えている。


あとは,hoge.dbというデータベースファイル名なのを,拡張子を忘れて「sqlite hoge」とかやっても同じ事態になる。

拡張子なんてなくても構わないのに,わざわざ付与したのが,逆に仇になってしまうわけだ。私の事だが。


結論

まあ,ここまで詳しく書いておけば,冒頭のような検索バグは起こるまい。

今後はこのエントリが,先頭かその付近に来るようになってくれるはずだから・・・。