Web開発フレームワーク
データベース拡張関数

  通常CGIはデータベースのAPIドライバーを使用して、DBに接続、パラメータのBind、SQLの実行、DBとの切断を、
データベースそれぞれの方法で実行しますが、CGJSはこのDBアクセスをデータベース共通の拡張関数としてまとめました。
また、扱うデータも文字列、数値等のカラム単位のデータではなく、レコードの配列等JSONの構造化されたデータにしました。
拡張関数を使用すると、複数レコードの検索結果をレコード(ArrayやHash)のJSON配列としてFrontに渡すことができます。
また、レコード(Array)のJSON配列をSQLと共に拡張関数に渡して、テーブルへの複数レコードINSERT,UPDATEができます。
 
拡張関数の一覧
openDb    select    record_map    selectHash    selectInto    selectToFront    selectHashToFront
closeDb    execute    record_hash    selectExists    alertToFront    sendToFront
1.DB操作関数
 
■ openDb   拡張関数の一覧へ
概要 データベースAPIのライブラリをロードし、データベースとの接続を確立する。
形式 openDb(db_name, lib_path, connect_str);
引数 db_name:接続するDBを指定する文字列
lib_path:接続するデータベースAPIのダイナミックライブラリのフルパス文字列
connect_str:ユーザーID、パスワードなどの接続文字列
戻り値 DBオブジェクト

 ・・・・・・・・・・・・・・・・・・・
 let db_name = 'oracle';
 let lib_path = '/opt/oracle/instantclient_21_7/libclntsh.so';
 let connect_str = 'db=ORA;user=test;pwd=test';
 let conn = openDb(db_name, lib_path, connect_str);
 ・・・・・・・・・・・・・・・・・・・

 
■ closeDb   拡張関数の一覧へ
概要 データベースとの接続を'commit'、'rollback'で終了する。
形式 closeDb(db_obj, close_op);
closeDb(db_obj)
引数 db_obj:DBオブジェクト(openDbの返値)
close_op:接続終了時の操作を指定する文字列('commit'、'rollback')
備考 close_opを省略した場合の終了時操作は'rollback'になります。
close_opの判定は、先頭1文字が'C'、'c'の場合'commit'として行っています。
openDbをした場合は必ずcloseDbを実行してください。
戻り値 undefined

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('oracle',
  '/opt/oracle/instantclient_21_7/libclntsh.so',
  'db=ORA;user=test;pwd=test');
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');
 ・・・・・・・・・・・・・・・・・・・

 
■ execute   拡張関数の一覧へ
概要 select文でないSQLを実行する。
形式 execute(db_obj, sql_str);
execute(db_obj, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するSQLの文字列(select文以外)
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
備考 複数レコードの処理をする場合、bind_valuesにはレコード(配列)の配列を設定
戻り値 Oracle以外:処理されたレコード数
Oracle:0

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('sqlserver',   "/opt/lib64/libmsodbcsql-17.10.so.1.1",
  "Server={tcp:1.0.0.1,1433};UID=SA;PWD=pwd;Database=DB");
 ・・・・・・・・・・・・・・・・・・・
 execute(conn, "insert into table01 (col1,col2,col3) values (10,20,30)");
 execute(conn, 'insert into table01 (col1,col2,col3) values (:1,:2,:3)',
  [[1,2,3],[4,5,6],[7,8,9]]);
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');
 ・・・・・・・・・・・・・・・・・・・

 
■ record_map   拡張関数の一覧へ
概要 select文を実行し、検索されたrecordごとに、各カラムの値を変数名がcolumnの配列に設定し、
JavaScriptのStatementを実行する。配列のindexはselect文のカラムの並び順です。
Statementの実行環境(変数・関数のScope、Extent)は、record_map関数の実行場所の環境です。
形式 record_map(db_obj, sql_str, statement);
record_map(db_obj, sql_str, bind_values, statement);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するSQLの文字列(select文)
bind_values:SQL文中のBind Parameterに設定する値の配列
          「リファレンス-->SQL文のBIND」ページを参照
statement:実行するJavaScriptの文字列
備考 実行するJavaScriptでは、record_mapの位置で参照できる変数・関数にアクセスでき、
変数column(配列)が追加になっている。もし、変数columnを既に使用している場合は一旦隠され、
record_map終了後に復活する。
戻り値 なし

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('sqlserver',   "/opt/lib64/libmsodbcsql-17.10.so.1.1",
  "Server={tcp:1.0.0.1,1433};UID=SA;PWD=pwd;Database=DB");
 ・・・・・・・・・・・・・・・・・・・
 let hash = { };
 let total = 0;
 record_map(conn, "select code, name from master",
   `hash[column[0]] = column[1]; total += column[1]*1;`);
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');
 ・・・・・・・・・・・・・・・・・・・
 // もしselect結果が[ ['a', 4], ['b', 5], ['c', 6'] ]であれば、totalは15,
 // hashは { 'a':4, 'b':5, 'c':6 } になる。

 
■ select   拡張関数の一覧へ
概要 select文のSQLを実行し、結果をレコード(カラム並び順のArray)の配列で返す。
形式 select(db_obj, sql_str);
select(db_obj, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するselect文のSQL文字列
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
備考 bind_valuesは単純な配列。配列の配列は設定できない。
戻り値 select結果(配列の配列)

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('sqlserver',
  "/opt/lib64/libmsodbcsql-17.10.so.1.1",
  "Server={tcp:127.0.0.1,1433};UID=SA;PWD=pwd;Database=DB");
 ・・・・・・・・・・・・・・・・・・・
 let arr = select(conn,
  "select col1,col2,col3 from table01 where key = 1");
 let arr = select(conn,
  "select col1,col2,col3 from table01 where key = :1 and code = :2", [1,2]);
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');

 
■ selectHash   拡張関数の一覧へ
概要 select文のSQLを実行し、結果をレコード(カラム名をキーにしたHash)の
配列で返す。
形式 selectHash(db_obj, sql_str);
selectHash(db_obj, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するselect文のSQL文字列
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
備考 bind_valuesは単純な配列。配列の配列は設定できない。
戻り値 select結果の連想配列(Hash)の配列

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('db2', "/opt/lib/libdb2.so",
  "odbc:HOSTNAME=1.0.0.1;PORT=1;DATABASE=DB;
  PROTOCOL=TCPIP;UID=id;PWD=pwd;");
 ・・・・・・・・・・・・・・・・・・・
 let arr = selectHash(conn,
  "select col1,col2,col3 from table01 where key = 1");
 let arr = selectHash(conn,
  "select col1,col2,col3 from table01 where key = :1 and code = :2", [1,2]);
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');

 
■ selectInto   拡張関数の一覧へ
概要 select文のSQLを実行し、検索結果をカラムの並び順で
変数に設定する。
形式 selectInto(db_obj, sql_str, var_a, var_b, var_c, ・・・);
selectInto(db_obj, sql_str, var_a, var_b, var_c, ・・・,
     bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するselect文のSQL文字列
var_a, var_b, var_c:検索結果を設定する変数
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
備考 bind_valuesは単純な配列。配列の配列は設定できない。
検索結果のレコードが複数ある場合は最初のレコードの値を
変数に設定します。
戻り値 undefined

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('postgresql',
  '/usr/lib/libpq.so.5',
  "host=1.0.0.1;port=5432;db=db;user=id;pwd=pwd");
 ・・・・・・・・・・・・・・・・・・・
 selectInto(conn, "select col1,col2,col3 from table01 where key = 1",
  x, y, z);
 selectInto(conn,
  "select col1,col2,col3 from table01 where key = :1 and code = :2",
  p, q, r, [1,2]);
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');

 
■ selectToFront   拡張関数の一覧へ
概要 select文のSQLを実行し、検索結果のレコード(Array)を
配列にしてFrontに転送する。
形式 selectToFront(db_obj, obj_name, sql_str);
selectToFront(db_obj, obj_name, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
obj_name:FrontのJavaScriptに渡す変数名(連想配列のキー)
sql_str:実行するselect文のSQL文字列
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
備考 bind_valuesは単純な配列。配列の配列は設定できない。
戻り値 Oracle以外:検索されたレコード数
Oracle:0

 [Back End]
  ・・・・・・・・・・・・・・・・・・・
  let conn = openDb('sqlite',
   '/usr/lib/libsqlite3.so.0',
   '/var/www/db/sqlite.db');
  let cnt = selectToFront(conn,
   "sel_obj",
   "select col1,col2,col3 from table01 where key = 1");
  closeDb(conn, 'rollback');
  ・・・・・・・・・・・・・・・・・・・
 [Front End]
  ・・・・・・・・・・・・・・・・・・・
  let ret_obj = { };
  let ret = CGJS.cgjs_if(ret_obj, send_obj);
  let obj_name = ret_obj.CGI_OBJ.sel_obj;
  // obj_nameの値は、[ [1,2,3],[4,5,6],[7,8,9] ]

 
■ selectHashToFront   拡張関数の一覧へ
概要 select文のSQLを実行し、検索結果のレコード(Hash)を
配列にしてFrontに転送する。
形式 selectHashToFront(db_obj, obj_name, sql_str);
selectHashToFront(db_obj, obj_name, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
obj_name:FrontのJavaScriptに渡す変数名(連想配列のキー)
sql_str:実行するselect文のSQL文字列
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
備考 bind_valuesは単純な配列。配列の配列は設定できない。
戻り値 Oracle以外:検索されたレコード数
Oracle:0

 [Back End]
 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('oracle',
  '/opt/oracle/instantclient_21_7/libclntsh.so',
  'db=ORA;user=test;pwd=test');
 let cnt = selectHashToFront(conn, "sel_obj",
  "select col1,col2,col3 from table01 where key = 1");
 closeDb(conn);
 ・・・・・・・・・・・・・・・・・・・
 [Front End]
 ・・・・・・・・・・・・・・・・・・・
 let ret_obj = { };
 let ret = CGJS.cgjs_if(ret_obj, send_obj);
 let obj_name = ret_obj.CGI_OBJ.sel_obj;
 // obj_nameの値は、[ {col1:1,col2:2,col3:3},
  {col1:4,col2:5,col3:6},{col1:7,col2:8,col3:9} ]

 
■ record_hash   拡張関数の一覧へ
概要 マスタテーブルを検索したrecordの、1カラム目をキー(key)にし、2カラム目を値(value)にした
連想配列を作成する。
形式 hash = record_hash(db_obj, sql_str);
hash = record_hash(db_obj, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するselect文のSQL文字列
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
戻り値 連想配列(hash)

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('db2', "/opt/lib/libdb2.so",
  "odbc:HOSTNAME=1.0.0.1;PORT=1;DATABASE=DB;
  PROTOCOL=TCPIP;UID=id;PWD=pwd;");
 ・・・・・・・・・・・・・・・・・・・
 let hash = record_hash(conn, "select code, name from master_tbl");
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');
 // もしselect結果が[ ['01', '北海道'], ['02', '青森'], ['03', '岩手'] ]であれば、
 // hashは { '01':'北海道', '02':'青森', '03':'岩手' } になる。

 
■ selectExists   拡張関数の一覧へ
概要 SQL文を実行し、レコードがあれば true を、なければ false を返す。
形式 ret = selectExists(db_obj, sql_str);
ret = selectExists(db_obj, sql_str, bind_values);
引数 db_obj:DBオブジェクト(openDbの返値)
sql_str:実行するselect文のSQL文字列
bind_values:SQL文中のBind Parameterに設定する値の配列
「リファレンス-->SQL文のBIND」ページを参照
戻り値 true または false

 ・・・・・・・・・・・・・・・・・・・
 let conn = openDb('db2', "/opt/lib/libdb2.so",
  "odbc:HOSTNAME=1.0.0.1;PORT=1;DATABASE=DB;
  PROTOCOL=TCPIP;UID=id;PWD=pwd;");
 ・・・・・・・・・・・・・・・・・・・
 let ret = selectExists(conn, "select 1 from test_tbl where code = '01'");
 if (ret) { ... } else { ... }
 ・・・・・・・・・・・・・・・・・・・
 closeDb(conn, 'commit');
2.その他関数
 
■ sendToFront   拡張関数の一覧へ
概要 Back End JavaScriptのオブジェクトをFront End JavaScriptに転送する。
形式 sendToFront(var_name);
sendToFront(var_name, value);
引数 1個の場合:var_nameは変数または変数名の文字列。
      転送するオブジェクトは変数の値。
2個の場合:var_nameは文字列。valueは転送するオブジェクト
戻り値 undefined

 [Back End]
  ・・・・・・・・・・・・・・・・・・・
  let obj = { num:1, dbl:3.14, str:"ABCD",
   arr:[1,2,3], hash:{a1, b:2, c:3 } };
  sendToFront(obj); // この2行は同じ処理
  sendToFront('obj', obj);
  ・・・・・・・・・・・・・・・・・・・
 [Front End]
  ・・・・・・・・・・・・・・・・・・・
  let ret_obj = { };
  let ret = CGJS.cgjs_if(ret_obj, send_obj);
  let obj_name = ret_obj.CGI_OBJ.obj;
  // obj_nameの値は、{ num:1, dbl:3.14, str:"ABCD",
   arr:[1,2,3], hash:{a1, b:2, c:3 } }

 
■ alertToFront   拡張関数の一覧へ
概要 Frontのcgjs.jsで、AjaxでCGI起動、その終了後、
alertのポップアップ画面でメッセージを表示する。
形式 alertToFront(message);
alertToFront(Exception);
引数 message:メッセージ文字列>
Exception:Exception(Error)オブジェクト
戻り値 undefined

 [Back End]
  ・・・・・・・・・・・・・・・・・・・
  alertToFront("エラーがありました。");
  let ex = new Exception('ERR200', "例外エラーがありました。");
  alertToFront(ex);
  ・・・・・・・・・・・・・・・・・・・
 [Front End]
  ・・・・・・・・・・・・・・・・・・・
  // ブラウザ画面に"エラーがありました。"が表示される
  // ブラウザ画面に
  // "Exception: CODE=ERR200, MESSAGE='例外エラーがありました。'"
  // が表示される