_dba = &$dba; } function &executeQuery($sql /*, [arg]... */) { return $this->_dba->executeQuery($sql, func_get_args()); } function &executeUpdate($sql /*, [arg]... */) { return $this->_dba->executeUpdate($sql, func_get_args()); } function &getTable($model) { if (!$this->isLoaded($model)) { $this->loadModel($model); } return $this->_tables[$model]; } function &getFinder($model) { if (!$this->isLoaded($model)) { $this->loadModel($model); } return $this->_finders[$model]; } function isLoaded($model) { return isset($this->_tables[$model]); } function loadModel($model) { assert(!$this->isLoaded($model)); $filename = FA_MODEL_DIR . "/{$model}_model.php"; if (!is_file($filename) || !is_readable($filename)) { trigger_error("No such model: {$table}", E_USER_ERROR); } require $filename; $class = $model . "Definition"; $table = &new $class($this); $finder = &new FARecordFinder($this, $table) $this->_tables[$model] = &$table; $this->_finders[$model] = &$finder; } } class FAQuery { var $_data = array(); var $_select; var $_from; var $_where; var $_order = ''; var $_group = ''; function FAQuery($select, $from, $where = '') { $this->_select = $select; $this->_from = $from; $this->_where = $where; } function addFrom($from) { $this->_from .= ", $from"; } function addWhere($where, $type = 'AND') { $this->_where .= ($this->_where) ? " $type $where" : $where; } function bind($offset, $value) { $this->_data[$offset] = $value; } function getArgs() { return $this->_data; } function getSql() { $sql = "SELECT {$this->_select}"; $sql .= " FROM {$this->_from}"; $sql .= ($this->_where) ? " WHERE {$this->_where}" : ''; $sql .= ($this->_order) ? " ORDER BY {$this->_order}" : ''; return $sql; } } class FARecord { var $_model; var $_table; var $_data = array(); var $_dirty = array(); function FARecord(&$model, &$table, $data = NULL) { $this->_model = &$model; $this->_table = &$table; if ($this->_data === NULL) { $this->_saved = FALSE; } else { $this->_data = $data; $this->_saved = TRUE; } } function &get($key) { $ret = NULL; if (isset($this->_cache[$key])) { $ret = &$this->_cache[$key]; } elseif ($this->_table->isRelation($key)) { $rel = &$this->_table->getRelation($key); $query = &$rel->createQuery($this->getId()); $finder = &$this->_model->getFinder($this->_table->getName()); if ($rel->isPlural()) { $ret = &$finder->findAllByQuery($query); } else { $ret = &$finder->findByQuery($query); } $this->_cache[$key] = &$ret; } elseif (method_exists($this, "get$key") && !method_exists(__CLASS__, "get$key")) { eval ("\$ret = &\$this->get$key();"); $this->_cache[$key] = &$ret; } elseif (isset($this->_dirty[$key])) { $ret = $this->_dirty[$key]; } elseif (isset($this->_data[$key])) { $ret = $this->_data[$key]; } return $ret; } function getId() { return $this->_data[$this->_table->getPrimaryKey()]; } } class FATable { var $_fks = array(); var $_model; function FATable(&$model) { $this->_model = &$model; $this->init(); } function getForeignKey($table) { return $this->_fks[$table]; } function getName() { return substr_utf(get_class($this), 0, -strlen_utf('Table')); } function getPrimaryKey() { assert(FALSE); } function getRecordClass() { $class = $this->getName() . 'Record'; if (!class_exists($class)) { $class = FARecord; } return $class; } function getRecordSetClass() { $class = $this->getName() . 'Iterator'; if (!class_exists($class)) { $class = FARecord; } return $class; } function getTable() { assert(FALSE); } /** * @table String This is the table we will are searching * @join String The table that holds the back reference to this table */ function hasMany($table, $join) { if ($join == $table) { // The joined table has the foreign key $relation = &new FAOneToManyRelation($this, $this->_model->getTable($table)); } else { // An intermediate table ($join) joins a many-to-many $relation = &new FAManyToManyRelation($this, $this->_model->getTable($join), $this->_model->getTable($table)); } } function hasOne($table, $fk) { $this->_fks[$table] = $fk; } } class UsersTable extends FATable { function getPrimaryKey() { return 'user_id'; } function getTable() { return 'k4_users'; } function init() { //$this->hasMany('Roles', 'UsersRoles'); } } class UsersRolesTable extends FATable { function getTable() { return 'k4_user_roles'; } function init() { $this->hasOne('Users', 'user_id'); $this->hasOne('Roles', 'role_id'); } } class RolesTable extends FATable { function getPrimaryKey() { return 'role_id'; } function getTable() { return 'k4_roles'; } function init() { $this->hasMany('Perms', 'Perms'); $this->hasMany('Users', 'UsersRoles'); } } $left = &new UsersTable; $middle = &new UsersRolesTable; $right = &new RolesTable; $left->init(); $middle->init(); $right->init(); $rel = &new FAManyToManyRelation($left, $middle, $right); $query = &$rel->createQuery(1); var_dump($query); ?>