Release of v5.0.0-alpha8

Add power path override option on component level. Fix the sql build feature. #1032.
This commit is contained in:
2024-04-06 23:41:34 +02:00
parent 2f64eec95b
commit 2b7b8f90e1
762 changed files with 1900 additions and 1246 deletions

View File

@@ -0,0 +1,290 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Database;
use Joomla\CMS\Date\Date;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Interfaces\InsertInterface;
use VDM\Joomla\Abstraction\Database;
/**
* Database Insert Class
*
* @since 3.2.0
*/
final class Insert extends Database implements InsertInterface
{
/**
* Switch to set the defaults
*
* @var bool
* @since 1.2.0
**/
protected bool $defaults = true;
/**
* Switch to prevent/allow defaults from being added.
*
* @param bool $trigger toggle the defaults
*
* @return void
* @since 3.2.0
**/
public function defaults(bool $trigger = true)
{
$this->defaults = $trigger;
}
/**
* Insert rows to the database (with remapping and filtering columns option)
*
* @param array $data Dataset to store in database [array of arrays (key => value)]
* @param string $table The table where the data is being added
* @param array $columns Data columns for remapping and filtering
*
* @return bool
* @since 3.2.0
**/
public function rows(array $data, string $table, array $columns = []): bool
{
if (!ArrayHelper::check($data))
{
return false;
}
if ($columns === [])
{
$columns = $this->getArrayColumns($data);
}
return ($columns === []) ? false : $this->insert($data, $table, $columns, true);
}
/**
* Insert items to the database (with remapping and filtering columns option)
*
* @param array $data Data to store in database (array of objects)
* @param string $table The table where the data is being added
* @param array $columns Data columns for remapping and filtering
*
* @return bool
* @since 3.2.0
**/
public function items(array $data, string $table, array $columns = []): bool
{
if (!ArrayHelper::check($data))
{
return false;
}
if ($columns === [])
{
$columns = $this->getObjectsColumns($data);
}
return ($columns === []) ? false : $this->insert($data, $table, $columns, false);
}
/**
* Insert row to the database
*
* @param array $data Dataset to store in database (key => value)
* @param string $table The table where the data is being added
*
* @return bool
* @since 3.2.0
**/
public function row(array $data, string $table): bool
{
return $this->rows([$data], $table);
}
/**
* Insert item to the database
*
* @param object $data Dataset to store in database (key => value)
* @param string $table The table where the data is being added
*
* @return bool
* @since 3.2.0
**/
public function item(object $data, string $table): bool
{
return $this->items([$data], $table);
}
/**
* Get columns from data array
*
* @param array $data Data array
*
* @return array
* @since 3.2.0
**/
protected function getArrayColumns(array &$data): array
{
$row = array_values($data)[0];
if (!ArrayHelper::check($row))
{
return [];
}
$columns = array_keys($row);
return array_combine($columns, $columns);
}
/**
* Get columns from data objects
*
* @param array $data Data objects
*
* @return array
* @since 3.2.0
**/
protected function getObjectsColumns(array &$data): array
{
$row = array_values($data)[0];
if (!is_object($row))
{
return [];
}
$columns = get_object_vars($row);
return array_combine(array_keys($columns), array_keys($columns));
}
/**
* Insert data into the database
*
* @param array $data Data to store in database
* @param string $table The table where the data is being added
* @param array $columns Data columns for remapping and filtering
* @param bool $isArray Whether the data is an array of arrays or an array of objects
*
* @return bool
* @since 3.2.0
**/
protected function insert(array &$data, string $table, array $columns, bool $isArray): bool
{
// set joomla default columns
$add_created = false;
$add_version = false;
$add_published = false;
// check if we should load the defaults
if ($this->defaults)
{
// get the date
$date = (new Date())->toSql();
if (!isset($columns['created']))
{
$columns['created'] = ' (o_O) ';
$add_created = true;
}
if (!isset($columns['version']))
{
$columns['version'] = ' (o_O) ';
$add_version = true;
}
if (!isset($columns['published']))
{
$columns['published'] = ' (o_O) ';
$add_published = true;
}
// the (o_O) prevents an empty value from being loaded
}
// get a query object
$query = $this->db->getQuery(true);
// set the query targets
$query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns)));
// limiting factor on the amount of rows to insert before we reset the query
$limit = 300;
// set the insert values
foreach ($data as $nr => $value)
{
// check the limit
if ($limit <= 1)
{
// execute and reset the query
$this->db->setQuery($query);
$this->db->execute();
// reset limit
$limit = 300;
// get a query object
$query = $this->db->getQuery(true);
// set the query targets
$query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns)));
}
$row = [];
foreach ($columns as $column => $key)
{
if (' (o_O) ' !== $key)
{
$row[] = ($isArray && isset($value[$key])) ? $this->quote($value[$key])
: ((!$isArray && isset($value->{$key})) ? $this->quote($value->{$key}) : '');
}
}
// set joomla default columns
if ($add_created)
{
$row[] = $this->db->quote($date);
}
if ($add_version)
{
$row[] = 1;
}
if ($add_published)
{
$row[] = 1;
}
// add to query
$query->values(implode(',', $row));
// decrement the limiter
$limit--;
// clear the data from memory
unset($data[$nr]);
}
// execute the final query
$this->db->setQuery($query);
$this->db->execute();
// always reset the default switch
$this->defaults();
return true;
}
}

View File

@@ -0,0 +1,469 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Database;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Interfaces\LoadInterface;
use VDM\Joomla\Abstraction\Database;
/**
* Database Load
*
* @since 3.2.0
*/
final class Load extends Database implements LoadInterface
{
/**
* Load data rows as an array of associated arrays
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
* @param int|null $limit Limit the number of values returned
*
* @return array|null
* @since 3.2.0
**/
public function rows(array $select, array $tables, ?array $where = null,
?array $order = null, ?int $limit = null): ?array
{
// set key if found
$key = '';
if (isset($select['key']))
{
if (is_string($select['key']))
{
$key = $select['key'];
}
unset($select['key']);
}
// check if we can get many rows
if ($this->many($select, $tables, $where, $order, $limit))
{
// return associated arrays from the table records
return $this->db->loadAssocList($key);
}
// data does not exist
return null;
}
/**
* Load data rows as an array of objects
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
* @param int|null $limit Limit the number of values returned
*
* @return array|null
* @since 3.2.0
**/
public function items(array $select, array $tables, ?array $where = null,
?array $order = null, ?int $limit = null): ?array
{
// set key if found
$key = '';
if (isset($select['key']))
{
if (is_string($select['key']))
{
$key = $select['key'];
}
unset($select['key']);
}
// check if we can get many rows
if ($this->many($select, $tables, $where, $order, $limit))
{
// return associated arrays from the table records
return $this->db->loadObjectList($key);
}
// data does not exist
return null;
}
/**
* Load data row as an associated array
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
*
* @return array|null
* @since 3.2.0
**/
public function row(array $select, array $tables, ?array $where = null, ?array $order = null): ?array
{
// check if we can get one row
if ($this->one($select, $tables, $where, $order))
{
return $this->db->loadAssoc();
}
// data does not exist
return null;
}
/**
* Load data row as an object
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
*
* @return object|null
* @since 3.2.0
**/
public function item(array $select, array $tables, ?array $where = null, ?array $order = null): ?object
{
// check if we can get one row
if ($this->one($select, $tables, $where, $order))
{
return $this->db->loadObject();
}
// data does not exist
return null;
}
/**
* Get the max value based on a filtered result from a given table
*
* @param string $field The field key
* @param string $tables The tables
* @param array $filter The filter keys
*
* @return int|null
* @since 3.2.0
**/
public function max($field, array $tables, array $filter): ?int
{
// only do check if we have the table set
if (isset($tables['a']))
{
// get the query
$query = $this->query(["all" => "MAX(`$field`)"], $tables, $filter);
// Load the max number
$this->db->setQuery($query);
$this->db->execute();
// check if we have values
if ($this->db->getNumRows())
{
return (int) $this->db->loadResult();
}
}
// data does not exist
return null;
}
/**
* Count the number of items based on filter result from a given table
*
* @param string $tables The table
* @param array $filter The filter keys
*
* @return int|null
* @since 3.2.0
**/
public function count(array $tables, array $filter): ?int
{
// only do check if we have the table set
if (isset($tables['a']))
{
// get the query
$query = $this->query(["all" => 'COUNT(*)'], $tables, $filter);
// Load the max number
$this->db->setQuery($query);
$this->db->execute();
// check if we have values
if ($this->db->getNumRows())
{
return (int) $this->db->loadResult();
}
}
// data does not exist
return null;
}
/**
* Load one value from a row
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
*
* @return mixed
* @since 3.2.0
**/
public function value(array $select, array $tables, ?array $where = null, ?array $order = null)
{
// check if we can get one value
if ($this->one($select, $tables, $where, $order))
{
return $this->db->loadResult();
}
// data does not exist
return null;
}
/**
* Load many
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
* @param int|null $limit Limit the number of values returned
*
* @return bool
* @since 3.2.0
**/
protected function many(array $select, array $tables, ?array $where = null,
?array $order = null, ?int $limit = null): bool
{
// only do check if we have the table set
if (isset($tables['a']))
{
// get the query
$query = $this->query($select, $tables, $where, $order, $limit);
// Load the items
$this->db->setQuery($query);
$this->db->execute();
// check if we have values
if ($this->db->getNumRows())
{
return true;
}
}
// data does not exist
return false;
}
/**
* Load one
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
*
* @return bool
* @since 3.2.0
**/
protected function one(array $select, array $tables, ?array $where = null, ?array $order = null): bool
{
// only do check if we have the table set
if (isset($tables['a']))
{
// get the query
$query = $this->query($select, $tables, $where, $order);
// Load the item
$this->db->setQuery($query, 0, 1);
$this->db->execute();
// check if we have values
if ($this->db->getNumRows())
{
return true;
}
}
// data does not exist
return false;
}
/**
* Get the query object
*
* @param array $select Array of selection keys
* @param array $tables Array of tables to search
* @param array|null $where Array of where key=>value match exist
* @param array|null $order Array of how to order the data
* @param int|null $limit Limit the number of values returned
*
* @return object|null The query object (DatabaseQuery)
* @since 3.2.0
**/
protected function query(array $select, array $tables, ?array $where = null,
?array $order = null, ?int $limit = null): ?object
{
$query = $this->db->getQuery(true);
// check if we have an all selection set
if (isset($select['all']))
{
// all selection example array: ['all' => ['a.*', 'b.*']]
if (ArrayHelper::check($select['all']))
{
foreach ($select['all'] as $select_all)
{
// set target selection
$query->select(
$select_all
);
}
}
// all selection example string: ['all' =>'a.*']
elseif (is_string($select['all']))
{
// set target selection
$query->select(
$select['all']
);
}
unset($select['all']);
}
// load the table where join
if (ArrayHelper::check($select))
{
// set target selection
$query->select(
$this->db->quoteName(
array_keys($select),
array_values($select)
)
);
}
// set main table
$query->from($this->db->quoteName($this->getTable($tables['a']), 'a'));
// remove main table
unset($tables['a']);
// load the table where join
if (ArrayHelper::check($tables))
{
foreach ($tables as $as => $table)
{
$query->join(
'LEFT', $this->db->quoteName(
$this->getTable($table['name']), $as
) . ' ON (' . $this->db->quoteName($table['join_on'])
. ' = ' . $this->db->quoteName($table['as_on']) . ')'
);
}
}
// load the table where getters
if (ArrayHelper::check($where))
{
foreach ($where as $key => $value)
{
if (ArrayHelper::check($value))
{
if (isset($value['value']) && isset($value['operator']))
{
// check if value needs to be quoted
$quote = $value['quote'] ?? true;
if (!$quote)
{
if (ArrayHelper::check($value['value']))
{
// add the where by array
$query->where($this->db->quoteName($key) . ' ' .
$value['operator'] . ' (' .
implode(',', $value['value'])
. ')'
);
}
else
{
// add the where
$query->where($this->db->quoteName($key) . ' ' .
$value['operator'] . ' ' . $value['value']);
}
}
else
{
if (ArrayHelper::check($value['value']))
{
// add the where by array
$query->where($this->db->quoteName($key) . ' ' .
$value['operator'] . ' (' .
implode(',',
array_map(
fn($val) => $this->quote($val),
$value['value']
)
)
. ')'
);
}
else
{
// add the where
$query->where($this->db->quoteName($key) . ' ' .
$value['operator'] . ' ' . $this->quote($value['value']));
}
}
}
else
{
// we should through an exception
// for security we just return nothing for now
return null;
}
}
else
{
// add the where
$query->where($this->db->quoteName($key) .
' = ' . $this->quote($value));
}
}
}
// load the row ordering
if (ArrayHelper::check($order))
{
foreach ($order as $key => $direction)
{
// add the ordering
$query->order($this->db->quoteName($key) .
' ' . $direction);
}
}
// only return a limited number
if (is_numeric($limit))
{
$query->setLimit($limit);
}
return $query;
}
}

View File

@@ -0,0 +1,188 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Database;
use VDM\Joomla\Interfaces\UpdateInterface;
use VDM\Joomla\Abstraction\Database;
/**
* Database Update Class
*
* @since 3.2.0
*/
final class Update extends Database implements UpdateInterface
{
/**
* Update rows in the database (with remapping and filtering columns option)
*
* @param array $data Dataset to update in database [array of arrays (key => value)]
* @param string $key Dataset key column to use in updating the values in the Database
* @param string $table The table where the data is being updated
* @param array $columns Data columns for remapping and filtering
*
* @return bool
* @since 3.2.0
**/
public function rows(array $data, string $key, string $table, array $columns = []): bool
{
// set the update columns
if ($data === [] || strlen($key) == 0)
{
return false;
}
// set the update values
foreach ($data as $values)
{
if ($columns !== [])
{
// load only what is part of the columns set
$row = [];
foreach ($columns as $column => $key_)
{
if (isset($values[$key_]))
{
$row[$column] = $values[$key_];
}
}
// update the row
$this->row($row, $key, $table);
}
else
{
// update the row
$this->row((array) $values, $key, $table);
}
}
return true;
}
/**
* Update items in the database (with remapping and filtering columns option)
*
* @param array $data Data to updated in database (array of objects)
* @param string $key Dataset key column to use in updating the values in the Database
* @param string $table The table where the data is being update
* @param array $columns Data columns for remapping and filtering
*
* @return bool
* @since 3.2.0
**/
public function items(array $data, string $key, string $table, array $columns = []): bool
{
// set the update columns
if ($data === [] || strlen($key) == 0)
{
return false;
}
// set the update values
foreach ($data as $nr => $values)
{
if ($columns !== [])
{
// load only what is part of the columns set
$row = [];
foreach ($columns as $column => $key_)
{
if (isset($values->{$key_}))
{
$row[$column] = $values->{$key_};
}
}
// update the row
$this->row($row, $key, $table);
}
else
{
// update the row
$this->row((array) $values, $key, $table);
}
}
return true;
}
/**
* Update row in the database
*
* @param array $data Dataset to update in database (key => value)
* @param string $key Dataset key column to use in updating the values in the Database
* @param string $table The table where the data is being updated
*
* @return bool
* @since 3.2.0
**/
public function row(array $data, string $key, string $table): bool
{
// set the update columns
if ($data === [] || strlen($key) == 0)
{
return false;
}
// get a query object
$query = $this->db->getQuery(true);
// set the query targets
$query->update($this->db->quoteName($this->getTable($table)));
// set the update values
$key_ = null;
foreach ($data as $column => $value)
{
if ($column === $key)
{
$key_ = $value;
}
else
{
$query->set($this->db->quoteName($column) . ' = ' . $this->quote($value));
}
}
// add the key condition
if ($key_ !== null)
{
$query->where($this->db->quoteName($key) . ' = ' . $this->quote($key_));
// execute the final query
$this->db->setQuery($query);
return $this->db->execute();
}
return false;
}
/**
* Update item in the database
*
* @param object $data Dataset to update in database (key => value)
* @param string $key Dataset key column to use in updating the values in the Database
* @param string $table The table where the data is being updated
*
* @return bool
* @since 3.2.0
**/
public function item(object $data, string $key, string $table): bool
{
// convert to an array
return $this->row((array) get_object_vars($data), $key, $table);
}
}

View File

@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>