use Friendica\Core\Hook;
use Friendica\Core\Logger;
use Friendica\DI;
+use Friendica\Model\Item;
+use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
/**
public static function update($basePath, $verbose, $action, $install = false, array $tables = null, array $definition = null)
{
if ($action && !$install) {
+ if (self::isUpdating()) {
+ return DI::l10n()->t('Another database update is currently running.');
+ }
+
DI::config()->set('system', 'maintenance', 1);
DI::config()->set('system', 'maintenance_reason', DI::l10n()->t('%s: Database update', DateTimeFormat::utcNow() . ' ' . date('e')));
}
}
}
- foreach ($existing_foreign_keys as $constraint => $param) {
- $sql2 = self::dropForeignKey($constraint);
+ foreach ($existing_foreign_keys as $param) {
+ $sql2 = self::dropForeignKey($param['CONSTRAINT_NAME']);
if ($sql3 == "") {
$sql3 = "ALTER" . $ignore . " TABLE `" . $temp_name . "` " . $sql2;
if (DBA::isResult($foreign_keys)) {
foreach ($foreign_keys as $foreign_key) {
- $constraint = $foreign_key['CONSTRAINT_NAME'];
- unset($foreign_key['CONSTRAINT_NAME']);
+ $parameters = ['foreign' => [$foreign_key['REFERENCED_TABLE_NAME'] => $foreign_key['REFERENCED_COLUMN_NAME']]];
+ $constraint = self::getConstraintName($table, $foreign_key['COLUMN_NAME'], $parameters);
$foreigndata[$constraint] = $foreign_key;
}
}
$fielddata[$field['COLUMN_NAME']]['not null'] = true;
}
- if (isset($field['COLUMN_DEFAULT'])) {
- $fielddata[$field['COLUMN_NAME']]['default'] = $field['COLUMN_DEFAULT'];
+ if (isset($field['COLUMN_DEFAULT']) && ($field['COLUMN_DEFAULT'] != 'NULL')) {
+ $fielddata[$field['COLUMN_NAME']]['default'] = trim($field['COLUMN_DEFAULT'], "'");
}
if (!empty($field['EXTRA'])) {
$foreign_table = array_keys($parameters['foreign'])[0];
$foreign_field = array_values($parameters['foreign'])[0];
- $constraint = self::getConstraintName($tablename, $fieldname, $parameters);
-
- $sql = "CONSTRAINT `" . $constraint . "` FOREIGN KEY (`" . $fieldname . "`)" .
- " REFERENCES `" . $foreign_table . "` (`" . $foreign_field . "`)";
+ $sql = "FOREIGN KEY (`" . $fieldname . "`) REFERENCES `" . $foreign_table . "` (`" . $foreign_field . "`)";
if (!empty($parameters['foreign']['on update'])) {
$sql .= " ON UPDATE " . strtoupper($parameters['foreign']['on update']);
return true;
}
+ /**
+ * Check if a foreign key exists for the given table field
+ *
+ * @param string $table
+ * @param string $field
+ * @return boolean
+ */
+ public static function existsForeignKeyForField(string $table, string $field)
+ {
+ return DBA::exists(['INFORMATION_SCHEMA' => 'KEY_COLUMN_USAGE'],
+ ["`TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ? AND `REFERENCED_TABLE_SCHEMA` IS NOT NULL",
+ DBA::databaseName(), $table, $field]);
+ }
/**
* Check if a table exists
*
return DBA::toArray($stmtColumns);
}
- private static function checkInitialValues()
+ /**
+ * Check if initial database values do exist - or create them
+ */
+ public static function checkInitialValues()
{
- if (DBA::tableExists('contact') && !DBA::exists('contact', ['id' => 0])) {
+ if (self::existsTable('verb') && !DBA::exists('verb', ['id' => 1])) {
+ foreach (Item::ACTIVITIES as $index => $activity) {
+ DBA::insert('verb', ['id' => $index + 1, 'name' => $activity], true);
+ }
+ }
+
+ if (self::existsTable('contact') && !DBA::exists('contact', ['id' => 0])) {
DBA::insert('contact', ['nurl' => '']);
$lastid = DBA::lastInsertId();
if ($lastid != 0) {
}
}
- if (DBA::tableExists('permissionset') && !DBA::exists('permissionset', ['id' => 0])) {
- DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']);
- $lastid = DBA::lastInsertId();
- if ($lastid != 0) {
- DBA::update('permissionset', ['id' => 0], ['id' => $lastid]);
+ if (self::existsTable('permissionset')) {
+ if (!DBA::exists('permissionset', ['id' => 0])) {
+ DBA::insert('permissionset', ['allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '']);
+ $lastid = DBA::lastInsertId();
+ if ($lastid != 0) {
+ DBA::update('permissionset', ['id' => 0], ['id' => $lastid]);
+ }
+ }
+ if (!self::existsForeignKeyForField('item', 'psid')) {
+ $sets = DBA::p("SELECT `psid`, `item`.`uid`, `item`.`private` FROM `item`
+ LEFT JOIN `permissionset` ON `permissionset`.`id` = `item`.`psid`
+ WHERE `permissionset`.`id` IS NULL AND NOT `psid` IS NULL");
+ while ($set = DBA::fetch($sets)) {
+ if (($set['private'] == Item::PRIVATE) && ($set['uid'] != 0)) {
+ $owner = User::getOwnerDataById($set['uid']);
+ if ($owner) {
+ $permission = '<' . $owner['id'] . '>';
+ } else {
+ $permission = '<>';
+ }
+ } else {
+ $permission = '';
+ }
+ $fields = ['id' => $set['psid'], 'uid' => $set['uid'], 'allow_cid' => $permission,
+ 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => ''];
+ DBA::insert('permissionset', $fields);
+ }
+ DBA::close($sets);
}
}
- if (DBA::tableExists('tag') && !DBA::exists('tag', ['id' => 0])) {
+ if (self::existsTable('tag') && !DBA::exists('tag', ['id' => 0])) {
DBA::insert('tag', ['name' => '']);
$lastid = DBA::lastInsertId();
if ($lastid != 0) {
DBA::update('tag', ['id' => 0], ['id' => $lastid]);
}
- }
+ }
+
+ if (!self::existsForeignKeyForField('tokens', 'client_id')) {
+ $tokens = DBA::p("SELECT `tokens`.`id` FROM `tokens`
+ LEFT JOIN `clients` ON `clients`.`client_id` = `tokens`.`client_id`
+ WHERE `clients`.`client_id` IS NULL");
+ while ($token = DBA::fetch($tokens)) {
+ DBA::delete('tokens', ['id' => $token['id']]);
+ }
+ DBA::close($tokens);
+ }
+ }
+
+ /**
+ * Checks if a database update is currently running
+ *
+ * @return boolean
+ */
+ private static function isUpdating()
+ {
+ $isUpdate = false;
+
+ $processes = DBA::select(['information_schema' => 'processlist'], ['info'],
+ ['db' => DBA::databaseName(), 'command' => ['Query', 'Execute']]);
+
+ while ($process = DBA::fetch($processes)) {
+ $parts = explode(' ', $process['info']);
+ if (in_array(strtolower(array_shift($parts)), ['alter', 'create', 'drop', 'rename'])) {
+ $isUpdate = true;
+ }
+ }
+
+ DBA::close($processes);
+
+ return $isUpdate;
}
}