mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
SQLite3 database driver in working condition
PDO stub for now; other drivers to come
This commit is contained in:
parent
03b86c222f
commit
6ffe942f99
19 changed files with 380 additions and 112 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,7 +4,7 @@ vendor/simplepie/*
|
|||
#temp files
|
||||
cache/*
|
||||
test.php
|
||||
newssync.db*
|
||||
/db
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
|
130
schema.sql
130
schema.sql
|
@ -1,109 +1,111 @@
|
|||
begin;
|
||||
|
||||
create table main.newssync_settings(
|
||||
key varchar(255) primary key not null, --
|
||||
value varchar(255), --
|
||||
type varchar(255) not null check(
|
||||
type in('numeric','text','timestamp', 'date', 'time', 'bool')
|
||||
) --
|
||||
);
|
||||
insert into main.newssync_settings values('schema_version',1,'int');
|
||||
|
||||
-- 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_type TEXT, -- avatar image's MIME content type
|
||||
avatar_data BLOB, -- avatar image's binary data
|
||||
admin boolean not null default 0 -- whether the user is an administrator
|
||||
create table main.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_type TEXT, -- avatar image's MIME content type
|
||||
avatar_data BLOB, -- avatar image's binary data
|
||||
admin boolean not null default 0 -- whether the user is an administrator
|
||||
);
|
||||
|
||||
-- TT-RSS categories and ownCloud folders
|
||||
create table newssync_categories(
|
||||
id integer primary key not null, -- sequence number
|
||||
owner TEXT references 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
|
||||
create table main.newssync_categories(
|
||||
id integer primary key not null, -- sequence number
|
||||
owner TEXT not null references 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
|
||||
);
|
||||
|
||||
-- newsfeeds, deduplicated
|
||||
create table newssync_feeds(
|
||||
id integer primary key not null, -- sequence number
|
||||
url TEXT not null, -- URL of feed
|
||||
title TEXT, -- default title of feed
|
||||
favicon TEXT, -- URL of favicon
|
||||
source TEXT, -- URL of site to which the feed belongs
|
||||
updated datetime, -- time at which the feed was last fetched
|
||||
modified datetime not null default CURRENT_TIMESTAMP, --
|
||||
err_count integer not null default 0, -- count of successive times update resulted in error since last successful update
|
||||
err_msg TEXT, -- last error message
|
||||
username TEXT, -- HTTP authentication username
|
||||
password TEXT, -- HTTP authentication password (this is stored in plain text)
|
||||
unique(url,username,password) -- a URL with particular credentials should only appear once
|
||||
create table feeds.newssync_feeds(
|
||||
id integer primary key not null, -- sequence number
|
||||
url TEXT not null, -- URL of feed
|
||||
title TEXT, -- default title of feed
|
||||
favicon TEXT, -- URL of favicon
|
||||
source TEXT, -- URL of site to which the feed belongs
|
||||
updated datetime, -- time at which the feed was last fetched
|
||||
modified datetime not null default CURRENT_TIMESTAMP, --
|
||||
err_count integer not null default 0, -- count of successive times update resulted in error since last successful update
|
||||
err_msg TEXT, -- last error message
|
||||
username TEXT, -- HTTP authentication username
|
||||
password TEXT, -- HTTP authentication password (this is stored in plain text)
|
||||
unique(url,username,password) -- a URL with particular credentials should only appear once
|
||||
);
|
||||
|
||||
-- users' subscriptions to newsfeeds, with settings
|
||||
create table newssync_subscriptions(
|
||||
create table main.newssync_subscriptions(
|
||||
id integer primary key not null, -- sequence number
|
||||
owner TEXT references users(id) on delete cascade on update cascade, -- owner of subscription
|
||||
feed integer references feeds(id) on delete cascade, -- feed for the subscription
|
||||
owner TEXT not null references users(id) on delete cascade on update cascade, -- owner of subscription
|
||||
feed integer not null references 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 categories(id) on delete set null, -- TT-RSS category (nestable); the first-level category (which acts as ownCloud folder) is joined in when needed
|
||||
category integer not null references 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
|
||||
);
|
||||
|
||||
-- entries in newsfeeds
|
||||
create table newssync_articles(
|
||||
id integer primary key not null, -- sequence number
|
||||
feed integer references feeds(id) on delete cascade, -- feed for the subscription
|
||||
url TEXT not null, -- URL of article
|
||||
title TEXT, -- article title
|
||||
author TEXT, -- author's name
|
||||
published datetime, -- time of original publication
|
||||
edited datetime, -- time of last edit
|
||||
guid TEXT, -- GUID
|
||||
content TEXT, -- content, as (X)HTML
|
||||
modified datetime not null default CURRENT_TIMESTAMP, -- date when article properties were last modified
|
||||
hash varchar(64) not null, -- ownCloud hash
|
||||
fingerprint varchar(64) not null, -- ownCloud fingerprint
|
||||
enclosures_hash varchar(64), -- hash of enclosures, if any; since enclosures are not uniquely identified, we need to know when they change
|
||||
tags_hash varchar(64) -- hash of RSS/Atom categories included in article; since these categories are not uniquely identified, we need to know when they change
|
||||
create table feeds.newssync_articles(
|
||||
id integer primary key not null, -- sequence number
|
||||
feed integer not null references feeds(id) on delete cascade, -- feed for the subscription
|
||||
url TEXT not null, -- URL of article
|
||||
title TEXT, -- article title
|
||||
author TEXT, -- author's name
|
||||
published datetime, -- time of original publication
|
||||
edited datetime, -- time of last edit
|
||||
guid TEXT, -- GUID
|
||||
content TEXT, -- content, as (X)HTML
|
||||
modified datetime not null default CURRENT_TIMESTAMP, -- date when article properties were last modified
|
||||
hash varchar(64) not null, -- ownCloud hash
|
||||
fingerprint varchar(64) not null, -- ownCloud fingerprint
|
||||
enclosures_hash varchar(64), -- hash of enclosures, if any; since enclosures are not uniquely identified, we need to know when they change
|
||||
tags_hash varchar(64) -- hash of RSS/Atom categories included in article; since these categories are not uniquely identified, we need to know when they change
|
||||
);
|
||||
|
||||
-- users' actions on newsfeed entries
|
||||
create table newssync_subscription_articles(
|
||||
create table main.newssync_subscription_articles(
|
||||
id integer primary key not null,
|
||||
article integer references articles(id) on delete cascade,
|
||||
article integer not null references articles(id) on delete cascade,
|
||||
read boolean not null default 0,
|
||||
starred boolean not null default 0,
|
||||
modified datetime not null default CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- enclosures associated with articles
|
||||
create table newssync_enclosures(
|
||||
article integer references articles(id) on delete cascade,
|
||||
create table main.newssync_enclosures(
|
||||
article integer not null references articles(id) on delete cascade,
|
||||
url TEXT,
|
||||
type varchar(255)
|
||||
);
|
||||
|
||||
-- author labels ("categories" in RSS/Atom parlance) associated with newsfeed entries
|
||||
create table newssync_tags(
|
||||
article integer references articles(id) on delete cascade,
|
||||
create table main.newssync_tags(
|
||||
article integer not null references articles(id) on delete cascade,
|
||||
name TEXT
|
||||
);
|
||||
|
||||
-- user labels associated with newsfeed entries
|
||||
create table newssync_labels(
|
||||
sub_article integer references subscription_articles(id) on delete cascade,
|
||||
owner TEXT references users(id) on delete cascade on update cascade,
|
||||
create table main.newssync_labels(
|
||||
sub_article integer not null references subscription_articles(id) on delete cascade,
|
||||
owner TEXT not null references users(id) on delete cascade on update cascade,
|
||||
name TEXT
|
||||
);
|
||||
create index newssync_label_names on newssync_labels(name);
|
||||
|
||||
create table newssync_settings(
|
||||
key varchar(255) primary key not null,
|
||||
value varchar(255),
|
||||
type varchar(255) not null
|
||||
);
|
||||
insert into newssync_settings values('schema_version',0,'int');
|
||||
create index main.newssync_label_names on newssync_labels(name);
|
||||
|
||||
commit;
|
|
@ -2,7 +2,7 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Auth;
|
||||
|
||||
Interface AuthInterface {
|
||||
Interface Driver {
|
||||
public function __construct($conf, $db);
|
||||
public function auth(): bool;
|
||||
public function authHTTP(): bool;
|
|
@ -2,7 +2,7 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Auth;
|
||||
|
||||
class Internal implements AuthInterface {
|
||||
class Internal implements Driver {
|
||||
protected $conf;
|
||||
protected $db;
|
||||
|
||||
|
|
2
vendor/JKingWeb/NewsSync/Conf.php
vendored
2
vendor/JKingWeb/NewsSync/Conf.php
vendored
|
@ -6,7 +6,7 @@ class Conf {
|
|||
public $lang = "en";
|
||||
|
||||
public $dbClass = NS_BASE."Db\\DriverSQLite3";
|
||||
public $dbSQLite3File = BASE."newssync.db";
|
||||
public $dbSQLite3Path = BASE."db";
|
||||
public $dbSQLite3Key = "";
|
||||
public $dbPostgreSQLHost = "localhost";
|
||||
public $dbPostgreSQLUser = "newssync";
|
||||
|
|
23
vendor/JKingWeb/NewsSync/Database.php
vendored
23
vendor/JKingWeb/NewsSync/Database.php
vendored
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync;
|
||||
|
||||
class Database {
|
||||
|
@ -6,10 +7,26 @@ class Database {
|
|||
|
||||
public function __construct(Conf $conf) {
|
||||
$driver = $conf->dbClass;
|
||||
$this->drv = new $driver($conf);
|
||||
$this->drv = $driver::create($conf);
|
||||
}
|
||||
|
||||
static public function listDrivers() {
|
||||
|
||||
static public function listDrivers(): array {
|
||||
$sep = \DIRECTORY_SEPARATOR;
|
||||
$path = __DIR__.$sep."Db".$sep;
|
||||
$classes = [];
|
||||
foreach(glob($path."Driver?*.php") as $file) {
|
||||
$name = basename($file, ".php");
|
||||
if(substr($name,-3) != "PDO") {
|
||||
$name = NS_BASE."Db\\$name";
|
||||
if(class_exists($name)) {
|
||||
$classes[$name] = $name::driverName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
|
||||
public function schemaVersion(): int {
|
||||
return $this->drv->schemaVersion();
|
||||
}
|
||||
}
|
47
vendor/JKingWeb/NewsSync/Db/Common.php
vendored
Normal file
47
vendor/JKingWeb/NewsSync/Db/Common.php
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
Trait Common {
|
||||
protected $transDepth;
|
||||
|
||||
public function begin(): bool {
|
||||
if($this->transDepth==0) {
|
||||
$this->exec("BEGIN TRANSACTION");
|
||||
} else{
|
||||
$this->exec("SAVEPOINT newssync_".$this->transDepth);
|
||||
}
|
||||
$this->transDepth += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function commit(bool $all = false): bool {
|
||||
if($this->transDepth==0) return false;
|
||||
if(!$all) {
|
||||
$this->exec("RELEASE SAVEPOINT newssync_".$this->transDepth-1);
|
||||
$this->transDepth -= 1;
|
||||
} else {
|
||||
$this->exec("COMMIT TRANSACTION");
|
||||
$this->transDepth = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rollback(bool $all = false): bool {
|
||||
if($this->transDepth==0) return false;
|
||||
if(!$all) {
|
||||
$this->exec("ROLLBACK TRANSACTION TO SAVEPOINT newssync_".$this->transDepth-1);
|
||||
$this->transDepth -= 1;
|
||||
if($this->transDepth==0) $this->exec("ROLLBACK TRANSACTION");
|
||||
} else {
|
||||
$this->exec("ROLLBACK TRANSACTION");
|
||||
$this->transDepth = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function prepare(string $query, string ...$paramType): Statement {
|
||||
return $this->prepareArray($query, $paramType);
|
||||
}
|
||||
|
||||
}
|
17
vendor/JKingWeb/NewsSync/Db/CommonPDO.php
vendored
Normal file
17
vendor/JKingWeb/NewsSync/Db/CommonPDO.php
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
Trait CommonPDO {
|
||||
public function unsafeQuery(string $query): Result {
|
||||
return new ResultPDO($this->db->query($query));
|
||||
}
|
||||
|
||||
public function prepareArray(string $query, array $paramTypes): Statement {
|
||||
return new StatementPDO($query, $paramTypes);
|
||||
}
|
||||
|
||||
public function prepare(string $query, string ...$paramType): Statement {
|
||||
return $this->prepareArray($query, $paramType);
|
||||
}
|
||||
}
|
18
vendor/JKingWeb/NewsSync/Db/CommonSQLite3.php
vendored
Normal file
18
vendor/JKingWeb/NewsSync/Db/CommonSQLite3.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
Trait CommonSQLite3 {
|
||||
|
||||
static public function driverName(): string {
|
||||
return "SQLite 3";
|
||||
}
|
||||
|
||||
public function schemaVersion(string $schema = "main"): int {
|
||||
return $this->unsafeQuery("PRAGMA $schema.user_version")->getSingle();
|
||||
}
|
||||
|
||||
public function exec(string $query): bool {
|
||||
return (bool) $this->db->exec($query);
|
||||
}
|
||||
}
|
15
vendor/JKingWeb/NewsSync/Db/Driver.php
vendored
Normal file
15
vendor/JKingWeb/NewsSync/Db/Driver.php
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
interface Driver {
|
||||
static function create(\JKingWeb\NewsSync\Conf $conf, bool $install = false): Driver;
|
||||
static function driverName(): string;
|
||||
function schemaVersion(): int;
|
||||
function begin(): bool;
|
||||
function commit(): bool;
|
||||
function rollback(): bool;
|
||||
function exec(string $query): bool;
|
||||
function unsafeQuery(string $query): Result;
|
||||
function prepare(string $query, string ...$paramType): Statement;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
interface DriverInterface {
|
||||
function __construct(\JKingWeb\NewsSync\Conf $conf);
|
||||
static function driverName(): string;
|
||||
}
|
81
vendor/JKingWeb/NewsSync/Db/DriverSQLite3.php
vendored
81
vendor/JKingWeb/NewsSync/Db/DriverSQLite3.php
vendored
|
@ -1,44 +1,65 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
class DriverSQLite3 implements DriverInterface {
|
||||
protected $db;
|
||||
protected $pdo = false;
|
||||
class DriverSQLite3 implements Driver {
|
||||
use Common, CommonSQLite3;
|
||||
|
||||
public function __construct(\JKingWeb\NewsSync\Conf $conf, bool $install = false) {
|
||||
protected $db;
|
||||
|
||||
private function __construct(\JKingWeb\NewsSync\Conf $conf, bool $install = false) {
|
||||
// normalize the path
|
||||
$path = $conf->dbSQLite3Path;
|
||||
$sep = \DIRECTORY_SEPARATOR;
|
||||
if(substr($path,-(strlen($sep))) != $sep) $path .= $sep;
|
||||
$mainfile = $path."newssync-main.db";
|
||||
$feedfile = $path."newssync-feeds.db";
|
||||
// if the files exists (or we're initializing the database), try to open it and set initial options
|
||||
try {
|
||||
$this->db = new \SQLite3($mainfile, ($install) ? \SQLITE3_OPEN_READWRITE | \SQLITE3_OPEN_CREATE : \SQLITE3_OPEN_READWRITE, $conf->dbSQLite3Key);
|
||||
$this->db->enableExceptions(true);
|
||||
$attach = "'".$this->db->escapeString($feedfile)."'";
|
||||
$this->exec("ATTACH DATABASE $attach AS feeds");
|
||||
$this->exec("PRAGMA main.jounral_mode = wal");
|
||||
$this->exec("PRAGMA feeds.jounral_mode = wal");
|
||||
$this->exec("PRAGMA foreign_keys = yes");
|
||||
} catch(\Throwable $e) {
|
||||
// if opening the database doesn't work, check various pre-conditions to find out what the problem might be
|
||||
foreach([$mainfile, $mainfile."-wal", $mainfile."-shm", $feedfile, $feedfile."-wal", $feedfile."-shm"] as $file) {
|
||||
if(!file_exists($file)) {
|
||||
if($install && !is_writable(dirname($file))) throw new Exception("fileUncreatable", dirname($file));
|
||||
throw new Exception("fileMissing", $file);
|
||||
}
|
||||
if(!is_readable($file) && !is_writable($file)) throw new Exception("fileUnusable", $file);
|
||||
if(!is_readable($file)) throw new Exception("fileUnreadable", $file);
|
||||
if(!is_writable($file)) throw new Exception("fileUnwritable", $file);
|
||||
}
|
||||
// otherwise the database is probably corrupt
|
||||
throw new Exception("fileCorrupt", $mainfile);
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->db->close();
|
||||
unset($this->db);
|
||||
}
|
||||
|
||||
static public function create(\JKingWeb\NewsSync\Conf $conf, bool $install = false): Driver {
|
||||
// check to make sure required extensions are loaded
|
||||
if(class_exists("SQLite3")) {
|
||||
$this->pdo = false;
|
||||
return new self($conf, $install);
|
||||
} else if(class_exists("PDO") && in_array("sqlite",\PDO::getAvailableDrivers())) {
|
||||
$this->pdo = true;
|
||||
return new DriverSQLite3PDO($conf, $install);
|
||||
} else {
|
||||
throw new Exception("extMissing", self::driverName());
|
||||
}
|
||||
// if the file exists (or we're initializing the database), try to open it and set initial options
|
||||
if((!$install && file_exists($conf->dbSQLite3File)) || $install) {
|
||||
try {
|
||||
$this->db = ($this->PDO) ? (new \SQLite3($conf->dbSQLite3File, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $conf->dbSQLite3Key)) : (new PDO("sqlite:".$conf->dbSQLite3File));
|
||||
//FIXME: add foreign key enforcement, WAL mode
|
||||
} catch(\Throwable $e) {
|
||||
// if opening the database doesn't work, check various pre-conditions to find out what the problem might be
|
||||
foreach([$conf->dbSQLite3File, $conf->dbSQLite3File."-wal", $conf->dbSQLite3File."-shm"] as $file) {
|
||||
if(!file_exists($file)) {
|
||||
if($install && !is_writable(dirname($file))) throw new Exception("fileUncreatable", dirname($file));
|
||||
throw new Exception("fileMissing", $file);
|
||||
}
|
||||
if(!is_readable($file) && !is_writable($file)) throw new Exception("fileUnusable", $file);
|
||||
if(!is_readable($file)) throw new Exception("fileUnreadable", $file);
|
||||
if(!is_writable($file)) throw new Exception("fileUnwritable", $file);
|
||||
}
|
||||
// otherwise the database is probably corrupt
|
||||
throw new Exception("fileCorrupt", $conf->dbSQLite3File);
|
||||
}
|
||||
} else {
|
||||
throw new Exception("fileMissing", $conf->dbSQLite3File);
|
||||
}
|
||||
}
|
||||
|
||||
static public function driverName(): string {
|
||||
return "SQLite3";
|
||||
public function unsafeQuery(string $query): Result {
|
||||
return new ResultSQLite3($this->db->query($query));
|
||||
}
|
||||
|
||||
public function prepareArray(string $query, array $paramTypes): Statement {
|
||||
return new StatementSQLite3($query, $paramTypes);
|
||||
}
|
||||
}
|
28
vendor/JKingWeb/NewsSync/Db/DriverSQLite3PDO.php
vendored
Normal file
28
vendor/JKingWeb/NewsSync/Db/DriverSQLite3PDO.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
class DriverSQLite3 implements Driver {
|
||||
use CommonPDO, CommonSQLite3;
|
||||
|
||||
protected $db;
|
||||
|
||||
private function __construct(\JKingWeb\NewsSync\Conf $conf, bool $install = false) {
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
// FIXME: stub
|
||||
}
|
||||
|
||||
static public function create(\JKingWeb\NewsSync\Conf $conf, bool $install = false): Driver {
|
||||
// check to make sure required extensions are loaded
|
||||
if(class_exists("PDO") && in_array("sqlite",\PDO::getAvailableDrivers())) {
|
||||
return new self($conf, $install);
|
||||
} else if(class_exists("SQLite3")) {
|
||||
return new DriverSQLite3($conf, $install);
|
||||
} else {
|
||||
throw new Exception("extMissing", self::driverName());
|
||||
}
|
||||
}
|
||||
}
|
9
vendor/JKingWeb/NewsSync/Db/Result.php
vendored
Normal file
9
vendor/JKingWeb/NewsSync/Db/Result.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
interface Result {
|
||||
function __invoke(); // alias of get()
|
||||
function get();
|
||||
function getSingle();
|
||||
}
|
30
vendor/JKingWeb/NewsSync/Db/ResultSQLite3.php
vendored
Normal file
30
vendor/JKingWeb/NewsSync/Db/ResultSQLite3.php
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
class ResultSQLite3 implements Result {
|
||||
protected $set;
|
||||
|
||||
public function __construct(\SQLite3Result $resultObj) {
|
||||
$this->set = $resultObj;
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->set->finalize();
|
||||
unset($this->set);
|
||||
}
|
||||
|
||||
public function __invoke() {
|
||||
return $this->get();
|
||||
}
|
||||
|
||||
public function get() {
|
||||
return $this->set->fetchArray(\SQLITE3_ASSOC);
|
||||
}
|
||||
|
||||
public function getSingle() {
|
||||
$res = $this->get();
|
||||
if($res===FALSE) return null;
|
||||
return array_shift($res);
|
||||
}
|
||||
}
|
9
vendor/JKingWeb/NewsSync/Db/Statement.php
vendored
Normal file
9
vendor/JKingWeb/NewsSync/Db/Statement.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
interface Statement {
|
||||
function __invoke(...$bindings); // alias of run()
|
||||
function run(...$bindings): Result;
|
||||
function runArray(array $bindings): Result;
|
||||
}
|
62
vendor/JKingWeb/NewsSync/Db/StatementSQLite3.php
vendored
Normal file
62
vendor/JKingWeb/NewsSync/Db/StatementSQLite3.php
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\NewsSync\Db;
|
||||
|
||||
class StatementSQLite3 implements Statement {
|
||||
protected $st;
|
||||
protected $types;
|
||||
|
||||
public function __construct(\SQLite3Stmt $st, $bindings = null) {
|
||||
$this->st = $st;
|
||||
$this->types = [];
|
||||
foreach($bindings as $binding) {
|
||||
switch(trim(strtolower($binding))) {
|
||||
case "int":
|
||||
case "integer":
|
||||
$this->types[] = \SQLITE3_INTEGER; break;
|
||||
case "float":
|
||||
case "double":
|
||||
case "real":
|
||||
case "numeric":
|
||||
$this->types[] = \SQLITE3_FLOAT; break;
|
||||
case "blob":
|
||||
case "bin":
|
||||
case "binary":
|
||||
$this->types[] = \SQLITE3_BLOB; break;
|
||||
case "text":
|
||||
case "string":
|
||||
case "str":
|
||||
$this->types[] = \SQLITE3_TEXT; break;
|
||||
default:
|
||||
$this->types[] = \SQLITE3_TEXT; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->st->close();
|
||||
unset($this->st);
|
||||
}
|
||||
|
||||
public function __invoke(&...$values) {
|
||||
return $this->runArray($values);
|
||||
}
|
||||
|
||||
public function run(&...$values): Result {
|
||||
return $this->runArray($values);
|
||||
}
|
||||
|
||||
public function runArray(array &$values = null): Result {
|
||||
$this->st->clear();
|
||||
$l = sizeof($values);
|
||||
for($a = 0; $a < $l; $a++) {
|
||||
if($values[$a]===null) {
|
||||
$type = \SQLITE3_NULL;
|
||||
} else {
|
||||
$type = (array_key_exists($a,$this->types)) ? $this->types[$a] : \SQLITE3_TEXT;
|
||||
}
|
||||
$st->bindParam($a+1, $values[$a], $type);
|
||||
}
|
||||
return new ResultSQLite3($st->execute());
|
||||
}
|
||||
}
|
2
vendor/JKingWeb/NewsSync/Exception.php
vendored
2
vendor/JKingWeb/NewsSync/Exception.php
vendored
|
@ -13,7 +13,7 @@ class Exception extends \Exception {
|
|||
"Lang/Exception.stringMissing" => 10105,
|
||||
];
|
||||
|
||||
public function __construct(string $msgID = "", $vars = null, Throwable $e = null) {
|
||||
public function __construct(string $msgID = "", $vars = null, \Throwable $e = null) {
|
||||
if($msgID=="") {
|
||||
$msg = "";
|
||||
$code = 0;
|
||||
|
|
6
vendor/JKingWeb/NewsSync/RuntimeData.php
vendored
6
vendor/JKingWeb/NewsSync/RuntimeData.php
vendored
|
@ -3,9 +3,9 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\NewsSync;
|
||||
|
||||
class RuntimeData {
|
||||
protected $conf;
|
||||
protected $db;
|
||||
protected $auth;
|
||||
public $conf;
|
||||
public $db;
|
||||
public $auth;
|
||||
|
||||
public function __construct(Conf $conf) {
|
||||
$this->conf = $conf;
|
||||
|
|
Loading…
Reference in a new issue