Skip to content

Commit

Permalink
Add support for UPDATE SQL for Sql Data object
Browse files Browse the repository at this point in the history
  • Loading branch information
nicksagona committed Nov 27, 2024
1 parent 1b5e2cd commit 50cce27
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 53 deletions.
34 changes: 22 additions & 12 deletions src/Db.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php
/**
* Pop PHP Framework (http://www.popphp.org/)
* Pop PHP Framework (https://www.popphp.org/)
*
* @link https://github.com/popphp/popphp-framework
* @author Nick Sagona, III <dev@nolainteractive.com>
* @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
* @license http://www.popphp.org/license New BSD License
* @author Nick Sagona, III <dev@noladev.com>
* @copyright Copyright (c) 2009-2025 NOLA Interactive, LLC.
* @license https://www.popphp.org/license New BSD License
*/

/**
Expand All @@ -18,9 +18,9 @@
*
* @category Pop
* @package Pop\Db
* @author Nick Sagona, III <dev@nolainteractive.com>
* @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
* @license http://www.popphp.org/license New BSD License
* @author Nick Sagona, III <dev@noladev.com>
* @copyright Copyright (c) 2009-2025 NOLA Interactive, LLC.
* @license https://www.popphp.org/license New BSD License
* @version 6.5.0
*/
class Db
Expand Down Expand Up @@ -150,6 +150,7 @@ public static function check(string $adapter, array $options, string $prefix = '
}

error_reporting((int)$error);

return $result;
}

Expand All @@ -161,10 +162,14 @@ public static function check(string $adapter, array $options, string $prefix = '
* @param array $options
* @param string $prefix
* @throws Exception
* @return void
* @return int
*/
public static function executeSql(string $sql, mixed $adapter, array $options = [], string $prefix = '\Pop\Db\Adapter\\'): void
public static function executeSql(
string $sql, mixed $adapter, array $options = [], string $prefix = '\Pop\Db\Adapter\\'
): int
{
$affectedRows = 0;

if (is_string($adapter)) {
$adapter = ucfirst(strtolower($adapter));
$class = $prefix . $adapter;
Expand Down Expand Up @@ -242,10 +247,13 @@ public static function executeSql(string $sql, mixed $adapter, array $options =
foreach ($statements as $statement) {
if (!empty($statement)) {
$db->query($statement);
$affectedRows += $db->getNumberOfAffectedRows();
}
}
}
}

return $affectedRows;
}

/**
Expand All @@ -256,15 +264,17 @@ public static function executeSql(string $sql, mixed $adapter, array $options =
* @param array $options
* @param string $prefix
* @throws Exception
* @return void
* @return int
*/
public static function executeSqlFile(string $sqlFile, mixed $adapter, array $options = [], string $prefix = '\Pop\Db\Adapter\\'): void
public static function executeSqlFile(
string $sqlFile, mixed $adapter, array $options = [], string $prefix = '\Pop\Db\Adapter\\'
): int
{
if (!file_exists($sqlFile)) {
throw new Exception("Error: The SQL file '" . $sqlFile . "' does not exist.");
}

self::executeSql(file_get_contents($sqlFile), $adapter, $options, $prefix);
return self::executeSql(file_get_contents($sqlFile), $adapter, $options, $prefix);
}

/**
Expand Down
143 changes: 102 additions & 41 deletions src/Sql/Data.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php
/**
* Pop PHP Framework (http://www.popphp.org/)
* Pop PHP Framework (https://www.popphp.org/)
*
* @link https://github.com/popphp/popphp-framework
* @author Nick Sagona, III <dev@nolainteractive.com>
* @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
* @license http://www.popphp.org/license New BSD License
* @author Nick Sagona, III <dev@noladev.com>
* @copyright Copyright (c) 2009-2025 NOLA Interactive, LLC.
* @license https://www.popphp.org/license New BSD License
*/

/**
Expand All @@ -20,9 +20,9 @@
*
* @category Pop
* @package Pop\Db
* @author Nick Sagona, III <dev@nolainteractive.com>
* @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
* @license http://www.popphp.org/license New BSD License
* @author Nick Sagona, III <dev@noladev.com>
* @copyright Copyright (c) 2009-2025 NOLA Interactive, LLC.
* @license https://www.popphp.org/license New BSD License
* @version 6.5.0
*/
class Data extends AbstractSql
Expand Down Expand Up @@ -52,6 +52,12 @@ class Data extends AbstractSql
*/
protected array $conflictColumns = [];

/**
* Force UPDATE instead of UPSERT if conflict keys/columns are provided
* @var bool
*/
protected bool $forceUpdate = false;

/**
* SQL string
* @var ?string
Expand Down Expand Up @@ -96,6 +102,30 @@ public function getDivide(): int
return $this->divide;
}

/**
* Set force update
*
* @param bool $forceUpdate
* @param string $conflictKey
* @return Data
*/
public function setForceUpdate(bool $forceUpdate = true, string $conflictKey = 'id'): Data
{
$this->forceUpdate = $forceUpdate;
$this->conflictKey = $conflictKey;
return $this;
}

/**
* Is force update
*
* @return bool
*/
public function isForceUpdate(): bool
{
return $this->forceUpdate;
}

/**
* Set the database table
*
Expand Down Expand Up @@ -191,45 +221,76 @@ public function serialize(array $data, mixed $omit = null, bool $nullEmpty = fal
}
}

$columns = array_map([$this, 'quoteId'], $columns);
$insert = "INSERT INTO " . $table . " (" . implode(', ', $columns) . ") VALUES" . PHP_EOL;
$onUpdate = $this->formatConflicts();

foreach ($data as $i => $row) {
if (!empty($omit)) {
foreach ($omit as $o) {
if (isset($row[$o])) {
unset($row[$o]);
// Force UPDATE SQL
if (($this->forceUpdate) && !empty($this->conflictKey)) {
foreach ($data as $i => $row) {
$primaryValue = $row[$this->conflictKey];
unset($row[$this->conflictKey]);

$update = "UPDATE " . $table . " SET ";
if (!empty($omit)) {
foreach ($omit as $o) {
if (isset($row[$o])) {
unset($row[$o]);
}
}
}
}
$value = "(" . implode(', ', array_map(function($value) use ($forceQuote) {
return $this->quote($value, $forceQuote);
}, $row)) . ")";
if ($nullEmpty) {
$value = str_replace(["('',", " '', ", ", '')"], ["(NULL,", ' NULL, ', ', NULL)'], $value);
}

switch ($this->divide) {
case 0:
if ($i == 0) {
$this->sql .= $insert;
$values = [];
foreach ($row as $key => $value) {
$values[] = $this->quoteId($key) . ' = ' . $this->quote($value, $forceQuote);
}
$values = implode(', ', $values);

if ($nullEmpty) {
$values = str_replace(["('',", " '', ", ", '')"], ["(NULL,", ' NULL, ', ', NULL)'], $values);
}

$update .= $values . " WHERE " . $this->quoteId($this->conflictKey) . ' = ' . $primaryValue . ';';
$this->sql .= $update . PHP_EOL;
}
// Else, INSERT/UPSERT SQL
} else {
$columns = array_map([$this, 'quoteId'], $columns);
$insert = "INSERT INTO " . $table . " (" . implode(', ', $columns) . ") VALUES" . PHP_EOL;
$onUpdate = $this->formatConflicts();

foreach ($data as $i => $row) {
if (!empty($omit)) {
foreach ($omit as $o) {
if (isset($row[$o])) {
unset($row[$o]);
}
}
$this->sql .= $value;
$this->sql .= ($i == (count($data) - 1)) ? $onUpdate . ';' : ',';
$this->sql .= PHP_EOL;
break;
case 1:
$this->sql .= $insert . $value . $onUpdate . ';' . PHP_EOL;
break;
default:
if (($i % $this->divide) == 0) {
$this->sql .= $insert . $value . (($i == (count($data) - 1)) ? $onUpdate . ';' : ',') . PHP_EOL;
} else {
}
$value = "(" . implode(', ', array_map(function($value) use ($forceQuote) {
return $this->quote($value, $forceQuote);
}, $row)) . ")";
if ($nullEmpty) {
$value = str_replace(["('',", " '', ", ", '')"], ["(NULL,", ' NULL, ', ', NULL)'], $value);
}

switch ($this->divide) {
case 0:
if ($i == 0) {
$this->sql .= $insert;
}
$this->sql .= $value;
$this->sql .= (((($i + 1) % $this->divide) == 0) || ($i == (count($data) - 1))) ? $onUpdate . ';' : ',';
$this->sql .= ($i == (count($data) - 1)) ? $onUpdate . ';' : ',';
$this->sql .= PHP_EOL;
}
break;
case 1:
$this->sql .= $insert . $value . $onUpdate . ';' . PHP_EOL;
break;
default:
if (($i % $this->divide) == 0) {
$this->sql .= $insert . $value . (($i == (count($data) - 1)) ? $onUpdate . ';' : ',') . PHP_EOL;
} else {
$this->sql .= $value;
$this->sql .= (((($i + 1) % $this->divide) == 0) || ($i == (count($data) - 1))) ? $onUpdate . ';' : ',';
$this->sql .= PHP_EOL;
}
}
}
}

Expand Down Expand Up @@ -379,4 +440,4 @@ protected function formatConflicts(): string
return $onUpdate;
}

}
}

0 comments on commit 50cce27

Please sign in to comment.