前回はAndroidで生成されたDBファイルをLinux Boxに取り出して調べてみたが、今回は逆にLinux Boxで作ったDBファイルをAndroidにコピーして読み込めるか調べてみる。
データベース生成用PHPスクリプト
sqlite3をコマンドラインで直接操作してもDBファイルは作れる。けれど、投稿のカテゴリなど属性情報のテーブルはデータを予め入れておきたいし、スクリプトである程度自動化したい。そこで、PHPはsqliteをネイティブサポートしていることもあって、PHPでDBファイル生成用スクリプトを作成することにした。
#! /usr/bin/php -q
<?php
/**
* CSVデータからテーブル定義を抽出してSQL化、同時にデータも抽出してテーブルに追加する
*/
$db = new MyDB();
$tables = array('android_metadata', 'category', 'subcategory', 'record');
foreach($tables as $tbl) {
$csvfile = $tbl . '.csv';
$file = new SplFileObject($csvfile);
$file->setFlags(SplFileObject::READ_CSV);
$lineCount = 0;
foreach ($file as $line) {
$lineCount++;
if(!is_null($line[0])){
$linmb = mb_convert_encoding($line, 'utf-8', 'sjis');
switch($lineCount) {
case 1:
$fieldName = $linmb;
break;
case 2:
$fieldType = $linmb;
$fieldList = createSQLtable($db, $tbl, $fieldName, $fieldType);
break;
default:
$fldCnt = count($linmb);
$sql = 'INSERT INTO ' . $tbl . ' ' . $fieldList . " values ('" . $linmb[0] . "'";
for($n = 1; $n < $fldCnt; $n++) {
$sql .= ',' . "'$linmb[$n]'";
}
$sql .= ')';
$db->exec($sql);
print "$sql\n\n";
}
}
}
}
function createSQLtable($db, $tableName, $fieldName, $fieldType)
{
$sql = 'create table ' . $tableName;
$fldCnt = count($fieldName);
if ( $fldCnt == count($fieldType) ) {
$fldList = '(' . $fieldName[0];
$sql .= ' (' . $fieldName[0] . ' ' . $fieldType[0];
for($n = 1; $n < $fldCnt; $n++) {
$sql .= ', ' . $fieldName[$n] . ' ' . $fieldType[$n];
$fldList .= ', ' . $fieldName[$n];
}
$sql .= ')';
$fldList .= ')';
$db->exec($sql);
return $fldList;
} else {
print $tableName . ":Field Count Mismatch\n";
return null;
}
}
class MyDB extends SQLite3
{
function __construct()
{
$this->open('myLog.db');
}
}
?>
$tables配列にテーブル名を入れておき、’テーブル名.csv’という名前のCSVファイルを別途用意しておく。このCSVは、以下のフォーマットでカンマ区切りテキストでデータを入れておく(次節で実データも挙げます)。
- 1行目:カラム名
- 2行目:カラムのデータ型
- 3行目〜:テーブルのデータ
そして、createSQLtable関数が上記CSVファイルを読み込んだうえで、以下の操作を行う。
- データベースにcreate table文でテーブルを作成する
- CSVの3行目以降の値をテーブルにデータ登録する
テーブル作成用CSVファイル
上記スクリプトで用いるCSVファイルも挙げておく。
- android_metadata.csv
locale
TEXT
ja_JP
- category.csv
CatID,CatName
INTEGER,TEXT
1,仕事
2,日本酒
3,旅
- subcategory.csv
CatID,SubID,SubName
INTEGER,INTEGER,TEXT
1,1,仕事1
1,2,仕事2
1,3,仕事3
2,1,美味かった
2,2,不味かった
3,1,ハワイ2019
3,2,ヨーロッパ2020
- record.csv
ID,DateTime,CatID,SubID,Comment,Photo1,Photo2,Photo3,Photo4,Link
INTEGER,TEXT,INTEGER,INTEGER,TEXT,TEXT,TEXT,TEXT,TEXT,INTEGER
1,2019/3/26 12:34,1,1,テスト,,,,,0
作ったDBファイルをコマンドラインで確認
コマンドラインのsqliteを使って作成したDBファイルをチェックする。
$ sqlite3 myLog.db
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> .tables
android_metadata category record subcategory
sqlite> .schema record
CREATE TABLE record (ID INTEGER, DateTime TEXT, CatID INTEGER, SubID INTEGER, Comment TEXT, Photo1 TEXT, Photo2 TEXT, Photo3 TEXT, Photo4 TEXT, Link INTEGER);
sqlite> select * from record;
1|2019/3/26 12:34|1|1|テスト|||||0
特に問題無さそう。
作ったDBファイルをAndroid端末で読み込む
上記で作ったファイルをSDカード経由でadb shellによってアプリの管理領域にコピーする。実際のアプリではSDカード経由だと色々面倒なので別途方法を考える必要があるが、とりあえず今回はテストのために簡単な方法で。
$ adb shell
shell@SC-03E:/ $ su
su
root@SC-03E:/ # ls /storage/extSdCard/Temp
ls /storage/extSdCard/Temp
myLog.db
root@SC-03E:/ # cd /data/data/com.example.androidtest/databases
cd /data/data/com.example.androidtest/databases
root@SC-03E:/data/data/com.example.androidtest/databases # cp /storage/extSdCard/Temp/myLog.db .
e/extSdCard/Temp/myLog.db . <
root@SC-03E:/data/data/com.example.androidtest/databases # ls
ls
myLog.db
上記データベースを扱うためには、SQLiteOpenHelperの派生クラスを作ってやる必要がある。詳細は別記事に譲るとして、今回はテストコードの断片だけ挙げておく。
public void getDbTableDetails() {
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
int count = 0;
Log.i("DBA","*** Table List of '" + DATABASE_NAME + "' ***");
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
String temp = c.getString(0);
count++;
Log.i("DBA","Table" + count + ":" + temp);
}
}
上記を実行すると、LogCatのinfoセクションにテーブル一覧が表示される。
05-19 09:28:56.796 9055-9055/com.example.androidtest I/DBA: *** Table List of 'myLog.db' ***
05-19 09:28:56.801 9055-9055/com.example.androidtest I/DBA: Table1:android_metadata
05-19 09:28:56.801 9055-9055/com.example.androidtest I/DBA: Table2:category
05-19 09:28:56.801 9055-9055/com.example.androidtest I/DBA: Table3:subcategory
05-19 09:28:56.801 9055-9055/com.example.androidtest I/DBA: Table4:record
コメント