mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Reorganize Db namespace; alter User ns to match
This commit is contained in:
parent
37dad63dee
commit
7687109132
23 changed files with 248 additions and 184 deletions
|
@ -9,3 +9,4 @@ if(!defined(NS_BASE."INSTALL")) define(NS_BASE."INSTALL", false);
|
||||||
|
|
||||||
require_once BASE."vendor".DIRECTORY_SEPARATOR."autoload.php";
|
require_once BASE."vendor".DIRECTORY_SEPARATOR."autoload.php";
|
||||||
ignore_user_abort(true);
|
ignore_user_abort(true);
|
||||||
|
iconv_set_encoding("internal_encoding", "UTF-8");
|
|
@ -19,6 +19,8 @@
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.0.0",
|
"php": "^7.0.0",
|
||||||
|
"ext-intl": "*",
|
||||||
|
"ext-iconv": "*",
|
||||||
"jkingweb/druuid": "^3.0.0",
|
"jkingweb/druuid": "^3.0.0",
|
||||||
"phpseclib/phpseclib": "^2.0.4",
|
"phpseclib/phpseclib": "^2.0.4",
|
||||||
"webmozart/glob": "^4.1.0",
|
"webmozart/glob": "^4.1.0",
|
||||||
|
|
6
composer.lock
generated
6
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "264437f06f643a1413d45660c2a32124",
|
"content-hash": "8260cf555776b4ffaef7fca3ca891311",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "fguillot/picofeed",
|
"name": "fguillot/picofeed",
|
||||||
|
@ -479,7 +479,9 @@
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^7.0.0"
|
"php": "^7.0.0",
|
||||||
|
"ext-intl": "*",
|
||||||
|
"ext-iconv": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": []
|
"platform-dev": []
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,22 @@ abstract class AbstractException extends \Exception {
|
||||||
"Lang/Exception.fileCorrupt" => 10104,
|
"Lang/Exception.fileCorrupt" => 10104,
|
||||||
"Lang/Exception.stringMissing" => 10105,
|
"Lang/Exception.stringMissing" => 10105,
|
||||||
"Lang/Exception.stringInvalid" => 10106,
|
"Lang/Exception.stringInvalid" => 10106,
|
||||||
"Db/Exception.extMissing" => 10201,
|
"Db/ExceptionStartup.extMissing" => 10201,
|
||||||
"Db/Exception.fileMissing" => 10202,
|
"Db/ExceptionStartup.fileMissing" => 10202,
|
||||||
"Db/Exception.fileUnusable" => 10203,
|
"Db/ExceptionStartup.fileUnusable" => 10203,
|
||||||
"Db/Exception.fileUnreadable" => 10204,
|
"Db/ExceptionStartup.fileUnreadable" => 10204,
|
||||||
"Db/Exception.fileUnwritable" => 10205,
|
"Db/ExceptionStartup.fileUnwritable" => 10205,
|
||||||
"Db/Exception.fileUncreatable" => 10206,
|
"Db/ExceptionStartup.fileUncreatable" => 10206,
|
||||||
"Db/Exception.fileCorrupt" => 10207,
|
"Db/ExceptionStartup.fileCorrupt" => 10207,
|
||||||
"Db/Exception.paramTypeInvalid" => 10401,
|
"Db/Exception.paramTypeInvalid" => 10401,
|
||||||
"Db/Exception.paramTypeUnknown" => 10402,
|
"Db/Exception.paramTypeUnknown" => 10402,
|
||||||
"Db/Exception.paramTypeMissing" => 10403,
|
"Db/Exception.paramTypeMissing" => 10403,
|
||||||
"Db/Update/Exception.tooNew" => 10211,
|
"Db/ExceptionUpdate.tooNew" => 10211,
|
||||||
"Db/Update/Exception.fileMissing" => 10212,
|
"Db/ExceptionUpdate.fileMissing" => 10212,
|
||||||
"Db/Update/Exception.fileUnusable" => 10213,
|
"Db/ExceptionUpdate.fileUnusable" => 10213,
|
||||||
"Db/Update/Exception.fileUnreadable" => 10214,
|
"Db/ExceptionUpdate.fileUnreadable" => 10214,
|
||||||
"Db/Update/Exception.manual" => 10215,
|
"Db/ExceptionUpdate.manual" => 10215,
|
||||||
"Db/Update/Exception.manualOnly" => 10216,
|
"Db/ExceptionUpdate.manualOnly" => 10216,
|
||||||
"Conf/Exception.fileMissing" => 10302,
|
"Conf/Exception.fileMissing" => 10302,
|
||||||
"Conf/Exception.fileUnusable" => 10303,
|
"Conf/Exception.fileUnusable" => 10303,
|
||||||
"Conf/Exception.fileUnreadable" => 10304,
|
"Conf/Exception.fileUnreadable" => 10304,
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace JKingWeb\NewsSync;
|
||||||
class Conf {
|
class Conf {
|
||||||
public $lang = "en";
|
public $lang = "en";
|
||||||
|
|
||||||
public $dbDriver = Db\DriverSQLite3::class;
|
public $dbDriver = Db\SQLite3\Driver::class;
|
||||||
public $dbSQLite3File = BASE."newssync.db";
|
public $dbSQLite3File = BASE."newssync.db";
|
||||||
public $dbSQLite3Key = "";
|
public $dbSQLite3Key = "";
|
||||||
public $dbSQLite3AutoUpd = true;
|
public $dbSQLite3AutoUpd = true;
|
||||||
|
@ -23,7 +23,7 @@ class Conf {
|
||||||
public $dbMySQLDb = "newssync";
|
public $dbMySQLDb = "newssync";
|
||||||
public $dbMySQLAutoUpd = false;
|
public $dbMySQLAutoUpd = false;
|
||||||
|
|
||||||
public $userDriver = User\DriverInternal::class;
|
public $userDriver = User\Internal\Driver::class;
|
||||||
public $userAuthPreferHTTP = false;
|
public $userAuthPreferHTTP = false;
|
||||||
public $userComposeNames = true;
|
public $userComposeNames = true;
|
||||||
public $userTempPasswordLength = 20;
|
public $userTempPasswordLength = 20;
|
||||||
|
|
|
@ -34,14 +34,10 @@ class Database {
|
||||||
$sep = \DIRECTORY_SEPARATOR;
|
$sep = \DIRECTORY_SEPARATOR;
|
||||||
$path = __DIR__.$sep."Db".$sep;
|
$path = __DIR__.$sep."Db".$sep;
|
||||||
$classes = [];
|
$classes = [];
|
||||||
foreach(glob($path."Driver?*.php") as $file) {
|
foreach(glob($path."*".$sep."Driver.php") as $file) {
|
||||||
$name = basename($file, ".php");
|
$name = basename(dirname($file));
|
||||||
if(substr($name,-3) != "PDO") {
|
$class = NS_BASE."Db\\$name\\Driver";
|
||||||
$name = NS_BASE."Db\\$name";
|
$classes[$class] = $class::driverName();
|
||||||
if(class_exists($name)) {
|
|
||||||
$classes[$name] = $name::driverName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $classes;
|
return $classes;
|
||||||
}
|
}
|
||||||
|
@ -328,4 +324,38 @@ class Database {
|
||||||
return (bool) $this->db->prepare("DELETE from newssync_subscriptions where id is ?", "int")->run($id)->changes();
|
return (bool) $this->db->prepare("DELETE from newssync_subscriptions where id is ?", "int")->run($id)->changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function folderAdd(string $user, array $data): int {
|
||||||
|
// If the user isn't authorized to perform this action then throw an exception.
|
||||||
|
if (!$this->data->user->authorize($user, __FUNCTION__)) {
|
||||||
|
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
|
}
|
||||||
|
// If the user doesn't exist throw an exception.
|
||||||
|
if (!$this->userExists($user)) {
|
||||||
|
throw new User\Exception("doesNotExist", ["user" => $user, "action" => __FUNCTION__]);
|
||||||
|
}
|
||||||
|
// if the desired folder name is missing or invalid, throw an exception
|
||||||
|
if(!array_key_exists("name", $data)) {
|
||||||
|
throw new Db\ExceptionInput("missing", ["action" => __FUNCTION__, "field" => "name"]);
|
||||||
|
} else if(!strlen(trim($data['name']))) {
|
||||||
|
throw new Db\ExceptionInput("whitespace", ["action" => __FUNCTION__, "field" => "name"]);
|
||||||
|
} else if(iconv_strlen($data['name']) > 100) {
|
||||||
|
throw new Db\ExceptionInput("tooLong", ["action" => __FUNCTION__, "field" => "name", 'max' => 100]);
|
||||||
|
}
|
||||||
|
// normalize folder's parent, if there is one
|
||||||
|
$parent = array_key_exists("parent", $data) ? (int) $data['parent'] : 0;
|
||||||
|
if($parent===0) {
|
||||||
|
// if no parent is specified, do nothing
|
||||||
|
$parent = null;
|
||||||
|
$root = null;
|
||||||
|
} else {
|
||||||
|
// if a parent is specified, make sure it exists and belongs to the user; get its root (first-level) folder if it's a nested folder
|
||||||
|
$p = $this->db->prepare("SELECT id,root from newssync_folders where owner is ? and id is ?", "str", "int")->run($user, $parent)->get();
|
||||||
|
if($p===null) {
|
||||||
|
throw new Db\ExceptionInput("idMissing", ["action" => __FUNCTION__, "field" => "parent", 'id' => $parent]);
|
||||||
|
} else {
|
||||||
|
// if the parent does not have a root specified (because it is a first-level folder) use the parent ID as the root ID
|
||||||
|
$root = $p['root']===null ? $parent : $p['root'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
6
lib/Db/ExceptionInput.php
Normal file
6
lib/Db/ExceptionInput.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\Db;
|
||||||
|
|
||||||
|
class ExceptionInput extends Exception {
|
||||||
|
}
|
6
lib/Db/ExceptionStartup.php
Normal file
6
lib/Db/ExceptionStartup.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\Db;
|
||||||
|
|
||||||
|
class ExceptionInput extends Exception {
|
||||||
|
}
|
6
lib/Db/ExceptionTimeout.php
Normal file
6
lib/Db/ExceptionTimeout.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\Db;
|
||||||
|
|
||||||
|
class ExceptionTimeout extends Exception {
|
||||||
|
}
|
6
lib/Db/ExceptionUpdate.php
Normal file
6
lib/Db/ExceptionUpdate.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\Db;
|
||||||
|
|
||||||
|
class ExceptionUpdate extends Exception {
|
||||||
|
}
|
|
@ -1,14 +1,26 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
namespace JKingWeb\NewsSync\Db;
|
namespace JKingWeb\NewsSync\Db\SQLite3;
|
||||||
|
use JKingWeb\NewsSync\Lang;
|
||||||
|
use JKingWeb\NewsSync\Db\Exception;
|
||||||
|
use JKingWeb\NewsSync\Db\ExceptionStartup;
|
||||||
|
use JKingWeb\NewsSync\Db\ExceptionUpdate;
|
||||||
|
use JKingWeb\NewsSync\Db\ExceptionInput;
|
||||||
|
use JKingWeb\NewsSync\Db\ExceptionTimeout;
|
||||||
|
|
||||||
|
|
||||||
|
class Driver extends \JKingWeb\NewsSync\Db\AbstractDriver {
|
||||||
|
const SQLITE_ERROR = 1;
|
||||||
|
const SQLITE_BUSY = 5;
|
||||||
|
const SQLITE_CONSTRAINT = 19;
|
||||||
|
const SQLITE_MISMATCH = 20;
|
||||||
|
|
||||||
class DriverSQLite3 extends AbstractDriver {
|
|
||||||
protected $db;
|
protected $db;
|
||||||
protected $data;
|
protected $data;
|
||||||
|
|
||||||
public function __construct(\JKingWeb\NewsSync\RuntimeData $data, bool $install = false) {
|
public function __construct(\JKingWeb\NewsSync\RuntimeData $data, bool $install = false) {
|
||||||
// check to make sure required extension is loaded
|
// check to make sure required extension is loaded
|
||||||
if(!class_exists("SQLite3")) throw new Exception("extMissing", self::driverName());
|
if(!class_exists("SQLite3")) throw new ExceptionStartup("extMissing", self::driverName());
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
$file = $data->conf->dbSQLite3File;
|
$file = $data->conf->dbSQLite3File;
|
||||||
// if the file exists (or we're initializing the database), try to open it and set initial options
|
// if the file exists (or we're initializing the database), try to open it and set initial options
|
||||||
|
@ -20,14 +32,14 @@ class DriverSQLite3 extends AbstractDriver {
|
||||||
} catch(\Throwable $e) {
|
} catch(\Throwable $e) {
|
||||||
// if opening the database doesn't work, check various pre-conditions to find out what the problem might be
|
// if opening the database doesn't work, check various pre-conditions to find out what the problem might be
|
||||||
if(!file_exists($file)) {
|
if(!file_exists($file)) {
|
||||||
if($install && !is_writable(dirname($file))) throw new Exception("fileUncreatable", dirname($file));
|
if($install && !is_writable(dirname($file))) throw new ExceptionStartup("fileUncreatable", dirname($file));
|
||||||
throw new Exception("fileMissing", $file);
|
throw new ExceptionStartup("fileMissing", $file);
|
||||||
}
|
}
|
||||||
if(!is_readable($file) && !is_writable($file)) throw new Exception("fileUnusable", $file);
|
if(!is_readable($file) && !is_writable($file)) throw new ExceptionStartup("fileUnusable", $file);
|
||||||
if(!is_readable($file)) throw new Exception("fileUnreadable", $file);
|
if(!is_readable($file)) throw new ExceptionStartup("fileUnreadable", $file);
|
||||||
if(!is_writable($file)) throw new Exception("fileUnwritable", $file);
|
if(!is_writable($file)) throw new ExceptionStartup("fileUnwritable", $file);
|
||||||
// otherwise the database is probably corrupt
|
// otherwise the database is probably corrupt
|
||||||
throw new Exception("fileCorrupt", $mainfile);
|
throw new ExceptionStartup("fileCorrupt", $mainfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,18 +50,17 @@ class DriverSQLite3 extends AbstractDriver {
|
||||||
|
|
||||||
|
|
||||||
static public function driverName(): string {
|
static public function driverName(): string {
|
||||||
$name = str_replace(Driver::class, "", static::class);
|
return Lang::msg("Driver.Db.SQLite3.Name");
|
||||||
return Lang::msg("Driver.Db.$name.Name");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schemaVersion(): int {
|
public function schemaVersion(): int {
|
||||||
return $this->query("PRAGMA user_version")->getSingle();
|
return $this->query("PRAGMA user_version")->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function schemaUpdate(int $to): bool {
|
public function schemaUpdate(int $to): bool {
|
||||||
$ver = $this->schemaVersion();
|
$ver = $this->schemaVersion();
|
||||||
if(!$this->data->conf->dbSQLite3AutoUpd) throw new Update\Exception("manual", ['version' => $ver, 'driver_name' => $this->driverName()]);
|
if(!$this->data->conf->dbSQLite3AutoUpd) throw new ExceptionUpdate("manual", ['version' => $ver, 'driver_name' => $this->driverName()]);
|
||||||
if($ver >= $to) throw new Update\Exception("tooNew", ['difference' => ($ver - $to), 'current' => $ver, 'target' => $to, 'driver_name' => $this->driverName()]);
|
if($ver >= $to) throw new ExceptionUpdate("tooNew", ['difference' => ($ver - $to), 'current' => $ver, 'target' => $to, 'driver_name' => $this->driverName()]);
|
||||||
$sep = \DIRECTORY_SEPARATOR;
|
$sep = \DIRECTORY_SEPARATOR;
|
||||||
$path = \JKingWeb\NewsSync\BASE."sql".$sep."SQLite3".$sep;
|
$path = \JKingWeb\NewsSync\BASE."sql".$sep."SQLite3".$sep;
|
||||||
$this->lock();
|
$this->lock();
|
||||||
|
@ -58,10 +69,10 @@ class DriverSQLite3 extends AbstractDriver {
|
||||||
$this->begin();
|
$this->begin();
|
||||||
try {
|
try {
|
||||||
$file = $path.$a.".sql";
|
$file = $path.$a.".sql";
|
||||||
if(!file_exists($file)) throw new Update\Exception("fileMissing", ['file' => $file, 'driver_name' => $this->driverName()]);
|
if(!file_exists($file)) throw new ExceptionUpdate("fileMissing", ['file' => $file, 'driver_name' => $this->driverName()]);
|
||||||
if(!is_readable($file)) throw new Update\Exception("fileUnreadable", ['file' => $file, 'driver_name' => $this->driverName()]);
|
if(!is_readable($file)) throw new ExceptionUpdate("fileUnreadable", ['file' => $file, 'driver_name' => $this->driverName()]);
|
||||||
$sql = @file_get_contents($file);
|
$sql = @file_get_contents($file);
|
||||||
if($sql===false) throw new Update\Exception("fileUnusable", ['file' => $file, 'driver_name' => $this->driverName()]);
|
if($sql===false) throw new ExceptionUpdate("fileUnusable", ['file' => $file, 'driver_name' => $this->driverName()]);
|
||||||
$this->exec($sql);
|
$this->exec($sql);
|
||||||
} catch(\Throwable $e) {
|
} catch(\Throwable $e) {
|
||||||
// undo any partial changes from the failed update
|
// undo any partial changes from the failed update
|
||||||
|
@ -69,6 +80,7 @@ class DriverSQLite3 extends AbstractDriver {
|
||||||
// commit any successful updates if updating by more than one version
|
// commit any successful updates if updating by more than one version
|
||||||
$this->commit(true);
|
$this->commit(true);
|
||||||
// throw the error received
|
// throw the error received
|
||||||
|
// FIXME: This should create the relevant type of SQL exception
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
$this->commit();
|
$this->commit();
|
||||||
|
@ -82,11 +94,11 @@ class DriverSQLite3 extends AbstractDriver {
|
||||||
return (bool) $this->db->exec($query);
|
return (bool) $this->db->exec($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function query(string $query): Result {
|
public function query(string $query): \JKingWeb\NewsSync\Db\Result {
|
||||||
return new ResultSQLite3($this->db->query($query), $this->db->changes());
|
return new Result($this->db->query($query), $this->db->changes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function prepareArray(string $query, array $paramTypes): Statement {
|
public function prepareArray(string $query, array $paramTypes): \JKingWeb\NewsSync\Db\Statement {
|
||||||
return new StatementSQLite3($this->db, $this->db->prepare($query), $paramTypes);
|
return new Statement($this->db, $this->db->prepare($query), $paramTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
namespace JKingWeb\NewsSync\Db;
|
namespace JKingWeb\NewsSync\Db\SQLite3;
|
||||||
|
|
||||||
class ResultSQLite3 implements Result {
|
class Result implements \JKingWeb\NewsSync\Db\Result {
|
||||||
protected $st;
|
protected $st;
|
||||||
protected $set;
|
protected $set;
|
||||||
protected $pos = 0;
|
protected $pos = 0;
|
||||||
|
@ -40,7 +40,7 @@ class ResultSQLite3 implements Result {
|
||||||
|
|
||||||
// constructor/destructor
|
// constructor/destructor
|
||||||
|
|
||||||
public function __construct(\SQLite3Result $result, int $changes = 0, StatementSQLite3 $statement = null) {
|
public function __construct(\SQLite3Result $result, int $changes = 0, Statement $statement = null) {
|
||||||
$this->st = $statement; //keeps the statement from being destroyed, invalidating the result set
|
$this->st = $statement; //keeps the statement from being destroyed, invalidating the result set
|
||||||
$this->set = $result;
|
$this->set = $result;
|
||||||
$this->rows = $changes;
|
$this->rows = $changes;
|
|
@ -1,8 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
namespace JKingWeb\NewsSync\Db;
|
namespace JKingWeb\NewsSync\Db\SQLite3;
|
||||||
|
use JKingWeb\NewsSync\Db\Exception;
|
||||||
|
|
||||||
class StatementSQLite3 extends AbstractStatement {
|
class Statement extends \JKingWeb\NewsSync\Db\AbstractStatement {
|
||||||
const BINDINGS = [
|
const BINDINGS = [
|
||||||
"null" => \SQLITE3_NULL,
|
"null" => \SQLITE3_NULL,
|
||||||
"integer" => \SQLITE3_INTEGER,
|
"integer" => \SQLITE3_INTEGER,
|
||||||
|
@ -38,7 +39,7 @@ class StatementSQLite3 extends AbstractStatement {
|
||||||
])[$part];
|
])[$part];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runArray(array $values = null): Result {
|
public function runArray(array $values = null): \JKingWeb\NewsSync\Db\Result {
|
||||||
$this->st->clear();
|
$this->st->clear();
|
||||||
$l = sizeof($values);
|
$l = sizeof($values);
|
||||||
for($a = 0; $a < $l; $a++) {
|
for($a = 0; $a < $l; $a++) {
|
||||||
|
@ -58,6 +59,6 @@ class StatementSQLite3 extends AbstractStatement {
|
||||||
// perform binding
|
// perform binding
|
||||||
$this->st->bindValue($a+1, $values[$a], $type);
|
$this->st->bindValue($a+1, $values[$a], $type);
|
||||||
}
|
}
|
||||||
return new ResultSQLite3($this->st->execute(), $this->db->changes(), $this);
|
return new Result($this->st->execute(), $this->db->changes(), $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
namespace JKingWeb\NewsSync\Db\Update;
|
|
||||||
|
|
||||||
class Exception extends \JKingWeb\NewsSync\Db\Exception {
|
|
||||||
}
|
|
10
lib/User.php
10
lib/User.php
|
@ -15,12 +15,10 @@ class User {
|
||||||
$sep = \DIRECTORY_SEPARATOR;
|
$sep = \DIRECTORY_SEPARATOR;
|
||||||
$path = __DIR__.$sep."User".$sep;
|
$path = __DIR__.$sep."User".$sep;
|
||||||
$classes = [];
|
$classes = [];
|
||||||
foreach(glob($path."Driver?*.php") as $file) {
|
foreach(glob($path."*".$sep."Driver.php") as $file) {
|
||||||
$drv = basename($file, ".php");
|
$name = basename(dirname($file));
|
||||||
$drv = NS_BASE."Db\\$drv";
|
$class = NS_BASE."User\\$name\\Driver";
|
||||||
if(class_exists($drv)) {
|
$classes[$class] = $class::driverName();
|
||||||
$classes[$drv] = $drv::driverName();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return $classes;
|
return $classes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
namespace JKingWeb\NewsSync\User;
|
|
||||||
use JKingWeb\NewsSync\Lang;
|
|
||||||
|
|
||||||
final class DriverInternal implements Driver {
|
|
||||||
use InternalFunctions;
|
|
||||||
|
|
||||||
protected $data;
|
|
||||||
protected $db;
|
|
||||||
protected $functions = [
|
|
||||||
"auth" => Driver::FUNC_INTERNAL,
|
|
||||||
"userList" => Driver::FUNC_INTERNAL,
|
|
||||||
"userExists" => Driver::FUNC_INTERNAL,
|
|
||||||
"userAdd" => Driver::FUNC_INTERNAL,
|
|
||||||
"userRemove" => Driver::FUNC_INTERNAL,
|
|
||||||
"userPasswordSet" => Driver::FUNC_INTERNAL,
|
|
||||||
"userPropertiesGet" => Driver::FUNC_INTERNAL,
|
|
||||||
"userPropertiesSet" => Driver::FUNC_INTERNAL,
|
|
||||||
"userRightsGet" => Driver::FUNC_INTERNAL,
|
|
||||||
"userRightsSet" => Driver::FUNC_INTERNAL,
|
|
||||||
];
|
|
||||||
|
|
||||||
static public function create(\JKingWeb\NewsSync\RuntimeData $data): Driver {
|
|
||||||
return new static($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function driverName(): string {
|
|
||||||
$name = str_replace(Driver::class, "", static::class);
|
|
||||||
return Lang::msg("Driver.User.$name.Name");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function driverFunctions(string $function = null) {
|
|
||||||
if($function===null) return $this->functions;
|
|
||||||
if(array_key_exists($function, $this->functions)) {
|
|
||||||
return $this->functions[$function];
|
|
||||||
} else {
|
|
||||||
return Driver::FUNC_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// see InternalFunctions.php for bulk of methods
|
|
||||||
}
|
|
43
lib/User/Internal/Driver.php
Normal file
43
lib/User/Internal/Driver.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\NewsSync\User\Internal;
|
||||||
|
use JKingWeb\NewsSync\Lang;
|
||||||
|
use JKingWeb\NewsSync\User\Driver as Iface;
|
||||||
|
|
||||||
|
final class Driver implements Iface {
|
||||||
|
use InternalFunctions;
|
||||||
|
|
||||||
|
protected $data;
|
||||||
|
protected $db;
|
||||||
|
protected $functions = [
|
||||||
|
"auth" => Iface::FUNC_INTERNAL,
|
||||||
|
"userList" => Iface::FUNC_INTERNAL,
|
||||||
|
"userExists" => Iface::FUNC_INTERNAL,
|
||||||
|
"userAdd" => Iface::FUNC_INTERNAL,
|
||||||
|
"userRemove" => Iface::FUNC_INTERNAL,
|
||||||
|
"userPasswordSet" => Iface::FUNC_INTERNAL,
|
||||||
|
"userPropertiesGet" => Iface::FUNC_INTERNAL,
|
||||||
|
"userPropertiesSet" => Iface::FUNC_INTERNAL,
|
||||||
|
"userRightsGet" => Iface::FUNC_INTERNAL,
|
||||||
|
"userRightsSet" => Iface::FUNC_INTERNAL,
|
||||||
|
];
|
||||||
|
|
||||||
|
static public function create(\JKingWeb\NewsSync\RuntimeData $data): Driver {
|
||||||
|
return new static($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function driverName(): string {
|
||||||
|
return Lang::msg("Driver.User.Internal.Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function driverFunctions(string $function = null) {
|
||||||
|
if($function===null) return $this->functions;
|
||||||
|
if(array_key_exists($function, $this->functions)) {
|
||||||
|
return $this->functions[$function];
|
||||||
|
} else {
|
||||||
|
return Iface::FUNC_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// see InternalFunctions.php for bulk of methods
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
namespace JKingWeb\NewsSync\User;
|
namespace JKingWeb\NewsSync\User\Internal;
|
||||||
|
|
||||||
trait InternalFunctions {
|
trait InternalFunctions {
|
||||||
protected $actor = [];
|
protected $actor = [];
|
|
@ -21,31 +21,31 @@ return [
|
||||||
'Exception.JKingWeb/NewsSync/Conf/Exception.fileUnwritable' => 'Insufficient permissions to overwrite configuration file "{0}"',
|
'Exception.JKingWeb/NewsSync/Conf/Exception.fileUnwritable' => 'Insufficient permissions to overwrite configuration file "{0}"',
|
||||||
'Exception.JKingWeb/NewsSync/Conf/Exception.fileCorrupt' => 'Configuration file "{0}" is corrupt or does not conform to expected format',
|
'Exception.JKingWeb/NewsSync/Conf/Exception.fileCorrupt' => 'Configuration file "{0}" is corrupt or does not conform to expected format',
|
||||||
|
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.extMissing' => 'Required PHP extension for driver "{0}" not installed',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.extMissing' => 'Required PHP extension for driver "{0}" not installed',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.fileMissing' => 'Database file "{0}" does not exist',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.fileMissing' => 'Database file "{0}" does not exist',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.fileUnreadable' => 'Insufficient permissions to open database file "{0}" for reading',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.fileUnreadable' => 'Insufficient permissions to open database file "{0}" for reading',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.fileUnwritable' => 'Insufficient permissions to open database file "{0}" for writing',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.fileUnwritable' => 'Insufficient permissions to open database file "{0}" for writing',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.fileUnusable' => 'Insufficient permissions to open database file "{0}" for reading or writing',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.fileUnusable' => 'Insufficient permissions to open database file "{0}" for reading or writing',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.fileUncreatable' => 'Insufficient permissions to create new database file "{0}"',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.fileUncreatable' => 'Insufficient permissions to create new database file "{0}"',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.fileCorrupt' => 'Database file "{0}" is corrupt or not a valid database',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionStartup.fileCorrupt' => 'Database file "{0}" is corrupt or not a valid database',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.paramTypeInvalid' => 'Prepared statement parameter type "{0}" is invalid',
|
'Exception.JKingWeb/NewsSync/Db/Exception.paramTypeInvalid' => 'Prepared statement parameter type "{0}" is invalid',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.paramTypeUnknown' => 'Prepared statement parameter type "{0}" is valid, but not implemented',
|
'Exception.JKingWeb/NewsSync/Db/Exception.paramTypeUnknown' => 'Prepared statement parameter type "{0}" is valid, but not implemented',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Exception.paramTypeMissing' => 'Prepared statement parameter type for parameter #{0} was not specified',
|
'Exception.JKingWeb/NewsSync/Db/Exception.paramTypeMissing' => 'Prepared statement parameter type for parameter #{0} was not specified',
|
||||||
|
|
||||||
'Exception.JKingWeb/NewsSync/Db/Update/Exception.manual' =>
|
'Exception.JKingWeb/NewsSync/Db/ExceptionUpdate.manual' =>
|
||||||
'{from_version, select,
|
'{from_version, select,
|
||||||
0 {{driver_name} database is configured for manual updates and is not initialized; please populate the database with the base schema}
|
0 {{driver_name} database is configured for manual updates and is not initialized; please populate the database with the base schema}
|
||||||
other {{driver_name} database is configured for manual updates; please update from schema version {current} to version {target}}
|
other {{driver_name} database is configured for manual updates; please update from schema version {current} to version {target}}
|
||||||
}',
|
}',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Update/Exception.manualOnly' =>
|
'Exception.JKingWeb/NewsSync/Db/ExceptionUpdate.manualOnly' =>
|
||||||
'{from_version, select,
|
'{from_version, select,
|
||||||
0 {{driver_name} database must be updated manually and is not initialized; please populate the database with the base schema}
|
0 {{driver_name} database must be updated manually and is not initialized; please populate the database with the base schema}
|
||||||
other {{driver_name} database must be updated manually; please update from schema version {current} to version {target}}
|
other {{driver_name} database must be updated manually; please update from schema version {current} to version {target}}
|
||||||
}',
|
}',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Update/Exception.fileMissing' => 'Automatic updating of the {driver_name} database failed due to instructions for updating from version {current} not being available',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionUpdate.fileMissing' => 'Automatic updating of the {driver_name} database failed due to instructions for updating from version {current} not being available',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Update/Exception.fileUnreadable' => 'Automatic updating of the {driver_name} database failed due to insufficient permissions to read instructions for updating from version {current}',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionUpdate.fileUnreadable' => 'Automatic updating of the {driver_name} database failed due to insufficient permissions to read instructions for updating from version {current}',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Update/Exception.fileUnusable' => 'Automatic updating of the {driver_name} database failed due to an error reading instructions for updating from version {current}',
|
'Exception.JKingWeb/NewsSync/Db/ExceptionUpdate.fileUnusable' => 'Automatic updating of the {driver_name} database failed due to an error reading instructions for updating from version {current}',
|
||||||
'Exception.JKingWeb/NewsSync/Db/Update/Exception.tooNew' =>
|
'Exception.JKingWeb/NewsSync/Db/ExceptionUpdate.tooNew' =>
|
||||||
'{difference, select,
|
'{difference, select,
|
||||||
0 {Automatic updating of the {driver_name} database failed because it is already up to date with the requested version, {target}}
|
0 {Automatic updating of the {driver_name} database failed because it is already up to date with the requested version, {target}}
|
||||||
other {Automatic updating of the {driver_name} database failed because its version, {current}, is newer than the requested version, {target}}
|
other {Automatic updating of the {driver_name} database failed because its version, {current}, is newer than the requested version, {target}}
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
-- settings
|
||||||
|
create table newssync_settings(
|
||||||
|
key varchar(255) primary key not null, -- setting key
|
||||||
|
value varchar(255), -- setting value, serialized as a string
|
||||||
|
type varchar(255) not null check(
|
||||||
|
type in('int','numeric','text','timestamp','date','time','bool','null','json')
|
||||||
|
) default 'text' -- the deserialized type of the value
|
||||||
|
);
|
||||||
|
|
||||||
|
-- users
|
||||||
|
create table newssync_users(
|
||||||
|
id TEXT primary key not null, -- user id
|
||||||
|
password TEXT, -- password, salted and hashed; if using external authentication this would be blank
|
||||||
|
name TEXT, -- display name
|
||||||
|
avatar_url TEXT, -- external URL to avatar
|
||||||
|
avatar_type TEXT, -- internal avatar image's MIME content type
|
||||||
|
avatar_data BLOB, -- internal avatar image's binary data
|
||||||
|
rights integer not null default 0 -- any administrative rights the user may have
|
||||||
|
);
|
||||||
|
|
||||||
-- newsfeeds, deduplicated
|
-- newsfeeds, deduplicated
|
||||||
create table newssync_feeds(
|
create table newssync_feeds(
|
||||||
id integer primary key not null, -- sequence number
|
id integer primary key not null, -- sequence number
|
||||||
|
@ -15,6 +35,31 @@ create table newssync_feeds(
|
||||||
unique(url,username,password) -- a URL with particular credentials should only appear once
|
unique(url,username,password) -- a URL with particular credentials should only appear once
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- users' subscriptions to newsfeeds, with settings
|
||||||
|
create table newssync_subscriptions(
|
||||||
|
id integer primary key not null, -- sequence number
|
||||||
|
owner TEXT not null references newssync_users(id) on delete cascade on update cascade, -- owner of subscription
|
||||||
|
feed integer not null references newssync_feeds(id) on delete cascade, -- feed for the subscription
|
||||||
|
added datetime not null default CURRENT_TIMESTAMP, -- time at which feed was added
|
||||||
|
modified datetime not null default CURRENT_TIMESTAMP, -- date at which subscription properties were last modified
|
||||||
|
title TEXT, -- user-supplied title
|
||||||
|
order_type int not null default 0, -- ownCloud sort order
|
||||||
|
pinned boolean not null default 0, -- whether feed is pinned (always sorts at top)
|
||||||
|
folder integer references newssync_folders(id) on delete set null, -- TT-RSS category (nestable); the first-level category (which acts as ownCloud folder) is joined in when needed
|
||||||
|
unique(owner,feed) -- a given feed should only appear once for a given owner
|
||||||
|
);
|
||||||
|
|
||||||
|
-- TT-RSS categories and ownCloud folders
|
||||||
|
create table newssync_folders(
|
||||||
|
id integer primary key not null, -- sequence number
|
||||||
|
owner TEXT not null references newssync_users(id) on delete cascade on update cascade, -- owner of folder
|
||||||
|
parent integer not null default 0, -- parent folder id
|
||||||
|
root integer not null default 0, -- first-level folder (ownCloud folder)
|
||||||
|
name TEXT not null, -- folder name
|
||||||
|
modified datetime not null default CURRENT_TIMESTAMP, --
|
||||||
|
unique(owner,name,parent) -- cannot have multiple folders with the same name under the same parent for the same owner
|
||||||
|
);
|
||||||
|
|
||||||
-- entries in newsfeeds
|
-- entries in newsfeeds
|
||||||
create table newssync_articles(
|
create table newssync_articles(
|
||||||
id integer primary key not null, -- sequence number
|
id integer primary key not null, -- sequence number
|
||||||
|
@ -40,57 +85,6 @@ create table newssync_enclosures(
|
||||||
type varchar(255)
|
type varchar(255)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- author labels ("categories" in RSS/Atom parlance) associated with newsfeed entries
|
|
||||||
create table newssync_tags(
|
|
||||||
article integer not null references newssync_articles(id) on delete cascade,
|
|
||||||
name TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- settings
|
|
||||||
create table newssync_settings(
|
|
||||||
key varchar(255) primary key not null, --
|
|
||||||
value varchar(255), --
|
|
||||||
type varchar(255) not null check(
|
|
||||||
type in('int','numeric','text','timestamp','date','time','bool','null','json')
|
|
||||||
) default 'text' --
|
|
||||||
);
|
|
||||||
|
|
||||||
-- users
|
|
||||||
create table newssync_users(
|
|
||||||
id TEXT primary key not null, -- user id
|
|
||||||
password TEXT, -- password, salted and hashed; if using external authentication this would be blank
|
|
||||||
name TEXT, -- display name
|
|
||||||
avatar_url TEXT, -- external URL to avatar
|
|
||||||
avatar_type TEXT, -- internal avatar image's MIME content type
|
|
||||||
avatar_data BLOB, -- internal avatar image's binary data
|
|
||||||
rights integer not null default 0 -- any administrative rights the user may have
|
|
||||||
);
|
|
||||||
|
|
||||||
-- TT-RSS categories and ownCloud folders
|
|
||||||
create table newssync_categories(
|
|
||||||
id integer primary key not null, -- sequence number
|
|
||||||
owner TEXT not null references newssync_users(id) on delete cascade on update cascade, -- owner of category
|
|
||||||
parent integer, -- parent category id
|
|
||||||
folder integer not null, -- first-level category (ownCloud folder)
|
|
||||||
name TEXT not null, -- category name
|
|
||||||
modified datetime not null default CURRENT_TIMESTAMP, --
|
|
||||||
unique(owner,name,parent) -- cannot have multiple categories with the same name under the same parent for the same owner
|
|
||||||
);
|
|
||||||
|
|
||||||
-- users' subscriptions to newsfeeds, with settings
|
|
||||||
create table newssync_subscriptions(
|
|
||||||
id integer primary key not null, -- sequence number
|
|
||||||
owner TEXT not null references newssync_users(id) on delete cascade on update cascade, -- owner of subscription
|
|
||||||
feed integer not null references newssync_feeds(id) on delete cascade, -- feed for the subscription
|
|
||||||
added datetime not null default CURRENT_TIMESTAMP, -- time at which feed was added
|
|
||||||
modified datetime not null default CURRENT_TIMESTAMP, -- date at which subscription properties were last modified
|
|
||||||
title TEXT, -- user-supplied title
|
|
||||||
order_type int not null default 0, -- ownCloud sort order
|
|
||||||
pinned boolean not null default 0, -- whether feed is pinned (always sorts at top)
|
|
||||||
category integer references newssync_categories(id) on delete set null, -- TT-RSS category (nestable); the first-level category (which acts as ownCloud folder) is joined in when needed
|
|
||||||
unique(owner,feed) -- a given feed should only appear once for a given owner
|
|
||||||
);
|
|
||||||
|
|
||||||
-- users' actions on newsfeed entries
|
-- users' actions on newsfeed entries
|
||||||
create table newssync_subscription_articles(
|
create table newssync_subscription_articles(
|
||||||
id integer primary key not null,
|
id integer primary key not null,
|
||||||
|
@ -108,6 +102,12 @@ create table newssync_labels(
|
||||||
);
|
);
|
||||||
create index newssync_label_names on newssync_labels(name);
|
create index newssync_label_names on newssync_labels(name);
|
||||||
|
|
||||||
|
-- author labels ("categories" in RSS/Atom parlance) associated with newsfeed entries
|
||||||
|
create table newssync_tags(
|
||||||
|
article integer not null references newssync_articles(id) on delete cascade,
|
||||||
|
name TEXT
|
||||||
|
);
|
||||||
|
|
||||||
-- set version marker
|
-- set version marker
|
||||||
pragma user_version = 1;
|
pragma user_version = 1;
|
||||||
insert into newssync_settings values('schema_version',1,'int');
|
insert into newssync_settings values('schema_version',1,'int');
|
|
@ -21,20 +21,20 @@ class TestDbResultSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
function testConstructResult() {
|
function testConstructResult() {
|
||||||
$set = $this->c->query("SELECT 1");
|
$set = $this->c->query("SELECT 1");
|
||||||
$this->assertInstanceOf(Db\ResultSQLite3::class, new Db\ResultSQLite3($set));
|
$this->assertInstanceOf(Db\Result::class, new Db\SQLite3\Result($set));
|
||||||
}
|
}
|
||||||
|
|
||||||
function testGetChangeCount() {
|
function testGetChangeCount() {
|
||||||
$this->c->query("CREATE TABLE test(col)");
|
$this->c->query("CREATE TABLE test(col)");
|
||||||
$set = $this->c->query("INSERT INTO test(col) values(1)");
|
$set = $this->c->query("INSERT INTO test(col) values(1)");
|
||||||
$rows = $this->c->changes();
|
$rows = $this->c->changes();
|
||||||
$this->assertEquals($rows, (new Db\ResultSQLite3($set,$rows))->changes());
|
$this->assertEquals($rows, (new Db\SQLite3\Result($set,$rows))->changes());
|
||||||
}
|
}
|
||||||
|
|
||||||
function testIterateOverResults() {
|
function testIterateOverResults() {
|
||||||
$set = $this->c->query("SELECT 1 as col union select 2 as col union select 3 as col");
|
$set = $this->c->query("SELECT 1 as col union select 2 as col union select 3 as col");
|
||||||
$rows = [];
|
$rows = [];
|
||||||
foreach(new Db\ResultSQLite3($set) as $row) {
|
foreach(new Db\SQLite3\Result($set) as $row) {
|
||||||
$rows[] = $row['col'];
|
$rows[] = $row['col'];
|
||||||
}
|
}
|
||||||
$this->assertEquals([1,2,3], $rows);
|
$this->assertEquals([1,2,3], $rows);
|
||||||
|
@ -43,7 +43,7 @@ class TestDbResultSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
function testIterateOverResultsTwice() {
|
function testIterateOverResultsTwice() {
|
||||||
$set = $this->c->query("SELECT 1 as col union select 2 as col union select 3 as col");
|
$set = $this->c->query("SELECT 1 as col union select 2 as col union select 3 as col");
|
||||||
$rows = [];
|
$rows = [];
|
||||||
$test = new Db\ResultSQLite3($set);
|
$test = new Db\SQLite3\Result($set);
|
||||||
foreach($test as $row) {
|
foreach($test as $row) {
|
||||||
$rows[] = $row['col'];
|
$rows[] = $row['col'];
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ class TestDbResultSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
function testGetSingleValues() {
|
function testGetSingleValues() {
|
||||||
$set = $this->c->query("SELECT 1867 as year union select 1970 as year union select 2112 as year");
|
$set = $this->c->query("SELECT 1867 as year union select 1970 as year union select 2112 as year");
|
||||||
$test = new Db\ResultSQLite3($set);
|
$test = new Db\SQLite3\Result($set);
|
||||||
$this->assertEquals(1867, $test->getValue());
|
$this->assertEquals(1867, $test->getValue());
|
||||||
$this->assertEquals(1970, $test->getValue());
|
$this->assertEquals(1970, $test->getValue());
|
||||||
$this->assertEquals(2112, $test->getValue());
|
$this->assertEquals(2112, $test->getValue());
|
||||||
|
@ -64,7 +64,7 @@ class TestDbResultSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
function testGetFirstValuesOnly() {
|
function testGetFirstValuesOnly() {
|
||||||
$set = $this->c->query("SELECT 1867 as year, 19 as century union select 1970 as year, 20 as century union select 2112 as year, 22 as century");
|
$set = $this->c->query("SELECT 1867 as year, 19 as century union select 1970 as year, 20 as century union select 2112 as year, 22 as century");
|
||||||
$test = new Db\ResultSQLite3($set);
|
$test = new Db\SQLite3\Result($set);
|
||||||
$this->assertEquals(1867, $test->getValue());
|
$this->assertEquals(1867, $test->getValue());
|
||||||
$this->assertEquals(1970, $test->getValue());
|
$this->assertEquals(1970, $test->getValue());
|
||||||
$this->assertEquals(2112, $test->getValue());
|
$this->assertEquals(2112, $test->getValue());
|
||||||
|
@ -77,7 +77,7 @@ class TestDbResultSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
['album' => '2112', 'track' => '2112'],
|
['album' => '2112', 'track' => '2112'],
|
||||||
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
|
||||||
];
|
];
|
||||||
$test = new Db\ResultSQLite3($set);
|
$test = new Db\SQLite3\Result($set);
|
||||||
$this->assertEquals($rows[0], $test->get());
|
$this->assertEquals($rows[0], $test->get());
|
||||||
$this->assertEquals($rows[1], $test->get());
|
$this->assertEquals($rows[1], $test->get());
|
||||||
$this->assertSame(null, $test->get());
|
$this->assertSame(null, $test->get());
|
||||||
|
|
|
@ -8,7 +8,7 @@ class TestDbStatementSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
use Test\Tools, Test\Db\BindingTests;
|
use Test\Tools, Test\Db\BindingTests;
|
||||||
|
|
||||||
protected $c;
|
protected $c;
|
||||||
static protected $imp = Db\StatementSQLite3::class;
|
static protected $imp = Db\SQLite3\Statement::class;
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
date_default_timezone_set("UTC");
|
date_default_timezone_set("UTC");
|
||||||
|
@ -36,7 +36,7 @@ class TestDbStatementSQLite3 extends \PHPUnit\Framework\TestCase {
|
||||||
|
|
||||||
function testConstructStatement() {
|
function testConstructStatement() {
|
||||||
$nativeStatement = $this->c->prepare("SELECT ? as value");
|
$nativeStatement = $this->c->prepare("SELECT ? as value");
|
||||||
$this->assertInstanceOf(Db\StatementSQLite3::class, new Db\StatementSQLite3($this->c, $nativeStatement));
|
$this->assertInstanceOf(Statement::class, new Db\SQLite3\Statement($this->c, $nativeStatement));
|
||||||
}
|
}
|
||||||
|
|
||||||
function testBindMissingValue() {
|
function testBindMissingValue() {
|
||||||
|
|
|
@ -12,7 +12,7 @@ class TestUserInternalDriver extends \PHPUnit\Framework\TestCase {
|
||||||
protected $data;
|
protected $data;
|
||||||
|
|
||||||
function setUp() {
|
function setUp() {
|
||||||
$drv = User\DriverInternal::class;
|
$drv = User\Internal\Driver::class;
|
||||||
$conf = new Conf();
|
$conf = new Conf();
|
||||||
$conf->userDriver = $drv;
|
$conf->userDriver = $drv;
|
||||||
$conf->userAuthPreferHTTP = true;
|
$conf->userAuthPreferHTTP = true;
|
||||||
|
|
Loading…
Reference in a new issue