Skip to content

Commit

Permalink
Fix error on php 8.1+
Browse files Browse the repository at this point in the history
Add DBCacheQuery class to insert a large number of records using fewer queries
Little fixes
  • Loading branch information
alexdnepro committed Jan 30, 2023
1 parent b773c1b commit eb1c746
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 7 deletions.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ All methods available in both class types
```php
use \Power\DB;

// Non static
// Non-static
$db = new \Power\mDB('localhost', 'users', 'passwd', 'dbname', 'utf8mb4');
// Select all records from users table
$data = $db->getAll('SELECT * FROM ?n', 'users');
Expand Down Expand Up @@ -101,4 +101,26 @@ use \Power\DB;
DB::Init('localhost', 'user', 'passwd', 'dbname', 'utf8mb4');
DB::SetErrorLog(__DIR__.'/mysql_error.log');
DB::SetLogSql(__DIR__.'/mysql_sql.log', false);
```

#### Use ``DBCacheQuery`` class to insert a large number of records using fewer queries
```php
// Create class and point table name and col names for inserting records
$cache_items = new \DBCacheQuery('item_list', ['id', 'name', 'icon', 'list', 'data_type']);
foreach ($some_data as $data)
{
// Use Add method for each new row
// Make sure, that param array has the same data order as you make in class creation
$cache_items->Add(
[
$data['id'],
$data['name'],
$data['icon'],
$data['list'],
$data['type']
]);
}
// Then use Flush method to send the remaining data from the cache
$cache_items->Flush();
// That's all
```
26 changes: 25 additions & 1 deletion src/DB.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public static function pure(string $sql): stdClass
}

/**
* DONT'T USE - function in development
* DON'T USE - function in development
* Make condition for where/having and other parameters
*
* Example:
Expand All @@ -420,4 +420,28 @@ public static function cond(string $field, string $operator, $value): string
return self::instance()->parse('?n '.$operator.' '.$placeholder, $field, $value);
}

public static function escapeParam($val)
{
if (is_int($val) || is_float($val)) {
return self::escapeInt($val);
}
if (is_object($val) && isset($val->sql)) {
return $val->sql;
}
return self::escapeString($val);
}

private static function escapeInt($value)
{
if ($value === NULL)
{
return 'NULL';
}
if (is_float($value))
{
$value = number_format($value, 6, '.', ''); // may lose precision on big numbers
}
return $value;
}

}
50 changes: 50 additions & 0 deletions src/DBCacheQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Power;

class DBCacheQuery
{

private $fields;
private $table_name;
private $insert_ignore;
private $sql_cache = '';
private $query_size_limit;

public function __construct(string $table_name, array $field_names, bool $insert_ignore = false, int $query_size_limit = 250000)
{
$this->fields = $field_names;
$this->table_name = $table_name;
$this->insert_ignore = $insert_ignore;
$this->query_size_limit = $query_size_limit;
}

public function Flush()
{
if ($this->sql_cache !== '') {
DB::query('?p;', $this->sql_cache);
}
$this->sql_cache = '';
}

public function Add(array $values)
{
if (strlen($this->sql_cache) >= $this->query_size_limit) {
$this->Flush();
}
$v = '';
foreach ($values as $val) {
if ($v !== '') {
$v .= ',';
}
$v .= DB::escapeParam($val);
}
if ($this->sql_cache === '') {
$f = '`' . implode('`,`', $this->fields) . '`';
$this->sql_cache = 'INSERT ' . ($this->insert_ignore ? 'IGNORE ' : '') . 'INTO `' . $this->table_name . '` (' . $f . ') VALUES (' . $v . ')';
} else {
$this->sql_cache .= ', (' . $v . ')';
}
}

}
10 changes: 5 additions & 5 deletions src/mDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ public function parse(string $sql, ...$arg): string
*
* @param string $input - field name to test
* @param array $allowed - an array with allowed variants
* @param string $default - optional variable to set if no match found. Default to false.
* @param string|bool $default - optional variable to set if no match found. Default to false.
* @return string|bool - either sanitized value or FALSE
*/
public function whiteList(string $input, array $allowed, $default=false)
Expand Down Expand Up @@ -625,13 +625,13 @@ public function prepareQuery($args):string
$this->ConnectBase();
$query = '';
$raw = array_shift($args);
$array = preg_split('~(\?[nsiuap])~u',$raw,null,PREG_SPLIT_DELIM_CAPTURE);
$array = preg_split('~(\?[nsiuap])~u',$raw,-1,PREG_SPLIT_DELIM_CAPTURE);
$arguments_num = count($args);
$placeholders_num = (int)floor(count($array) / 2);
if ( $placeholders_num !== $arguments_num )
{
$this->ShowError("Number of args ($arguments_num) doesn't match number of placeholders ($placeholders_num) in [$raw]", true);
die();
return '';
}

foreach ($array as $i => $part)
Expand Down Expand Up @@ -678,7 +678,7 @@ protected function escapeInt($value)
if(!is_numeric($value))
{
$this->ShowError( "Integer (?i) placeholder expects numeric value, ".gettype($value)." given", true);
die();
return '';
}
if (is_float($value))
{
Expand Down Expand Up @@ -745,7 +745,7 @@ protected function createSET($data):string
foreach ($data as $key => $value)
{
// Check if value is DB::pure object
if (is_numeric($value))
if (is_int($value) || is_float($value))
{
$str = $this->escapeInt($value);
} elseif (is_object($value) && isset($value->sql)) {
Expand Down

0 comments on commit eb1c746

Please sign in to comment.