сам класс: http://mojura.googlecode.com/svn/trunk/db/dbclass.onc PHP: <?php class Mojura_DBclass { var $driver= null; # database driver (object) function Mojura_DBclass ($dsn='') { if ($dsn) $this->connect($dsn); } function debug ($d= null) { return $this->driver->debug($d); } function connect ($config) { # connect ('mysql://username:userpass@localhost/database/') if (is_string($config)) $config= parse_url($config); if (!$driver= onc(dirname(__FILE__).'/drivers/'.$config['scheme'])) return !trigger_error('database driver not found',E_USER_ERROR); if (!$this->driver= $driver->newobj()) return !trigger_error("can't instantiate database driver",E_USER_ERROR); return $this->driver->connect($config); } function prepare ($q) { # prepare ('a ','b',array('c','c2',null,'c3'),array(' d')) # a "b" d $s= ''; $i= 0; foreach ($q as $n => $p): if (is_null($p)) return ''; if (is_array($p)): $i= 0; $s.= $this->prepare($p); else: $s.= ($i^=1) ? $p : $this->escape($p); endif; endforeach; return $s; } function escape ($q) { # escape ('any_string') return $this->driver->escape($p); } function ident ($q) { # ident ('table_name') return $this->driver->ident($p); } function query ($q) { # query ('insert into table values (',_GET('a'),')') if (!$q) return false; $sql= $this->prepare(func_get_args()); return $this->driver->query($sql); } function get2d () { # --//-- $q= func_get_args(); if ($q) $this->query($q); return $this->driver->get2d(); } function get2dt () { # --//-- $q= func_get_args(); if ($q) $this->query($q); return $this->driver->get2dt(); } function get1d () { # --//-- $q= func_get_args(); if ($q) $this->query($q); return $this->driver->get1d(); } function get1dt () { # --//-- $q= func_get_args(); if ($q) $this->query($q); return $this->driver->get1dt(); } function get0d () { # --//-- $q= func_get_args(); if ($q) $this->query($q); return $this->driver->get0d(); } function affected () { # affected() return $this->driver->affected(); } function lastid () { # lastid() return $this->driver->lastid(); } function begin () { # begin() return $this->driver->begin(); } function rollback () { # rollback() return $this->driver->rollback(); } function commit () { # commit return $this->driver->commit(); } function table ($table, $columns) { # table ('table', array('id'=>'INTEGER PRIMARY KEY','name'=>'TEXT',)) return $this->driver->table($table, $columns); } function insert ($table, $row) { # insert ('table', array(/*'id'=>10,*/ 'name'=>'qwerty','age'=>'13'),) return $this->driver->insert($table, $row); } function statquery () { return $this->driver->statquery(); } function statime () { return $this->driver->statime(); } } return new Mojura_DBclass(); ?> драйвер для mysql-native: http://mojura.googlecode.com/svn/trunk/ ... /mysql.onc PHP: <?php class Mojura_mysql_DBclass { var $link= null; # link to database (resource) var $res= null; # last query result (resource) var $debug= false; # debug mode trigger (bool) var $stats= array('query'=>0,'time'=>0); # statistics (hash) function newobj() {return new $this;} function debug ($d=null) { if (!is_null($d)) $this->debug= $d; return $this->debug; } function lasterror () { $errno= mysql_errno($this->link); if (!$this->res) trigger_error($errno.':'.mysql_error($this->link),E_USER_WARNING); return $errno; } function connect ($config) { $this->link= mysql_connect($config['host'].(isset($config['port']) ? ':'.$config['port'] : ''), $config['user'], $config['pass']) and (mysql_select_db(trim($config['path'],'/'), $this->link)) or $this->lasterror(); return $this->link; } function escape ($s) { return "'".mysql_real_escape_string($s, $this->link)."'"; } function ident ($s) { return '`'.$s.'`'; } function query ($sql) { if ($this->debug()) trigger_error($sql); $this->statquery(1); $time= getmicrotime(); $this->res= mysql_unbuffered_query($sql, $this->link); $this->statime(getmicrotime()-$time); $this->lasterror(); return $this->res; } function get2d() { $ret= array(); while ($row= $this->get1d()) $ret[]= $row; return $ret; } function get2dt() { $ret= array(); while ($row= $this->get1d()) foreach ($row as $name => $val) $ret[$name][]= $val; return $ret; } function get1d() { return $this->res ? mysql_fetch_assoc($this->res) : array(); } function get1dt() { if (!$this->res) return NULL; $ret= array(); while ($row= mysql_fetch_row($this->res)) $ret[]= $row[0]; return $ret; } function get0d() { if (!$this->res) return NULL; $row= mysql_fetch_row($this->res); return $row[0]; } function affected () { return mysql_affected_rows ($this->link); } function lastid () { return mysql_insert_id($this->link); } function begin () { return $this->query('BEGIN'); } function rollback () { return $this->query('ROLLBACK'); } function commit () { return $this->query('COMMIT'); } function table ($table, $columns) { $colrefs= array(); foreach ($columns as $col => $ref) $colrefs[]= $this->ident($col).' '.$ref; $res= $this->query('CREATE TABLE '.$this->ident($table).' ('.implode(',',$colrefs).');'); $this->lasterror(); return $res; } function insert ($table, $row) { $c= array(); $vars= $vals= Array(); foreach ($row as $n => $v): $vars[]= $this->ident($n); $vals[]= $this->escape($v); endforeach; $this->query ('REPLACE INTO '.$this->ident($table).' ('.implode(',',$vars).") VALUES (".implode($vals,',').")"); return $this->lastid(); } function statquery ($inc= 0) { return $this->stats['query']+=$inc; } function statime ($inc= 0) { return $this->stats['time']+=$inc; } } return new Mojura_mysql_DBclass(); ?> также етсь драйвер для mysqli и почти дописан для pdo подключение к базе данных: Код (Text): $db= new $dbclass('mysql://user:pass@host/database/'); или так: Код (Text): $db= new $dbclass('pdo:sqlite:/tmp/foo.db'); или так: Код (Text): $db= new $dbclass(); $db->connect('pdo:sqlite:/tmp/foo.db'); соответствующие драйвера подгружаются по мере необходимости. создаём таблицу: Код (Text): $db->table ('test', array('id'=>'integer primary key auto_increment','name'=>'varchar(255)','value'=>'text')); к сожалению пока не проверяются поля, но впоследствие планируется это добавить. простейший запрос: Код (Text): $db->query('drop table `test`'); query возвращает либо false, либо ресурс. так, на всякий случай ;-) запрос возвращающий массив содержащий все строки в виде ассоциативных массивов: Код (Text): $db->get2d('select * from test'); get2dt - то же самое, но возвращается транспонированная таблица (ассоциативный массив из индексных). get1d - возвращает первую строку (при последующем вызове без параметров возвращает следующую) get1dt - возвращает первый столбец индексным массивом get0d - возвращает первое значение первой строки (при повторном вызове без параметров возвращает первое значение следующей строки) query и семейство get методов поддерживают автоэкранирование и автодроп. автоэкранирование: Код (Text): $db->query('select * from table where name=',$name,' and value=1); каждое чётное значение будет проэкранировано в соответствии с используемой субд и заключено в кавычки. каждое нечётное - вставлено как есть. тобишь образуется примерно такой запрос: Код (Text): select * from table where name="вася пупкин" and value=1 при необходимости им можно передавать параметры ввиде массива: Код (Text): $db->query(array('select * from table where name=',$name,' and value=1)); автодроп: иногда бывает необходимо убрать часть запроса ввиду отсутствия значения какой-то переменной - для этого можно использовать вложенные массивы, например: Код (Text): $db->query('select * from table where value=1',array(' and name=',$name),' and 1=1'); если хотябы одно значение во вложенном массиве равно null, то вместо всего массива будет подставлена пустая строка, то есть если $name не задана - образуется такой запрос: Код (Text): select * from table where value=1 and 1=1 тут важно отметить, что после вложенного массива "чётность" сбрасывается, то есть следующий элемент проэкранирован не будет, следующий после этого - будет, следующий не будет и так далее. всё это дело преобразуется в конечный sql-запрос с помощью функции prepare() вставка строки из ассоциативного массива: Код (Text): $db->insert ('test', array('name'=>'321','value'=>'texto')); где первым параметром идёт имя таблицы, а вторым - массив задающий значения полей. если задать значение для праймари поля, и в таблице уже будет запись с таким номером - она будет замещена. например: Код (Text): $db->insert('test',array('id'=>5,'name'=>'321','value'=>'texto')); возвращает этот метод идентификатор вставленной строки. работа с транзакциями - говорящие методы begin(), rollback(), commit() statquery() и statime() - возвращают общее число выполненных запросов к базе и общее время, которое это заняло, соответственно affected() - число рядов затронутых последним запросом. у разных субд разное представление о том, что тут должно возвращаться, поэтому не рекомендую использовать. lastid() - идентификатор последней вставленной строки escape() - экранирует строку в соответствии с используемым драйвером ident() - экранирует идентификатор (например, имя таблицы или поля) в соответствии с используемым драйвером debug(true) - включает режим отладки debug(false) - выключает режим отладки debug(!debug()) - переключает режим отладки в режиме отладки в виде нотисов валятся посылаемые субд sql-запросы. другого ничего (пока) не происходит.