From 4984b69366d0915e35dc4a139099551d9bac8373 Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 4 Apr 2017 18:27:31 +0200 Subject: [PATCH] - DB_Model: workaround for CI_DB_driver->_list_columns (if there are two tables with the same name in two different schemas, it returns a list of fields from the two tables) - DB_Model: changed loadTree to use the new method _list_columns - DB_Model: added the method getSchemaAndTable - Updated Studiengang_model to specify the schema when using the loadTree method - Studiengang_model: removed the titel parameter from method getAppliedStudiengang - Studiengang2 controller removed the titel parameter from method getAppliedStudiengang --- .../api/v1/organisation/Studiengang2.php | 4 +- application/core/DB_Model.php | 61 ++++++++++++++++++- .../models/organisation/Studiengang_model.php | 50 +++++++-------- 3 files changed, 82 insertions(+), 33 deletions(-) diff --git a/application/controllers/api/v1/organisation/Studiengang2.php b/application/controllers/api/v1/organisation/Studiengang2.php index 1c64e223d..dd4cf58f3 100644 --- a/application/controllers/api/v1/organisation/Studiengang2.php +++ b/application/controllers/api/v1/organisation/Studiengang2.php @@ -88,17 +88,15 @@ class Studiengang2 extends APIv1_Controller { $person_id = $this->get('person_id'); $studiensemester_kurzbz = $this->get('studiensemester_kurzbz'); - $titel = $this->get('titel'); $status_kurzbz = $this->get('status_kurzbz'); - if (isset($person_id) && isset($studiensemester_kurzbz) && isset($titel) && isset($status_kurzbz)) + if (isset($person_id) && isset($studiensemester_kurzbz) && isset($status_kurzbz)) { $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); $result = $this->StudiengangModel->getAppliedStudiengang( $person_id, $studiensemester_kurzbz, - $titel, $status_kurzbz ); diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index a0bc1e8f7..27985c958 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -8,6 +8,7 @@ class DB_Model extends FHC_Model const PGSQL_BOOLEAN_TRUE = 't'; const PGSQL_BOOLEAN_FALSE = 'f'; const MODEL_POSTFIX = '_model'; + const DEFAULT_SCHEMA = 'public'; protected $dbTable; // Name of the DB-Table for CI-Insert, -Update, ... protected $pk; // Name of the PrimaryKey for DB-Update, Load, ... @@ -226,6 +227,8 @@ class DB_Model extends FHC_Model * - Adding support for composed primary key * - Adding support for cascading side tables (useful?) * + * NOTE: sub queries are not supported in the from clause + * * @return array */ public function loadTree($mainTable, $sideTables, $where = null, $sideTablesAliases = null) @@ -246,13 +249,26 @@ class DB_Model extends FHC_Model $select = ''; for ($t = 0; $t < count($tables); $t++) { - $fields = $this->db->list_fields($tables[$t]); // list of the columns of the current table + // Get the schema if it is specified + $schemaAndTable = $this->getSchemaAndTable($tables[$t]); + // Discard the schema, not needed in the next steps + $tables[$t] = $schemaAndTable->table; + + // List of the columns of the current table + // NOTE: $this->db->list_fields($tables[$t]) doesn't work if there are two tables with + // the same name in two different schemas, use this workaround + $fields = array(); + if (isSuccess($lstColumns = $this->_list_columns($schemaAndTable->schema, $schemaAndTable->table))) + { + $fields = $lstColumns->retval; + } + for ($f = 0; $f < count($fields); $f++) { // To avoid overwriting of the properties within the object returned by CI // will be given an alias to every column, that will be composed with the following schema // . AS _ - $select .= $tables[$t] . '.' . $fields[$f] . ' AS ' . $tables[$t] . '_' . $fields[$f]; + $select .= $tables[$t] . '.' . $fields[$f]->column_name . ' AS ' . $tables[$t] . '_' . $fields[$f]->column_name; if ($f < count($fields) - 1) $select .= ', '; } @@ -640,6 +656,32 @@ class DB_Model extends FHC_Model return $result; } + /** + * Get schema and table name from the parameter + * If no schema are specified it will returns the parameter as table name, + * and the default schema as schema + * Ex: + * If the parameters is 'lehre.tbl_studienplan' it will returns the following object: + * obj + * |--->schema: lehre + * |--->table: tbl_studienplan + */ + protected function getSchemaAndTable($schemaAndTable) + { + $result = new stdClass(); + $result->schema = DB_Model::DEFAULT_SCHEMA; + $result->table = $schemaAndTable; + + // If a schema is specified + if (($pos = strpos($schemaAndTable, '.')) !== false) + { + $result->schema = substr($schemaAndTable, 0, $pos); + $result->table = substr($schemaAndTable, $pos + 1); + } + + return $result; + } + /** * Checks if the caller is entitled to perform this operation with this right */ @@ -755,4 +797,19 @@ class DB_Model extends FHC_Model return false; } + + /** + * Workaround of CI_DB_driver->_list_columns + * CI_DB_driver->list_fields($tableName), that calls CI_DB_postgre_driver->_list_columns, + * doesn't work if there are two tables with the same name in two different schemas + */ + private function _list_columns($schema, $table) + { + $query = 'SELECT column_name + FROM information_schema.columns + WHERE LOWER(table_schema) = ? + AND LOWER(table_name) = ?'; + + return $this->execQuery($query, array(strtolower($schema), strtolower($table))); + } } \ No newline at end of file diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 54dcaf242..ecc49754c 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -116,9 +116,9 @@ class Studiengang_model extends DB_Model $this->addOrder('lehre.tbl_studienplan.studienplan_id'); $result = $this->loadTree( - 'tbl_studiengang', + 'public.tbl_studiengang', array( - 'tbl_studienplan' + 'lehre.tbl_studienplan' ), array( 'lehre.tbl_studienplan_semester.studiensemester_kurzbz' => $studiensemester_kurzbz, @@ -158,10 +158,10 @@ class Studiengang_model extends DB_Model $this->addOrder('lehre.tbl_studienplan.studienplan_id'); $result = $this->loadTree( - 'tbl_studiengang', + 'public.tbl_studiengang', array( - 'tbl_studienplan', - 'tbl_akadgrad' + 'lehre.tbl_studienplan', + 'lehre.tbl_akadgrad' ), 'public.tbl_studiengang.aktiv = TRUE AND public.tbl_studiengang.onlinebewerbung = TRUE @@ -180,41 +180,35 @@ class Studiengang_model extends DB_Model } /** - * TODO + * */ - public function getAppliedStudiengang($person_id, $studiensemester_kurzbz, $titel, $status_kurzbz) + public function getAppliedStudiengang($person_id, $studiensemester_kurzbz, $status_kurzbz) { - // Then join with table + // Then join with table public.tbl_prestudent $this->addJoin('public.tbl_prestudent', 'studiengang_kz'); - // Join table + // Join table public.tbl_prestudentstatus $this->addJoin('public.tbl_prestudentstatus', 'prestudent_id'); - // Then join with table + // Then join with table lehre.tbl_studienplan $this->addJoin('lehre.tbl_studienplan', 'studienplan_id'); - // Then join with table - $this->addJoin( - '( - SELECT * - FROM public.tbl_notizzuordnung INNER JOIN public.tbl_notiz n USING(notiz_id) - WHERE n.titel = \''.$titel.'\') tbl_nn', - 'prestudent_id', - 'LEFT' - ); + // Then join with table public.tbl_notizzuordnung + $this->addJoin('public.tbl_notizzuordnung', 'prestudent_id', 'LEFT'); + // Then join with table public.tbl_notiz + $this->addJoin('public.tbl_notiz', 'notiz_id', 'LEFT'); // Ordering by studiengang_kz and studienplan_id $this->addOrder('public.tbl_studiengang.bezeichnung'); $result = $this->loadTree( - 'tbl_studiengang', + 'public.tbl_studiengang', array( - 'tbl_prestudent', - 'tbl_prestudentstatus', - 'tbl_studienplan', - 'tbl_nn' + 'public.tbl_prestudent', + 'public.tbl_prestudentstatus', + 'lehre.tbl_studienplan', + 'public.tbl_notiz' ), 'public.tbl_prestudent.person_id = '.$person_id. ' AND public.tbl_prestudentstatus.studiensemester_kurzbz = \''.$studiensemester_kurzbz.'\''. - ' AND (public.tbl_prestudentstatus.status_kurzbz = \'Interessent\' OR public.tbl_prestudentstatus.status_kurzbz = \'Bewerber\')' - , + ' AND (public.tbl_prestudentstatus.status_kurzbz = \'Interessent\' OR public.tbl_prestudentstatus.status_kurzbz = \'Bewerber\')', array( 'prestudenten', 'prestudentstatus', @@ -260,8 +254,8 @@ class Studiengang_model extends DB_Model $this->addOrder('tbl_studiengang.bezeichnung, tbl_reihungstest.stufe, tbl_reihungstest.datum'); return $this->loadTree( - 'tbl_studiengang', - array('tbl_reihungstest'), + 'public.tbl_studiengang', + array('public.tbl_reihungstest'), 'tbl_prestudentstatus.status_kurzbz = \'Interessent\' AND (tbl_prestudentstatus.rt_stufe >= tbl_reihungstest.stufe OR tbl_reihungstest.stufe IS NULL) AND (tbl_prestudent.aufnahmegruppe_kurzbz = tbl_reihungstest.aufnahmegruppe_kurzbz OR tbl_reihungstest.aufnahmegruppe_kurzbz IS NULL)