/** * Migrate method. * * @param boolean $version Version string. * * @return void */ public static function migrate($version = null) { $query = new Query(); $executed_migrations = Core\Utils::arrayFlatten($query->select('*')->from('migrations')->all()); $migrations_to_execute = array(); $dir = 'up'; if ($version) { /* Migrate to specific version */ preg_match('/[0-9]{10}$/', $version, $matches); if ($execute_to = $matches[0]) { $migrations_to_execute = $query->select('*')->from('migrations')->where('version > ?', array($execute_to))->order('version', 'desc')->all(); if (count($migrations_to_execute) == 0) { $migrations_to_execute = array_filter(self::$migrations, function ($item) use($executed_migrations, $execute_to) { return !in_array($item['version'], $executed_migrations) && $item['version'] <= $execute_to; }); } else { $dir = 'down'; } } } else { /* Execute all new migrations */ $migrations_to_execute = array_reverse(array_filter(self::$migrations, function ($item) use($executed_migrations) { return !in_array($item['version'], $executed_migrations); })); } foreach ($migrations_to_execute as $item) { DB\Migrate::$dir($item['version']); } }
/** * Builds a sql query. * * @param DB\Query $query SQL Query. * * @throws \DomainException DB Adapter does not support the required JOIN type. * * @return string */ private function buildSql(DB\Query $query) { $sql = array(); if ($query->type === 'select') { $sql[] = 'SELECT'; $sql[] = $query->db_fields === 'all' ? '*' : (is_array($query->db_fields) ? implode(',', $query->db_fields) : $query->db_fields); $sql[] = 'FROM'; $sql[] = $query->table; if ($query->join) { foreach ($query->join as $join) { if (!in_array($join['type'], self::getSupportedJoinTypes(), true)) { throw new \DomainException('DB Adapter not supporting the required JOIN type:' . $join['type']); } $sql[] = $join['type']; $sql[] = 'JOIN'; $sql[] = Core\Config()->DB['tables_prefix'] . $join['table']; if ($join['condition']) { $sql[] = 'ON (' . $join['condition'] . ')'; } } } if ($query->where) { $sql[] = 'WHERE'; $sql[] = implode(' AND ', array_map(function ($item) { return '(' . $item . ')'; }, $query->where)); } if ($query->order) { $sql[] = 'ORDER BY'; $sql[] = implode(', ', array_map(function ($item) { return "{$item['field']} {$item['direction']}"; }, $query->order)); } if ($query->limit) { $sql[] = 'LIMIT'; $sql[] = $query->limit; if ($query->offset) { $sql[] = 'OFFSET'; $sql[] = $query->offset; } } } elseif ($query->type === 'insert') { $sql[] = 'INSERT IGNORE INTO'; $sql[] = $query->table; $sql[] = '(' . implode(',', $query->db_fields) . ')'; $sql[] = 'VALUES'; if (is_array(current($query->bind_params))) { $sql[] = implode(',', array_map(function ($item) { return '(' . implode(',', array_map(function () { return '?'; }, $item)) . ')'; }, $query->bind_params)); $query->bind_params = Core\Utils::arrayFlatten($query->bind_params); } else { $sql[] = '(' . implode(',', array_map(function () { return '?'; }, $query->bind_params)) . ')'; } } elseif ($query->type === 'update') { $sql[] = 'UPDATE'; $sql[] = $query->table; $sql[] = 'SET'; $sql[] = implode(',', array_map(function ($item) { return $item . ' = ?'; }, $query->db_fields)); $sql[] = 'WHERE'; $sql[] = implode(' AND ', array_map(function ($item) { return '(' . $item . ')'; }, $query->where)); } elseif ($query->type === 'remove') { $sql[] = 'DELETE FROM'; $sql[] = $query->table; $sql[] = 'WHERE'; $sql[] = implode(' AND ', array_map(function ($item) { return '(' . $item . ')'; }, $query->where)); } return implode(' ', $sql); }
/** * Builds the SQL part of the query. * * @param DB\Query $query Query object. * * @throws \DomainException DB Adapter does not support the required JOIN type. * * @return string */ private function buildSql(DB\Query $query) { $sql = array(); if ($query->type === 'select') { $sql[] = 'SELECT'; $sql[] = $query->db_fields === 'all' ? '*' : (is_array($query->db_fields) ? implode(',', $query->db_fields) : $query->db_fields); $sql[] = 'FROM'; $sql[] = $query->table; if ($query->join) { foreach ($query->join as $join) { if (!in_array($join['type'], self::getSupportedJoinTypes(), true)) { throw new \DomainException('DB Adapter does not support the JOIN type:' . $join['type']); } $sql[] = $join['type']; $sql[] = 'JOIN'; $sql[] = Core\Config()->DB['tables_prefix'] . $join['table']; if ($join['condition']) { $sql[] = 'ON (' . $join['condition'] . ')'; } } } if ($query->where) { $sql[] = 'WHERE'; $sql[] = implode(' AND ', array_map(function ($item) { return '(' . $item . ')'; }, $query->where)); } if ($query->order) { $sql[] = 'ORDER BY'; $sql[] = implode(', ', array_map(function ($item) { return "{$item['field']} {$item['direction']}"; }, $query->order)); } if ($query->limit) { $sql[] = 'LIMIT'; $sql[] = $query->limit; if ($query->offset) { $sql[] = 'OFFSET'; $sql[] = $query->offset; } } } elseif ($query->type === 'insert') { $sql[] = 'INSERT IGNORE INTO'; $sql[] = $query->table; $sql[] = '(' . implode(',', $query->db_fields) . ')'; $sql[] = 'VALUES'; if (isset($query->bind_params[0]) && is_array($query->bind_params[0])) { $sql[] = implode(',', array_map(function ($item) { return '(' . implode(',', array_map(function () { return '?'; }, $item)) . ')'; }, $query->bind_params)); $query->bind_params = Core\Utils::arrayFlatten($query->bind_params); } else { $sql[] = '(' . implode(',', array_map(function () { return '?'; }, $query->bind_params)) . ')'; } } elseif ($query->type === 'update') { $sql[] = 'UPDATE'; $sql[] = $query->table; $sql[] = 'SET'; $sql[] = implode(',', array_map(function ($item) { return $item . ' = ?'; }, $query->db_fields)); $sql[] = 'WHERE'; $sql[] = implode(' AND ', array_map(function ($item) { return '(' . $item . ')'; }, $query->where)); } elseif ($query->type === 'remove') { $sql[] = 'DELETE FROM'; $sql[] = $query->table; $sql[] = 'WHERE'; $sql[] = implode(' AND ', array_map(function ($item) { return '(' . $item . ')'; }, $query->where)); } elseif ($query->type === 'create_table') { $sql[] = 'CREATE TABLE IF NOT EXISTS'; $sql[] = $query->table; $fields = array(); foreach ($query->db_fields as $field => $attributes) { $is_primary_key = false; $attrs = $this->convertAttributes($attributes); if ($pos = array_search('pk', $attrs)) { unset($attrs[$pos]); $is_primary_key = true; } $fields[] = $field . ' ' . implode(' ', $attrs); if ($is_primary_key) { $fields[] = 'PRIMARY KEY(' . $field . ')'; } } $sql[] = '(' . implode(',', $fields) . ')'; $sql[] = 'ENGINE ' . $query->table_engine; } elseif ($query->type === 'drop_table') { $sql[] = 'DROP TABLE ' . $query->table; } elseif ($query->type === 'add_columns') { $sql[] = 'ALTER TABLE'; $sql[] = $query->table; $sql[] = 'ADD COLUMN'; $fields = array(); foreach ($query->db_fields as $field => $attributes) { $is_primary_key = false; $attrs = $this->convertAttributes($attributes); if ($pos = array_search('pk', $attrs)) { unset($attrs[$pos]); $is_primary_key = true; } $fields[] = $field . ' ' . implode(' ', $attrs); if ($is_primary_key) { $fields[] = 'PRIMARY KEY(' . $field . ')'; } } $sql[] = '(' . implode(',', $fields) . ')'; } elseif ($query->type === 'drop_columns') { $sql[] = 'ALTER TABLE'; $sql[] = $query->table; $cols = array(); foreach ($query->db_fields as $column) { $cols[] = 'DROP COLUMN ' . $column; } $sql[] = implode(',', $cols); } return implode(' ', $sql); }
/** * Delete associated objects and records. * * @access private * * @return void */ private function deleteAssociations() { /* Delete objects of the habtm associations */ foreach ($this->hasAndBelongsToMany as $k => $rel) { if (isset($this->{$k}) && is_array($this->{$k})) { $association_table = $rel['table']; $key = $rel['key']; $relative_key = $rel['relative_key']; $primary_key = $this->{static::$primaryKeyField}; /* Gets the id of the original associated objects */ $query = new DB\Query(); $result = Core\DB()->run($query->select($relative_key)->from($association_table)->where("{$key} = ?", array($primary_key))); if ($result) { $original_ids = Core\Utils::arrayFlatten($result); /* Fills the ids of the current associated objects */ $passed_ids = array(); foreach ($this->{$k} as $item) { $passed_ids[] = is_object($item) ? $item->id : $item; } /* Get the difference */ $to_delete = array_diff($original_ids, $passed_ids); /* Delete if there are differences */ if (!empty($to_delete)) { /* @TODO implement the "where in (smt., smt.)" in the DB driver */ Core\DB()->run($query->remove()->from($association_table)->where("{$key} = ?", array($primary_key))->where("{$relative_key} IN (" . implode(',', array_map(function () { return '?'; }, $to_delete)) . ")", $to_delete)); } } } } }