dowasureDBjs

ど忘れDBjs

〜SQLをすぐに忘れてしまう人のためのJavaScriptライブラリ〜

Sorry! This description is in Japanese only.

https://github.com/ari2008/dowasureDBjs

    ツールの概要

    ちょっとしたWebアプリ(スケジュール管理アプリ、家計簿アプリetc.)を作りたいのに、 たまにしか使わないのでSQLが思い出せないという経験はないでしょうか? このライブラリは、そういう状況のために作成した、ほぼJavaScriptだけで データベースを利用できるようにするツールです。

    基本的な考え方は非常にシンプルです。

    JavaScriptのオブジェクトをJSON化し、データベースのレコードとして保存する。

    record IDObject NameValiable NameUpdate Timeextras1JSON

    その他の特徴は次のとおりです。

    以下の制限があります。

    使用開始までの準備

    ファイルを配置する

    dowasureDBjsフォルダ内のjsフォルダとphpフォルダを、目的のWebアプリと同じフォルダ内にコピーします。

    ※dwrdb.jsから「php/スクリプト.php」というパスで参照しているので、 phpフォルダの名前と位置には注意してください。

    データベースを作成する

    phpMyAdminなどを使って、dowasureDBで利用するデータベースとユーザーを作成します。

    PHPMyAdminでの設定例

    データベース情報を設定する

    phpフォルダ内の「00_dbinfo.php」をテキストエディタで開き、MySQLのデータベースに合わせて各設定を行います。 また、認証システムの最初のユーザーのユーザー名、パスワードも設定しておきます。
    データテーブルはdowasureDBjsがデータ(ユーザー情報を除く)を保存するテーブルの名前です。

    /*
     * ここに利用するデータベースの情報を入力し、ブラウザでinitDB.phpにアクセスしてください。
     */
    //サーバアドレス
    $mysql_server = "localhost:3306";
    
    //データベースに接続するためのユーザー名
    $mysql_user = "dwrdbjs";
    
    //データベースに接続するためのパスワード
    $mysql_password = "password";
    
    //データベース名
    $mysql_database = "dwrdbjs";
    
    //データテーブル名
    $mysql_datatable = "dwrdbjs";
    
    /* 
     * 以降はdowasureDBjsの認証システムに登録される最初のユーザーの情報を入力しておきます。
     * 何らかのユーザー名でログインしない限り、新しいユーザーの追加ができないためです。
     */
    //ファーストユーザー名
    $dwrdb_firstuser = 'admin';
    
    //ファーストユーザーのパスワード
    $dwrdb_fupassword = 'password';

    初期設定を実行する

    「01_initDB.php」にWebブラウザでアクセスします。このスクリプトが00_dbinfo.phpで指定したデータベース内に 必要なテーブルを作成し、最初のユーザーの情報を登録します。 「データベースの初期設定に成功しました。」と表示されれば成功です。

    dowasureDBjsの使い方

    サンプルファイルを例に、dowasureDBjsの使い方を説明しましょう。

    sample.php(サンプルではguest、guestでログイン)

    このサンプルファイルでは、入力ボックス付きの表が配置されています。 ページを2つ開き、一方で行の追加やデータの修正を行うと、もう一方にも自動反映されます。 データベースを介して複数が同じ状態になるよう自動同期されているわけです。

    一方に行を追加した
    一方に行を追加すると、約5秒後にもう一方にも反映される
    もう一方にも自動的に反映される
    一方の修正が約5秒後に反映される

    dwrdb.jsの読み込み

    <script src="js/dwrdb.js"></script>
    					

    レコードの読み込み

    DwrDBObjectオブジェクトの静的メソッドloadArrayFromDBを使って、 データベースから「testarray」という変数名のレコードをすべて読み込みます。 結果の配列変数を、2つめの引数に指定した関数で受け取ります。

    //既存レコードの読み込み
    DwrDBObject.loadArrayFromDB('testarray',
    	function(retarray){
    		if(retarray.length < 0){
    			testarray = [];
    		} else {
    			testarray = retarray;
    			updateTable(testarray);
    			//5秒ごとに表を更新
    			window.setInterval(autoUpdateTestArray, 5000);
    		}
    	}
    );

    配列変数の更新

    DwrDBObjectオブジェクトの静的メソッドupdateArrayによって配列変数を更新します。 このメソッドは「配列変数名」「配列変数のArrayオブジェクト」「結果を受け取る関数」の3つの引数を取り、 指定された配列変数を更新した後、第3引数の関数を呼び出します。 関数には更新レコード数(新規含む)と新規レコード数が渡されるので、更新があったかどうかを確認できます。

    //テーブルの自動更新
    function autoUpdateTestArray(){
    	DwrDBObject.updateArray('testarray', testarray,
    		function(numupdate, numnew){
    			if(numupdate>0){
    				//表を更新
    				updateTable(testarray);
    			}
    		}
    	);
    }

    レコードの新規作成

    新しいレコードを作成するには、まずDwrDBObjectのインスタンスを作成します。 インスタンスメソッドのcreateNewRecordOnDBを呼び出すと、データベース上に対応するレコードが作成され、 recordIDプロパティが自動設定されます。これでDwrDBObjectを保存できる状態になります。
    後はオブジェクトに任意のプロパティを設定し、writeToDBメソッドで書き込みを行います。 writeToDBメソッドには変数名を渡す必要があります。書き込み完了時に何らかの処理をしたい場合は、 第2引数に関数を設定します。

    ※いきなりwriteDBを呼び出した場合でも、自動的にcreateNewRecordOnDBを呼び出すよう改良しました。 つまり、createNewRecordOnDBメソッドは使う必要がありません。

    //レコードを作成
    function addRow(event){
    	//新しいオブジェクトの作成
    	var newobj = new DwrDBObject();
    	//データベース上に新レコード作成
    	newobj.createNewRecordOnDB(
    		function(){
    			//プロパティを追加してデータベースに保存
    			newobj.dummyfield = 'ダミー';
    			newobj.dummyfield2 = 'ダミー';
    			testarray.push(newobj);
    			newobj.writeToDB('testarray', 
    				function(){
    					//表を更新
    					updateTable(testarray);						
    				}
    			);
    		}
    	);
    }

    レコードの保存

    サンプルでは、表内のテキストボックスが更新されると、それをデータベースに反映するようにしています。 DwrDBObjectオブジェクトのインスタンスメソッドwriteToDBを呼び出します。 引数には変数名と書き込み完了時に呼び出される関数を指定します。

    //データ更新
    function changeInput(event){
    	var input = event.currentTarget;
    	var obj = testarray[input.dataindex];
    	obj[input.datapropname] = input.value;
    	obj.writeToDB('testarray', 
    		function(){
    			//表を更新
    			updateTable(testarray);						
    		}
    	);
    }

    認証システムの利用

    認証システムはPHPで作成しており、dowasureDBjsを利用するすべてのHTML(PHP)ファイルに対して、 いくつかのPHPコードを書いておく必要があります。
    ファイルの最初でdwrDBSessionStart関数を呼び出し、セッションを開始します。

    <?php 
    //PHPの関数群を読み込みます(必須)
    include_once 'php/99_dwrDBFunctions.php';
    //セッション開始(必須)
    dwrDBSessionStart();
    ?>
    
    <!DOCTYPE html>

    body要素の先頭に、ログインしていないときに表示するメッセージを書いておきます。 dwrDBGetAuth関数がfalseを返したらログインしていないので、メッセージとログインページへの リンクを書いておき、exit関数でそれ以降が表示されないようにします。

    <body>
    <?php
    	//ログイン済みかどうかを確認
    	if(dwrDBGetAuth()==false){
    		echo "<p>先にログインしてください。</p>";
    		echo "<p><a href='sample_login.php'>ログインページへ</a></p>";
    		exit();
    	}
    ?>

    上記のPHPコードを書かないと、ログインしていなくてもページの続きが表示されてしまいます。 しかし、DwrDBObjectオブジェクトのメソッドから呼び出されるPHPの関数の側でも、 ログインチェックをしているため、結局ログインしていなければ通信エラーが発生します。

    ログインページについて

    ログインページは、sample_login.phpや02_login_nosc.phpを参考に作成します。 他のページと同様、ファイル先頭でPHPのdwrDBSessionStart関数を呼び出します。

    <?php 
    //PHPの関数群を読み込みます(必須)
    include_once 'php/99_dwrDBFunctions.php';
    //セッション開始(必須)
    dwrDBSessionStart();
    ?>
    
    <!DOCTYPE html>

    未ログインのときは、ログインフォームが表示されるようにします。

    <body>
    	<?php
    		//ログイン済みかどうかを確認
    		if(dwrDBGetAuth()==false){
    			//未ログインならログインフォームを表示
    			echo "<form id='frm_login' method='POST' action='php/callPHPFunction.php'>";
    			echo "<fieldset>";
    			echo "<legend>ログイン";
    			echo "<label>ユーザー名(半角英数)";
    			echo "<input type='text' name='username' value=''>";
    			echo "</label>";
    			echo "<lable>パスワード(半角英数と記号)";
    			echo "<input type='password' name='password' value=''>";
    			echo "</lable>";
    			echo "<input type='submit' id='btn_submit' value='ログイン'>";
    			echo "</fieldset>";
    			echo "<input type='hidden' name='functionname' value='dwrDBLogin'>";
    			echo "<input type='hidden' name='redirecturl' value='../sample_login.php'>";
    			echo "</form>";
    			echo "<div id='div_error'></div>";
    			echo "</body></html>";
    			//ここでPHPの処理をストップ
    			exit();
    		}
    	?>
    hiddenタイプのinput要素として、「name='functionname' value='dwrDBLogin'」と 「name='redirecturl' value='../sample_login.php'」を指定しておきます。
    ログイン処理の後、ログイン成功、失敗を問わずにredirecturlとして設定したページにジャンプします。 通常は現在のページ自体を指定します。
    「現在のページ」→「php/callPHPFunction.php」→「現在のページ」と移動するため、 redirecturlは、callPHPFunction.phpの場所を基準としたパスか、絶対パスでなければいけません。

    認証システムの利用サンプル

    dowasureDBjsには簡単な認証システムが用意されており、ユーザーの追加、ニックネーム・パスワードの変更、 ユーザー一覧の取得を行うことができます。

    sample_user.php

    sample_user.phpの利用サンプル

    ユーザーの一覧取得

    DwrDBUserオブジェクトの静的メソッドgetAllUsersを呼び出すと、引数に指定した関数に ユーザーとニックネームを記録した無名オブジェクトの配列が渡されます。

    //データベースからユーザー一覧を取得
    DwrDBUser.getAllUsers(
    	function(userarr){
    		g_userlist = userarr;
    		for(var i=0; i<g_userlist.length; i++){
    			var newtr = document.createElement('tr');
    			var newtd = document.createElement('td');
    			……中略……
    			newtd = document.createElement('td');
    			newtd.innerHTML = g_userlist[i].username;
    			newtr.appendChild(newtd);					
    			newtd = document.createElement('td');
    			newtd.innerHTML = g_userlist[i].nickname;
    			newtr.appendChild(newtd);
    		

    ユーザーの追加

    DwrDBUserオブジェクトの静的メソッドaddUserを利用して、ユーザーを追加します。 ユーザー名のバリデーションなどは特に行っていないので、 必要に応じてJavaScript側で記述する設計です。 追加完了後に第4引数の関数を呼び出しますが、特に必要なければ関数を省略しても構いません。

    function clickAddUser(event){
    	var username = document.querySelector('#txt_username').value;
    	var password = document.querySelector('#txt_password').value;
    	var nickname = document.querySelector('#txt_nickname').value;
    	DwrDBUser.addUser(username, password, nickname,
    		function(userobj){
    			updateUserTable();
    		}
    	);
    }

    パスワードやニックネームの変更

    登録済みのユーザーのパスワードやニックネームを変更するには、 DwrDBUserの静的メソッドchangePassword、changeNicknameを呼び出します。 こちらもバリデーションなどは特に行っていないので、必要に応じてJavaScript側で処理します。 設定完了後に第3引数の関数を呼び出しますが、特に必要なければ関数を省略しても構いません。

    function clickChangePassword(event){
    	var newpassword = document.querySelector('#txt_newpassword').value;				
    	var sel = getSelectedUser();
    	if(sel<0) return;
    	DwrDBUser.changePassword(g_userlist[sel].username, newpassword);
    }
    function clickChangeNickname(event){
    	var newnickname = document.querySelector('#txt_newnickname').value;				
    	var sel = getSelectedUser();
    	if(sel<0) return;
    	DwrDBUser.changeNickname(g_userlist[sel].username, newnickname,
    		function(userobj){
    			updateUserTable();
    		}
    	);
    }

    読み取り専用バージョン

    dowasureDBjsの読み取り専用バージョンです。 書き込みやユーザー認証の機能をばっさり削ったもので、動的に生成するWebページを作る場合などに使います。

    サンプル(読み取り専用)

    オブジェクト/メソッド/プロパティ一覧

    DwrDBObjectオブジェクト

    メソッド名書式/説明
    DwrDBObjectコンストラクタvar dbobj = new DwrDBObject();
    新しいDwrDBObjectを作成します。
    recordIDプロパティ-
    データベース上でのユニークID(データベース上ではBigInt型)を記録します。
    updatetimeプロパティ-
    データベースへの最終書き込み時間を表すシリアル値です。
    objectnameプロパティ-
    データベースにオブジェクトの種類を書き込むために、オブジェクト名を記録しています。 初期値は「DwrDBObject」です。継承したオブジェクトを作成する場合、このプロパティの値を合わせて変更する必要が有ります。
    extras1プロパティ-
    レコード数が多い場合に絞り込みのために用意したプロパティです。 128文字以内のテキストを指定します。 データベース上ではextras1フィールドに書き込まれ、データベースからデータを読み込む際の検索条件に使うことができます。 データベースに書き込まれる際にエスケープ処理が施されるため、半角英数字のテキストのみを記録することを推奨します。
    phpfuncs静的プロパティDwrDBObject.phpfuncs = 'php/callPHPFunction.php';
    callPHPFunction.phpの場所を記録しておく静的プロパティです。場所を変更した場合などに設定してください。 初期値はdwrdb.jsを読み込んだPHPファイルを起点とする相対パスになっているため、場合によっては絶対パスに変更したほうがいいでしょう。
    ajaxError静的プロパティDwrDBObject.ajaxError = function(response){……}
    通信エラーを受け取るための関数を設定する静的プロパティです。
    loadArrayFromDB静的メソッド DwrDBObject.loadArrayFromDB(varname, retfunc, offset, extraquery)
    varnameに指定した名前の配列変数をデータベースから読み込み、retfuncに指定した関数「function(retarray)」に DwrDBObjectの配列を返します。 読み込みレコード数は一度に1000件までなので、必要に応じてoffsetやextraqueryなどを指定します。
    updateArray静的メソッド DwrDBObject.updateArray(varname, arrayobj, retfunc, offset, extraquery)
    loadArrayFromDBメソッドで読み込んだDwrDBObject配列のデータを最新のものに更新します。 varnameに配列変数名、arrayobjにArrayオブジェクトを指定し、retfuncには関数「function(全更新数, 新規追加数)」を指定します。 必要に応じてoffsetやextraqueryを指定します。
    更新されたレコードのみを読み込むので、offsetは指定する意味はないかもしれませんが、extraqueryはloadArrayFromDBと合わせたほうがいいでしょう。
    一度loadArrayFromDBで読み込んだ後は、なるべくupdateArrayオブジェクトで更新するようにしてください。 loadArrayFromDBは読み込み時に新しいDwrDBObjectを生成するため、同じレコードとひもづけられた複数のオブジェクトが作られ、 矛盾が起きる危険性があるからです。updateArrayはすでに読み込み済みのレコードであれば、そのプロパティだけを更新します。
    writeToDBメソッド dbobj.writeToDB(varname, retfunc)
    DwrDBObjectをデータベースに書き込みます。varnameに配列変数名を指定します。 書き込み完了を知りたい場合は、retfuncに関数「function()」を指定します。
    なお、配列変数の内容をまとめて書き込む関数はありません。読み込みはまとめて、書き込みは個別に行う設計です。
    deleteFromDBメソッド dbobj.deleteFromDB(retfunc)
    DwrDBObjectとひもづけられたレコードをデータベースから削除します。 書き込み完了を知りたい場合は、retfuncに関数「function()」を指定します。
    レコードを削除した後は、このDwrDBObjectを配列変数から取り除かなければいけません。 連想配列ならdelete演算子、普通(添字が数字)の配列変数ならspliceメソッドで削除します。