dashmarkを更新

ここ数週間ぽつぽつと作り続けているdashmarkを更新した。
dashmark03

Main Feature

  • Fast search!!
  • Saving all data onto Safari's client side database storage (SQL API:all information is closed)
  • Many CSS Animation effects
  • Overlaying bookmark search interface on other web-page.
  • Adding auto quote to your bookmark.

変更点

今回のバージョンアップで、クライアント側のデータベース・バージョンは1.4に更新されます。
タグ[tag]、引用[quote]、閲覧もと[referer]、Faviconのパス[favicon]が追加されます。tagとfaviconrefererについてはこれからユーザインターフェイスを追加していく予定。

また、ブックマークレットとdashmark間での情報のやり取りにJSONを用いるように仕様変更したので、古いバージョンから使っている方はブックマークレットの更新もお願いします。
新しいブックマークレットを用いると、ブックマークの追加を行うときに選択している部分をquoteに引用します。

また、追加予定としている全ページのログを保存する機能のために、同じページで重複してブックマークを保存する仕様を変更しました。同じURLに一つだけのブックマークしか保存できなくなります。

CSS Animationの効果を引き出すために、変更日付の古いブックマークの縮小表示を導入しました。

近い将来の予定

  • del.ico.us対応
    • 過去に投稿したブックマークの取得
    • del.ico.usへのポスト
  • タグのユーザインターフェイス追加
  • 絞り込み検索
  • spaceによる区切り文字を用いた検索
  • タイムライン表示
  • TimeMacine表示
  • SafariCSS Animation対応をより前進させる

ノート

今回のデータベースの更新では、今まで行ってきたSQLのalterによるcolumnの追加ではなく、temporary tableを作成してバックアップを行いながら新しい構造のテーブルにデータを流し込んでいる。
理由は二つ。一つ目はデータ型の一致のため。
前回のデータベースバージョンアップのときに、新たにデータベースを作る際にデータ型を間違えて作成させていた*1ために、データベースのデータ型に不整合を出してしまった。文字列でも数値でも動作するようにプログラム側に手を入れたが、その手のコードは可能な限り排除したいので今回データ型変換を行うことにした。
もう一つは通しナンバーで作成していたidを排除することにあった。
通しナンバーのidは先のことをあまり考えずに初期のバージョンでエントリをアイデンティファイするために用いていたのだが、一回目のバージョンアップのときにguidでユニークなidを付加することにしたので事実上使用していなかったのだが、データ型をREAL UNIQUEで作成してしまったために、存在するIDへのアクセスが発生すると、SQLエラーが出る問題が潜在していた。
SafariSQL APIで一度ロックされてしまったDBを解放する手段が私には見つけられていないので、本質的に書き込みを排他してしまう通し番号というアキレス腱を今回排除したかったのだ。

追記

build 00018にて以下のバグを修正

  • <TITLE>[改行][titleの名称][改行]</TITLE>となっているときにタイトルが消えるバグの修正
  • bookmarkが存在している場所でのブックマークサイズの修正

build 00019にて以下の機能を追加

  • 追加したタグによる検索
  • タグのレイアウトを変更
  • 検索結果を大きく表示するように設定

リソース追加

temporary tableを用いたchange versionのコード

まだ課題はあるけど今回のchange versionに用いたコードを抜粋。
大きな課題は下の二つ。バックアップを行うツールと古いデータベースを使うアプリケーションも用意しなきゃいかんよなぁ。

  1. 途中でエラーが出ても個別のエラーしか拾えず、データベースのバージョンチェンジが行われてしまう。
  2. ロールバックを行って作業前に戻す方法がわからない


var database_version = 1.4;
try {
if (window.openDatabase) {
var dbname = "bm_comments";
if(development) dbname += "_dev";
db = openDatabase( dbname,
database_version,
"database for web comments",
200000);
if (!db)
alert("Some problem occurs. It may your database storage
size limitation is too small for this application\n
データベースストレージ用の容量が不足しているなどの問題が発生しました。");
} else
alert( "Your browser does not support
client-side database storage.");
} catch(err) {
var dbname = "bm_comments";
if(development) dbname += "_dev";
db = null;
db = openDatabase(dbname,"","database for web comments",200000);
switch(db.version){
case "1.3":
db.changeVersion("1.3", database_version,
function(tx){
alert('Database format version up from 1.3 to '+ database_version);
//Creating temp table
//テンポラリテーブルの作成

tx.executeSql(
"CREATE TEMPORARY TABLE ELEMENT_DB_BK (uid TEXT, note TEXT....)", [],
function(result){ },
function(err){
alert("Faild to create temporary database\nERROR:" + err.message );
});

//backup table database
//データの入っているテーブルをテンポラリテーブルにバックアップ
//nullを許容しない場合は、'' as [collumn]としておく。
tx.executeSql("INSERT INTO ELEMENT_DB_BK SELECT uid , note, '' AS tag,...", [],
function(result){ },
function(err){
alert("Faild to back up current database\nERROR:" + err.message );
});

//Removing current database
//データの入っているテーブルを削除
tx.executeSql("DROP TABLE ELEMENT_DB", [],
function(result){ },
function(err){
alert("Faild to drop current database\nERROR" + err.message );
});

//Creating table
//テンポラリテーブルと同じ型のテーブルを作成する
tx.executeSql("CREATE TABLE ELEMENT_DB (uid TEXT, note TEXT ...", [],
function(result){ },
function(err){
alert("Faild to create temporary database\nERROR:" + err.message );
});

//Restoreing table database
//テンポラリテーブルからデータを書き戻す
tx.executeSql("INSERT INTO ELEMENT_DB SELECT * FROM ELEMENT_DB_BK", [],
function(result){ },
function(err){
alert("Faild to restoreing database\nERROR" + err.message );
});

},
function(err){
alert("Faild to update database version.+ err.message + "ERROR");
},
function(){
alert("Database version update process sucseeded. Restart Safari");
db = null;
}
);
break;
case "1.2":
db.changeVersion("1.2", database_version,
function(tx){
....}
break;

default:
alert("Unknown or unsupported database version.");
}
}

*1:labelとstarをNUMBERで作らなければならなかったのにTEXTで作成してしまった