Song Hyo Jin's SQL Common Libraries for PHP5

License : BSD
simple summary : http://creativecommons.org/licenses/BSD/

How to use.

include_once 'xenolib/db/PDOPostgreSQL.inc.php';
$db = new SHJPDOPostgreSQL('config.ini');

// simple example
$rows = $db->query('SELECT * FROM table LIMIT 5')->fetch_all();

// class for difficult select
$sel = $db->makeQuery('select');
$sel->tables[] = 'tbl1';
$sel->fields[] = 'a';
$sel->fields[] = 'b';
$sel->orders[] = 'notice_flag';
$sel->orders[] = 'ord DESC';
$sel->wheres[] = 'board_name = :board_name';
$sel->wheres[] = 'uid = :uid';
$sel->wfields->board_name = 'qna';
$sel->wfields->uid = 21;
$sel->limit = 20;
$sel->offset = ($_GET['page'] - 1) * 20;

$rows = $sel->prepare()->exec()->fetch_all();
// or
$stmt = $sel->prepare();
$stmt->exec();
$qnarows = $stmt->fetch_all();
$sel->wfields->board_name = 'notice';
$stmt->exec();
$noticerows = $stmt->fetch_all();

$sel->offset += 20; // mssql cannot modify offset limit. must re prepare()
$stmt->exec();
$next_noticerows = $stmt->fetch_all();

// join
$sel = $db->makeQuery('select');
$sel->tables[] = 'tbl1 t1';
$sel->tables[] = 'tbl2 t2';
$sel->wheres[] = 't1.seq = t2.seq';
$sel->limit = 20;

$rows = $sel->prepare()->exec()->fetch_all();


// insert
$ins = $db->makeQuery('insert');
$ins->table = 'tbl1';
$ins->fields = $_POST; // this is just example. you must validating. you don't need escaping.
$ins->insert()->exec();

$ins = $db->makeQuery('insert');
$ins->table = 'tbl1';
$ins->fields->fld1 = 'a';
$stmt = $ins->insert();
$stmt->exec();
$ins->fields->fld1 = 'b';
$stmt->exec();

$seq = $db->id(); // last inserted id
// PostgreSQL, ORACLE need sequence name.
$seq = $db->id('test1_seq');

// PostgreSQL can fetch result.
$row = $ins->insert(true)->exec()->fetch(); // inserted row return. with not setted fields. (ex : sequence. you don't need id())

// update
$upd = $db->makeQuery('update');
$upd->table = 'tbl1';
$upd->wheres[] = 'seq = :seq';
$upd->wfields->seq = $_POST['seq'];
unset($_POST['seq']);
$upd->fields = $_POST;
$upd->update()->exec();
// PostgreSQL can fetch result.
$row = $ins->update(true)->exec()->fetch(); // updated row return. with not setted fields.

// lob
$ins = $db->makeQuery('insert');
$ins->table = 'fileTable';
// lob field type is bytea (blob, clob)
$ins->fields->file1 = array(file_get_contents('file')); // bytea || blob
$ins->fields->file1 = array(file_get_contents('file'), ''); // oracle clob
$ins->fields->file2 = fopen('file', 'r'); // bytea || blob file pointer
$ins->fields->file2 = array(fopen('file', 'r')); // oracle clob file pointer
$ins->insert()->exec();
//or
$stmt = $ins->insert();
$stmt->exec();
$stmt->exec(); // oracle can't multi execute with lob
// mssql varbinary not supported. you need store procedure with OPENROWSET() for local hdd.


$rows = $db->query('SELECT * FROM fileTable')->fetch_all();
$db->readLobs($rows); // lob pointer to string

// compress ?
$ins = $db->makeQuery('insert');
$ins->table = 'fileTable';
$ins->fields->file1 = array(bzcompress(file_get_contents('file'), 9));
$ins->insert()->exec();

$rows = $db->query('SELECT * FROM fileTable')->fetch_all();
$db->readLobs($rows, 'bzdecompress'); // callback uncompress


// exception
try {
	$db->query('error query');
} catch(Exception $e) {
echo $e->getMessage(); // alert, email for you, etc...
}


// another way for binding.
$stmt = $db->prepare('INSERT INTO test1 (fld1, fld2) VALUES (:fld1, :fld2)');
$fields->fld1 = 'asdf';
$fields->fld2 = 'zxcv';
$stmt->exec($fields);




/* reference */
SHJPDOExt(pdo connect text, user, pass, pconnect boolean) return SHJPDOExt Object
SHJPDOMySQL(config.ini) return SHJPDOMySQL Object
SHJPDOPostgreSQL(config.ini) return SHJPDOPostgreSQL Object
SHJPDOMSSQL(config.ini) return SHJPDOMSSQL Object
SHJPDOORACLE(config.ini) return SHJPDOORACLE Object
SHJPDOSQLite(sqlite3 file) return SHJPDOSQLite Object

// config.ini
;host = localhost
user = sqluser
pass = sqlpass
;charset = utf-8
db = sqldb
;port = 4321

SHJPDOExt::exec(query) return boolean : not need return? use this.
SHJPDOExt::query(query) return Statement Object : normal query. you can chaining
SHJPDOExt::prepare(query) return Statement Object : prepared query.
SHJPDOExt::makeQuery('select' || 'insert' || 'update') return Select||Insert||Update Object : easy make query and binding.
SHJPDOExt::id() return last inserted id
SHJPDOPostgreSQL::id([sequence name]) return currval : need sequence name. default value is tablename_seq_seq (*1)
SHJPDOPostgreSQL::id(sequence name or false, sequence no >= 1) : setval
SHJPDOPostgreSQL::id(sequence name or false, -1) : return nextval
SHJPDOMSSQL::id(sequence no, [table name]) : modify IDENTITY (*1)
SHJPDOORACLE::id(sequence no) return currval
SHJPDOORACLE::id(sequence no, -1) return nextval

// *1) default table name from last Insert||Update object compile

// transaction : begin after not commited end? auto rollback.
SHJPDOExt::begin()
SHJPDOExt::commit()
SHJPDOExt::rollback()
// rollback after begin maybe error.


// SHJPDOExt::makeQuery('select')
SHJPDOSelect::tables = table name array
SHJPDOSelect::fields = default * or field name array
SHJPDOSelect::orders = order by field array
SHJPDOSelect::wheres = where condition array ex) wheres = array('a = :b', 'b = :c') is WHERE (a = :b) AND (b = :c)
SHJPDOSelect::wfields = prepare bind vars for wheres ex) $sel->b = 'asdf'; $sel->c = 'zxcv';
SHJPDOSelect::offset = offset default null // bindable (mssql cannot)
SHJPDOSelect::limit = limit default null // bindable (mssql cannot)
SHJPDOSelect::compile() return compiled query text : MySQL, PostgreSQL, ORACLE
SHJPDOSelect::prepare() return prepared SHJPDOStatement
SHJPDOSelect::compile(true) return compiled query text : MySQL, PostgreSQL, ORACLE can SELECT FOR UPDATE lock. MSSQL SELECT is naturally exclusive lock.
SHJPDOSelect::prepare(true) return prepared SHJPDOStatement
// group by, having, union, etc not supported.

// SHJPDOExt::makeQuery('insert')
SHJPDOInsert::table = table name
SHJPDOInsert::fields = insert data array || object
SHJPDOInsert::insertCompile() return compiled query text
SHJPDOInsert::insert() return prepared SHJPDOStatement : with fields bind
SHJPDOPostgreSQLInsert::insert(true) : returned SHJPDOStatement can fetch result.

// SHJPDOExt::makeQuery('update')
SHJPDOUpdate::table = table name
SHJPDOUpdate::fields = update data array || object
SHJPDOUpdate::wheres = where condition array
SHJPDOUpdate::wfields = prepare bind vars for wheres
SHJPDOUpdate::updateCompile() return compiled query text
SHJPDOUpdate::update() return prepared SHJPDOStatement : with fields, wfields bind
SHJPDOPostgreSQLUpdate::update(true) : returned SHJPDOStatement can fetch result.



// statement
SHJPDOStatement::bind(fields) : binding for prepared query
SHJPDOStatement::exec() return &self for chaining : execute prepared query
SHJPDOStatement::exec(fields) : another way for binding.
SHJPDOStatement::field() return one field or false : you must select one field.
SHJPDOStatement::fetch() return fields object or false
SHJPDOStatement::fetch_assoc() return fields array or false
SHJPDOStatement::fetch_all() return all fields objects array or false
SHJPDOStatement::fetch_assoc_all() return all fields arrays array or false


// utils.inc.php
// make_table($rows, [$titles]) return html : show rows with table for debug
$rows = $stmt->fetch_all();
echo make_table($rows);
// or
// SELECT seq, name, email FROM table
$titles[] = 'primary key';
$titles[] = 'name field';
$titles[] = 'email field';
echo make_table($rows, $titles);
