We now can define views
This commit is contained in:
		
					parent
					
						
							
								43b8bdea07
							
						
					
				
			
			
				commit
				
					
						63ebbb8a16
					
				
			
		
					 5 changed files with 243 additions and 2 deletions
				
			
		
							
								
								
									
										45
									
								
								database.sql
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								database.sql
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
-- ------------------------------------------
 | 
			
		||||
-- Friendica 2020.06-dev (Red Hot Poker)
 | 
			
		||||
-- DB_UPDATE_VERSION 1338
 | 
			
		||||
-- DB_UPDATE_VERSION 1340
 | 
			
		||||
-- ------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1175,6 +1175,31 @@ CREATE TABLE IF NOT EXISTS `term` (
 | 
			
		|||
	 INDEX `guid` (`guid`(64))
 | 
			
		||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='item taxonomy (categories, tags, etc.) table';
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- TABLE tag
 | 
			
		||||
--
 | 
			
		||||
CREATE TABLE IF NOT EXISTS `tag` (
 | 
			
		||||
	`id` int unsigned NOT NULL auto_increment COMMENT '',
 | 
			
		||||
	`name` varchar(96) NOT NULL DEFAULT '' COMMENT '',
 | 
			
		||||
	`url` varbinary(255) NOT NULL DEFAULT '' COMMENT '',
 | 
			
		||||
	 PRIMARY KEY(`id`),
 | 
			
		||||
	 UNIQUE INDEX `type_name_url` (`name`,`url`),
 | 
			
		||||
	 INDEX `url` (`url`)
 | 
			
		||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='tags and mentions';
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- TABLE post-tag
 | 
			
		||||
--
 | 
			
		||||
CREATE TABLE IF NOT EXISTS `post-tag` (
 | 
			
		||||
	`uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri',
 | 
			
		||||
	`type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
 | 
			
		||||
	`tid` int unsigned NOT NULL DEFAULT 0 COMMENT '',
 | 
			
		||||
	`cid` int unsigned NOT NULL DEFAULT 0 COMMENT 'Contact id of the mentioned public contact',
 | 
			
		||||
	 PRIMARY KEY(`uri-id`,`type`,`tid`,`cid`),
 | 
			
		||||
	 INDEX `uri-id` (`tid`),
 | 
			
		||||
	 INDEX `cid` (`tid`)
 | 
			
		||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='post relation to tags';
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- TABLE thread
 | 
			
		||||
--
 | 
			
		||||
| 
						 | 
				
			
			@ -1361,4 +1386,22 @@ CREATE TABLE IF NOT EXISTS `storage` (
 | 
			
		|||
	 PRIMARY KEY(`id`)
 | 
			
		||||
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Data stored by Database storage backend';
 | 
			
		||||
 | 
			
		||||
--
 | 
			
		||||
-- VIEW tag-view
 | 
			
		||||
--
 | 
			
		||||
DROP VIEW IF EXISTS `tag-view`;
 | 
			
		||||
CREATE VIEW `tag-view` AS SELECT 
 | 
			
		||||
	`post-tag`.`uri-id` AS `uri-id`,
 | 
			
		||||
	`item-uri`.`uri` AS `uri`,
 | 
			
		||||
	`item-uri`.`guid` AS `guid`,
 | 
			
		||||
	`post-tag`.`type` AS `type`,
 | 
			
		||||
	`post-tag`.`tid` AS `tid`,
 | 
			
		||||
	`post-tag`.`cid` AS `cid`,
 | 
			
		||||
	CASE `cid` WHEN 0 THEN `tag`.`name` ELSE `contact`.`name` END AS `name`,
 | 
			
		||||
	CASE `cid` WHEN 0 THEN `tag`.`url` ELSE `contact`.`url` END AS `url`
 | 
			
		||||
	FROM `post-tag`
 | 
			
		||||
			INNER JOIN `item-uri` ON `item-uri`.id = `post-tag`.`uri-id`
 | 
			
		||||
			LEFT JOIN `tag` ON `post-tag`.`tid` = `tag`.`id`
 | 
			
		||||
			LEFT JOIN `contact` ON `post-tag`.`cid` = `contact`.`id`;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -112,6 +112,8 @@ class DBStructure
 | 
			
		|||
 | 
			
		||||
			echo "\n";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		DBView::printStructure($basePath);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -594,6 +596,8 @@ class DBStructure
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		DBView::create($verbose, $action);
 | 
			
		||||
 | 
			
		||||
		if ($action && !$install) {
 | 
			
		||||
			DI::config()->set('system', 'maintenance', 0);
 | 
			
		||||
			DI::config()->set('system', 'maintenance_reason', '');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										138
									
								
								src/Database/DBView.php
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/Database/DBView.php
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,138 @@
 | 
			
		|||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * @copyright Copyright (C) 2020, Friendica
 | 
			
		||||
 *
 | 
			
		||||
 * @license GNU AGPL version 3 or any later version
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace Friendica\Database;
 | 
			
		||||
 | 
			
		||||
use Exception;
 | 
			
		||||
use Friendica\Core\Hook;
 | 
			
		||||
use Friendica\Core\Logger;
 | 
			
		||||
use Friendica\DI;
 | 
			
		||||
use Friendica\Util\DateTimeFormat;
 | 
			
		||||
use phpDocumentor\Reflection\Types\Boolean;
 | 
			
		||||
 | 
			
		||||
require_once __DIR__ . '/../../include/dba.php';
 | 
			
		||||
 | 
			
		||||
class DBView
 | 
			
		||||
{
 | 
			
		||||
	/**
 | 
			
		||||
	 * view definition loaded from config/dbview.config.php
 | 
			
		||||
	 *
 | 
			
		||||
	 * @var array
 | 
			
		||||
	 */
 | 
			
		||||
	private static $definition = [];
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Loads the database structure definition from the config/dbview.config.php file.
 | 
			
		||||
	 * On first pass, defines DB_UPDATE_VERSION constant.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @see static/dbview.config.php
 | 
			
		||||
	 * @param boolean $with_addons_structure Whether to tack on addons additional tables
 | 
			
		||||
	 * @param string  $basePath              The base path of this application
 | 
			
		||||
	 * @return array
 | 
			
		||||
	 * @throws Exception
 | 
			
		||||
	 */
 | 
			
		||||
	public static function definition($basePath = '', $with_addons_structure = true)
 | 
			
		||||
	{
 | 
			
		||||
		if (!self::$definition) {
 | 
			
		||||
			if (empty($basePath)) {
 | 
			
		||||
				$basePath = DI::app()->getBasePath();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$filename = $basePath . '/static/dbview.config.php';
 | 
			
		||||
 | 
			
		||||
			if (!is_readable($filename)) {
 | 
			
		||||
				throw new Exception('Missing database view config file static/dbview.config.php');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			$definition = require $filename;
 | 
			
		||||
 | 
			
		||||
			if (!$definition) {
 | 
			
		||||
				throw new Exception('Corrupted database view config file static/dbview.config.php');
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			self::$definition = $definition;
 | 
			
		||||
		} else {
 | 
			
		||||
			$definition = self::$definition;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($with_addons_structure) {
 | 
			
		||||
			Hook::callAll('dbview_definition', $definition);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $definition;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static function create(bool $verbose, bool $action)
 | 
			
		||||
	{
 | 
			
		||||
		$definition = self::definition();
 | 
			
		||||
 | 
			
		||||
		foreach ($definition as $name => $structure) {
 | 
			
		||||
			self::createview($name, $structure, $verbose, $action);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static function printStructure($basePath)
 | 
			
		||||
	{
 | 
			
		||||
		$database = self::definition($basePath, false);
 | 
			
		||||
 | 
			
		||||
		foreach ($database AS $name => $structure) {
 | 
			
		||||
			echo "--\n";
 | 
			
		||||
			echo "-- VIEW $name\n";
 | 
			
		||||
			echo "--\n";
 | 
			
		||||
			self::createView($name, $structure, true, false);
 | 
			
		||||
 | 
			
		||||
			echo "\n";
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private static function createview($name, $structure, $verbose, $action)
 | 
			
		||||
	{
 | 
			
		||||
		$r = true;
 | 
			
		||||
 | 
			
		||||
		$sql_rows = [];
 | 
			
		||||
		foreach ($structure["fields"] AS $fieldname => $origin) {
 | 
			
		||||
			$sql_rows[] = $origin . " AS `" . DBA::escape($fieldname) . "`";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$sql = sprintf("DROP VIEW IF EXISTS `%s`", DBA::escape($name));
 | 
			
		||||
 | 
			
		||||
		if ($verbose) {
 | 
			
		||||
			echo $sql . ";\n";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($action) {
 | 
			
		||||
			DBA::e($sql);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		$sql = sprintf("CREATE VIEW `%s` AS SELECT \n\t", DBA::escape($name)) .
 | 
			
		||||
			implode(",\n\t", $sql_rows) . "\n\t" . $structure['query'];
 | 
			
		||||
	
 | 
			
		||||
		if ($verbose) {
 | 
			
		||||
			echo $sql . ";\n";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if ($action) {
 | 
			
		||||
			$r = DBA::e($sql);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return $r;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -51,7 +51,7 @@
 | 
			
		|||
use Friendica\Database\DBA;
 | 
			
		||||
 | 
			
		||||
if (!defined('DB_UPDATE_VERSION')) {
 | 
			
		||||
	define('DB_UPDATE_VERSION', 1339);
 | 
			
		||||
	define('DB_UPDATE_VERSION', 1340);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										56
									
								
								static/dbview.config.php
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										56
									
								
								static/dbview.config.php
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * @copyright Copyright (C) 2020, Friendica
 | 
			
		||||
 *
 | 
			
		||||
 * @license GNU AGPL version 3 or any later version
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Affero General Public License as
 | 
			
		||||
 * published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Affero General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Main view structure configuration file.
 | 
			
		||||
 *
 | 
			
		||||
 * Here are described all the view Friendica needs to work.
 | 
			
		||||
 *
 | 
			
		||||
 * Syntax (braces indicate optionale values):
 | 
			
		||||
 * "<view name>" => [
 | 
			
		||||
 *	"fields" => [
 | 
			
		||||
 *		"<field name>" => "`table`.`field`",
 | 
			
		||||
 *		"<field name>" => "`other-table`.`field`",
 | 
			
		||||
 *		"<field name>" => "SQL expression",
 | 
			
		||||
 *		...
 | 
			
		||||
 *	],
 | 
			
		||||
 *	"query" => "FROM `table` INNER JOIN `other-table` ..."
 | 
			
		||||
 *	],
 | 
			
		||||
 * ],
 | 
			
		||||
 *
 | 
			
		||||
 * If you need to make any change, make sure to increment the DB_UPDATE_VERSION constant value in dbstructure.config.php.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
	"tag-view" => [
 | 
			
		||||
		"fields" => ["uri-id" => "`post-tag`.`uri-id`",
 | 
			
		||||
			"uri" => "`item-uri`.`uri`",
 | 
			
		||||
			"guid" => "`item-uri`.`guid`",
 | 
			
		||||
			"type" => "`post-tag`.`type`",
 | 
			
		||||
			"tid" => "`post-tag`.`tid`",
 | 
			
		||||
			"cid" => "`post-tag`.`cid`",
 | 
			
		||||
			"name" => "CASE `cid` WHEN 0 THEN `tag`.`name` ELSE `contact`.`name` END",
 | 
			
		||||
			"url" => "CASE `cid` WHEN 0 THEN `tag`.`url` ELSE `contact`.`url` END"],
 | 
			
		||||
		"query" => "FROM `post-tag`
 | 
			
		||||
			INNER JOIN `item-uri` ON `item-uri`.id = `post-tag`.`uri-id`
 | 
			
		||||
			LEFT JOIN `tag` ON `post-tag`.`tid` = `tag`.`id`
 | 
			
		||||
			LEFT JOIN `contact` ON `post-tag`.`cid` = `contact`.`id`"
 | 
			
		||||
	]
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue