171 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace nur\sery\db\sqlite;
 | 
						|
 | 
						|
use Generator;
 | 
						|
use nur\sery\cl;
 | 
						|
use SQLite3;
 | 
						|
use SQLite3Result;
 | 
						|
use SQLite3Stmt;
 | 
						|
 | 
						|
/**
 | 
						|
 * Class Sqlite: frontend vers une base de données sqlite3
 | 
						|
 */
 | 
						|
class Sqlite {
 | 
						|
  static function config_enableExceptions(self $sqlite) {
 | 
						|
    $sqlite->db->enableExceptions(true);
 | 
						|
  }
 | 
						|
 | 
						|
  const CONFIG = [
 | 
						|
    [self::class, "config_enableExceptions"],
 | 
						|
  ];
 | 
						|
  const MIGRATE = null;
 | 
						|
 | 
						|
  const SCHEMA = [
 | 
						|
    "file" => ["string", ""],
 | 
						|
    "flags" => ["int", SQLITE3_OPEN_READWRITE + SQLITE3_OPEN_CREATE],
 | 
						|
    "encryption_key" => ["string", ""],
 | 
						|
    "config" => ["?array|callable"],
 | 
						|
    "migrate" => ["?array|string|callable"],
 | 
						|
    "auto_open" => ["bool", true],
 | 
						|
  ];
 | 
						|
 | 
						|
  function __construct(?string $file=null, ?array $params=null) {
 | 
						|
    if ($file !== null) $params["file"] = $file;
 | 
						|
    ##schéma
 | 
						|
    $default_file = self::SCHEMA["file"][1];
 | 
						|
    $this->file = strval($params["file"] ?? $default_file);
 | 
						|
    #
 | 
						|
    $default_flags = self::SCHEMA["flags"][1];
 | 
						|
    $this->flags = intval($params["flags"] ?? $default_flags);
 | 
						|
    #
 | 
						|
    $default_encryptionKey = self::SCHEMA["encryption_key"][1];
 | 
						|
    $this->encryptionKey = strval($params["encryption_key"] ?? $default_encryptionKey);
 | 
						|
    # configuration
 | 
						|
    $this->config = $params["config"] ?? static::CONFIG;
 | 
						|
    # migrations
 | 
						|
    $this->migration = $params["migrate"] ?? static::MIGRATE;
 | 
						|
    #
 | 
						|
    $default_autoOpen = self::SCHEMA["auto_open"][1];
 | 
						|
    if ($params["auto_open"] ?? $default_autoOpen) {
 | 
						|
      $this->open();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  /** @var string */
 | 
						|
  protected $file;
 | 
						|
 | 
						|
  /** @var int */
 | 
						|
  protected $flags;
 | 
						|
 | 
						|
  /** @var string */
 | 
						|
  protected $encryptionKey;
 | 
						|
 | 
						|
  /** @var array|string|callable */
 | 
						|
  protected $config;
 | 
						|
 | 
						|
  /** @var array|string|callable */
 | 
						|
  protected $migration;
 | 
						|
 | 
						|
  /** @var SQLite3 */
 | 
						|
  protected $db;
 | 
						|
 | 
						|
  function open(): self {
 | 
						|
    if ($this->db === null) {
 | 
						|
      $this->db = new SQLite3($this->file, $this->flags, $this->encryptionKey);
 | 
						|
      _Config::with($this->config)->configure($this);
 | 
						|
      _Migration::with($this->migration)->migrate($this);
 | 
						|
    }
 | 
						|
    return $this;
 | 
						|
  }
 | 
						|
 | 
						|
  function close(): void {
 | 
						|
    if ($this->db !== null) {
 | 
						|
      $this->db->close();
 | 
						|
      $this->db = null;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  protected function checkStmt($stmt): SQLite3Stmt {
 | 
						|
    return SqliteException::check($this->db, $stmt);
 | 
						|
  }
 | 
						|
 | 
						|
  protected function checkResult($result): SQLite3Result {
 | 
						|
    return SqliteException::check($this->db, $result);
 | 
						|
  }
 | 
						|
 | 
						|
  function _exec(string $query): bool {
 | 
						|
    $this->open();
 | 
						|
    return $this->db->exec($query);
 | 
						|
  }
 | 
						|
 | 
						|
  function exec($query, ?array $params=null): bool {
 | 
						|
    $this->open();
 | 
						|
    $query = new _Query($query, $params);
 | 
						|
    $db = $this->db;
 | 
						|
    if ($query->useStmt($db, $stmt, $sql)) {
 | 
						|
      try {
 | 
						|
        return $stmt->execute()->finalize();
 | 
						|
      } finally {
 | 
						|
        $stmt->close();
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      return $db->exec($sql);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function _get(string $query, bool $entireRow=false) {
 | 
						|
    $this->open();
 | 
						|
    return $this->db->querySingle($query, $entireRow);
 | 
						|
  }
 | 
						|
 | 
						|
  function get($query, ?array $params=null, bool $entireRow=false) {
 | 
						|
    $this->open();
 | 
						|
    $query = new _Query($query, $params);
 | 
						|
    $db = $this->db;
 | 
						|
    if ($query->useStmt($db, $stmt, $sql)) {
 | 
						|
      try {
 | 
						|
        $result = $this->checkResult($stmt->execute());
 | 
						|
        try {
 | 
						|
          $row = $result->fetchArray(SQLITE3_ASSOC);
 | 
						|
          if ($row === false) return null;
 | 
						|
          elseif ($entireRow) return $row;
 | 
						|
          else return cl::first($row);
 | 
						|
        } finally {
 | 
						|
          $result->finalize();
 | 
						|
        }
 | 
						|
      } finally {
 | 
						|
        $stmt->close();
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      return $db->querySingle($sql, $entireRow);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  protected function _fetchResult(SQLite3Result $result): Generator {
 | 
						|
    try {
 | 
						|
      while (($row = $result->fetchArray(SQLITE3_ASSOC)) !== false) {
 | 
						|
        yield $row;
 | 
						|
      }
 | 
						|
    } finally {
 | 
						|
      $result->finalize();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  function all($query, ?array $params=null): iterable {
 | 
						|
    $this->open();
 | 
						|
    $query = new _Query($query, $params);
 | 
						|
    $db = $this->db;
 | 
						|
    if ($query->useStmt($db, $stmt, $sql)) {
 | 
						|
      try {
 | 
						|
        $result = $this->checkResult($stmt->execute());
 | 
						|
        return $this->_fetchResult($result);
 | 
						|
      } finally {
 | 
						|
        $stmt->close();
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      $result = $this->checkResult($db->query($sql));
 | 
						|
      return $this->_fetchResult($result);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |