Moved Sql and Database.php to remote project
This commit is contained in:
parent
82b0d9a63a
commit
34b9a80ba7
67 changed files with 341 additions and 1307 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -4,3 +4,6 @@
|
||||||
[submodule "php-markdown"]
|
[submodule "php-markdown"]
|
||||||
path = lib/php-markdown
|
path = lib/php-markdown
|
||||||
url = https://github.com/michelf/php-markdown.git
|
url = https://github.com/michelf/php-markdown.git
|
||||||
|
[submodule "lib/chibi-sql"]
|
||||||
|
path = lib/chibi-sql
|
||||||
|
url = https://github.com/rr-/chibi-sql.git
|
||||||
|
|
1
lib/chibi-sql
Submodule
1
lib/chibi-sql
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit a5d7a03965e7089c070defa5907798a1df66c847
|
|
@ -1,4 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class Bootstrap
|
class Bootstrap
|
||||||
{
|
{
|
||||||
public function render($callback = null)
|
public function render($callback = null)
|
||||||
|
|
|
@ -47,27 +47,8 @@ class IndexController
|
||||||
//check if post was deleted
|
//check if post was deleted
|
||||||
$featuredPost = PostModel::findById($featuredPostId, false);
|
$featuredPost = PostModel::findById($featuredPostId, false);
|
||||||
if (!$featuredPost)
|
if (!$featuredPost)
|
||||||
return $this->featureNewPost();
|
return PropertyModel::featureNewPost();
|
||||||
|
|
||||||
return $featuredPost;
|
return $featuredPost;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function featureNewPost()
|
|
||||||
{
|
|
||||||
$stmt = (new SqlSelectStatement)
|
|
||||||
->setColumn('id')
|
|
||||||
->setTable('post')
|
|
||||||
->setCriterion((new SqlConjunctionFunctor)
|
|
||||||
->add(new SqlEqualsFunctor('type', new SqlBinding(PostType::Image)))
|
|
||||||
->add(new SqlEqualsFunctor('safety', new SqlBinding(PostSafety::Safe))))
|
|
||||||
->setOrderBy(new SqlRandomFunctor(), SqlSelectStatement::ORDER_DESC);
|
|
||||||
$featuredPostId = Database::fetchOne($stmt)['id'];
|
|
||||||
if (!$featuredPostId)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
PropertyModel::set(PropertyModel::FeaturedPostId, $featuredPostId);
|
|
||||||
PropertyModel::set(PropertyModel::FeaturedPostDate, time());
|
|
||||||
PropertyModel::set(PropertyModel::FeaturedPostUserName, null);
|
|
||||||
return PostModel::findById($featuredPostId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ class PostController
|
||||||
|
|
||||||
if (InputHelper::get('submit'))
|
if (InputHelper::get('submit'))
|
||||||
{
|
{
|
||||||
Database::transaction(function()
|
\Chibi\Database::transaction(function()
|
||||||
{
|
{
|
||||||
$post = PostModel::spawn();
|
$post = PostModel::spawn();
|
||||||
LogHelper::bufferChanges();
|
LogHelper::bufferChanges();
|
||||||
|
|
134
src/Database.php
134
src/Database.php
|
@ -1,134 +0,0 @@
|
||||||
<?php
|
|
||||||
class Database
|
|
||||||
{
|
|
||||||
protected static $pdo = null;
|
|
||||||
protected static $queryLogs = [];
|
|
||||||
|
|
||||||
public static function connect($driver, $location, $user, $pass)
|
|
||||||
{
|
|
||||||
if (self::connected())
|
|
||||||
throw new Exception('Database is already connected');
|
|
||||||
|
|
||||||
$dsn = $driver . ':' . $location;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
self::$pdo = new PDO($dsn, $user, $pass);
|
|
||||||
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
self::$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
|
||||||
self::$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
self::$pdo = null;
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function convertStatement(SqlStatement $stmt)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$stmtText = $stmt->getAsString();
|
|
||||||
$stmtPdo = self::$pdo->prepare($stmtText);
|
|
||||||
foreach ($stmt->getBindings() as $key => $value)
|
|
||||||
if (strpos($stmtText, $key) !== false)
|
|
||||||
$stmtPdo->bindValue($key, $value);
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception('Problem with ' . $stmt->getAsString() . ' creation (' . $e->getMessage() . ')');
|
|
||||||
}
|
|
||||||
return $stmtPdo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function disconnect()
|
|
||||||
{
|
|
||||||
self::$pdo = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function connected()
|
|
||||||
{
|
|
||||||
return self::$pdo !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function execInternal(SqlStatement $stmt, $callback)
|
|
||||||
{
|
|
||||||
if (!self::connected())
|
|
||||||
throw new Exception('Database is not connected');
|
|
||||||
|
|
||||||
$stmtPdo = self::convertStatement($stmt);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$timeStart = microtime(true);
|
|
||||||
$stmtPdo->execute();
|
|
||||||
$timeExec = microtime(true) - $timeStart;
|
|
||||||
|
|
||||||
$timeStart = microtime(true);
|
|
||||||
$ret = $callback($stmtPdo);
|
|
||||||
$timeFetch = microtime(true) - $timeStart;
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new Exception('Problem with ' . $stmt->getAsString() . ' execution (' . $e->getMessage() . ')');
|
|
||||||
}
|
|
||||||
$queryLog = new StdClass();
|
|
||||||
$queryLog->statement = $stmt;
|
|
||||||
$queryLog->timeExec = $timeExec;
|
|
||||||
$queryLog->timeFetch = $timeFetch;
|
|
||||||
self::$queryLogs []= $queryLog;
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function exec(SqlStatement $stmt)
|
|
||||||
{
|
|
||||||
return self::execInternal($stmt, function($stmtPdo) { });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fetchOne(SqlStatement $stmt)
|
|
||||||
{
|
|
||||||
return self::execInternal($stmt, function($stmtPdo) { return $stmtPdo->fetch(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fetchAll(SqlStatement $stmt)
|
|
||||||
{
|
|
||||||
return self::execInternal($stmt, function($stmtPdo) { return $stmtPdo->fetchAll(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getLogs()
|
|
||||||
{
|
|
||||||
return self::$queryLogs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function inTransaction()
|
|
||||||
{
|
|
||||||
return self::$pdo->inTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function lastInsertId()
|
|
||||||
{
|
|
||||||
return self::$pdo->lastInsertId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function transaction($func)
|
|
||||||
{
|
|
||||||
if (self::inTransaction())
|
|
||||||
{
|
|
||||||
return $func();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
self::$pdo->beginTransaction();
|
|
||||||
$ret = $func();
|
|
||||||
self::$pdo->commit();
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
self::$pdo->rollBack();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
abstract class AbstractCrudModel implements IModel
|
abstract class AbstractCrudModel implements IModel
|
||||||
{
|
{
|
||||||
public static function spawn()
|
public static function spawn()
|
||||||
|
@ -21,10 +24,10 @@ abstract class AbstractCrudModel implements IModel
|
||||||
|
|
||||||
public static function findById($key, $throw = true)
|
public static function findById($key, $throw = true)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setTable(static::getTableName());
|
$stmt->setTable(static::getTableName());
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($key)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($key)));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -37,10 +40,10 @@ abstract class AbstractCrudModel implements IModel
|
||||||
|
|
||||||
public static function findByIds(array $ids)
|
public static function findByIds(array $ids)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setTable(static::getTableName());
|
$stmt->setTable(static::getTableName());
|
||||||
$stmt->setCriterion(SqlInFunctor::fromArray('id', SqlBinding::fromArray(array_unique($ids))));
|
$stmt->setCriterion(Sql\InFunctor::fromArray('id', Sql\Binding::fromArray(array_unique($ids))));
|
||||||
|
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
if ($rows)
|
if ($rows)
|
||||||
|
@ -51,8 +54,8 @@ abstract class AbstractCrudModel implements IModel
|
||||||
|
|
||||||
public static function getCount()
|
public static function getCount()
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setTable(static::getTableName());
|
$stmt->setTable(static::getTableName());
|
||||||
return Database::fetchOne($stmt)['count'];
|
return Database::fetchOne($stmt)['count'];
|
||||||
}
|
}
|
||||||
|
@ -107,7 +110,7 @@ abstract class AbstractCrudModel implements IModel
|
||||||
throw new Exception('Can be run only within transaction');
|
throw new Exception('Can be run only within transaction');
|
||||||
if (!$entity->id)
|
if (!$entity->id)
|
||||||
{
|
{
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable($table);
|
$stmt->setTable($table);
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
$entity->id = Database::lastInsertId();
|
$entity->id = Database::lastInsertId();
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class CommentModel extends AbstractCrudModel
|
class CommentModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
public static function getTableName()
|
public static function getTableName()
|
||||||
|
@ -25,12 +28,12 @@ class CommentModel extends AbstractCrudModel
|
||||||
'comment_date' => $comment->commentDate,
|
'comment_date' => $comment->commentDate,
|
||||||
'commenter_id' => $comment->commenterId];
|
'commenter_id' => $comment->commenterId];
|
||||||
|
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($comment->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($comment->id)));
|
||||||
|
|
||||||
foreach ($bindings as $key => $val)
|
foreach ($bindings as $key => $val)
|
||||||
$stmt->setColumn($key, new SqlBinding($val));
|
$stmt->setColumn($key, new Sql\Binding($val));
|
||||||
|
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
|
@ -40,9 +43,9 @@ class CommentModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($comment)
|
Database::transaction(function() use ($comment)
|
||||||
{
|
{
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($comment->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($comment->id)));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -51,10 +54,10 @@ class CommentModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findAllByPostId($key)
|
public static function findAllByPostId($key)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('comment.*');
|
$stmt->setColumn('comment.*');
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('post_id', new SqlBinding($key)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('post_id', new Sql\Binding($key)));
|
||||||
|
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
if ($rows)
|
if ($rows)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PostEntity extends AbstractEntity
|
class PostEntity extends AbstractEntity
|
||||||
{
|
{
|
||||||
public $type;
|
public $type;
|
||||||
|
@ -51,11 +54,11 @@ class PostEntity extends AbstractEntity
|
||||||
{
|
{
|
||||||
if ($this->hasCache('favoritee'))
|
if ($this->hasCache('favoritee'))
|
||||||
return $this->getCache('favoritee');
|
return $this->getCache('favoritee');
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('user.*');
|
$stmt->setColumn('user.*');
|
||||||
$stmt->setTable('user');
|
$stmt->setTable('user');
|
||||||
$stmt->addInnerJoin('favoritee', new SqlEqualsFunctor('favoritee.user_id', 'user.id'));
|
$stmt->addInnerJoin('favoritee', new Sql\EqualsFunctor('favoritee.user_id', 'user.id'));
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('favoritee.post_id', new SqlBinding($this->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('favoritee.post_id', new Sql\Binding($this->id)));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
$favorites = UserModel::convertRows($rows);
|
$favorites = UserModel::convertRows($rows);
|
||||||
$this->setCache('favoritee', $favorites);
|
$this->setCache('favoritee', $favorites);
|
||||||
|
@ -69,19 +72,19 @@ class PostEntity extends AbstractEntity
|
||||||
if ($this->hasCache('relations'))
|
if ($this->hasCache('relations'))
|
||||||
return $this->getCache('relations');
|
return $this->getCache('relations');
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('post.*');
|
$stmt->setColumn('post.*');
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$binding = new SqlBinding($this->id);
|
$binding = new Sql\Binding($this->id);
|
||||||
$stmt->addInnerJoin('crossref', (new SqlDisjunctionFunctor)
|
$stmt->addInnerJoin('crossref', (new Sql\DisjunctionFunctor)
|
||||||
->add(
|
->add(
|
||||||
(new SqlConjunctionFunctor)
|
(new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post.id', 'crossref.post2_id'))
|
->add(new Sql\EqualsFunctor('post.id', 'crossref.post2_id'))
|
||||||
->add(new SqlEqualsFunctor('crossref.post_id', $binding)))
|
->add(new Sql\EqualsFunctor('crossref.post_id', $binding)))
|
||||||
->add(
|
->add(
|
||||||
(new SqlConjunctionFunctor)
|
(new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post.id', 'crossref.post_id'))
|
->add(new Sql\EqualsFunctor('post.id', 'crossref.post_id'))
|
||||||
->add(new SqlEqualsFunctor('crossref.post2_id', $binding))));
|
->add(new Sql\EqualsFunctor('crossref.post2_id', $binding))));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
$posts = PostModel::convertRows($rows);
|
$posts = PostModel::convertRows($rows);
|
||||||
$this->setCache('relations', $posts);
|
$this->setCache('relations', $posts);
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class TagEntity extends AbstractEntity
|
class TagEntity extends AbstractEntity
|
||||||
{
|
{
|
||||||
public $name;
|
public $name;
|
||||||
|
|
||||||
public function getPostCount()
|
public function getPostCount()
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('tag_id', new SqlBinding($this->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('tag_id', new Sql\Binding($this->id)));
|
||||||
return Database::fetchOne($stmt)['count'];
|
return Database::fetchOne($stmt)['count'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class UserEntity extends AbstractEntity
|
class UserEntity extends AbstractEntity
|
||||||
{
|
{
|
||||||
public $name;
|
public $name;
|
||||||
|
@ -111,23 +114,23 @@ class UserEntity extends AbstractEntity
|
||||||
|
|
||||||
public function hasFavorited($post)
|
public function hasFavorited($post)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
$stmt->setCriterion((new SqlConjunctionFunctor)
|
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('user_id', new SqlBinding($this->id)))
|
->add(new Sql\EqualsFunctor('user_id', new Sql\Binding($this->id)))
|
||||||
->add(new SqlEqualsFunctor('post_id', new SqlBinding($post->id))));
|
->add(new Sql\EqualsFunctor('post_id', new Sql\Binding($post->id))));
|
||||||
return Database::fetchOne($stmt)['count'] == 1;
|
return Database::fetchOne($stmt)['count'] == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getScore($post)
|
public function getScore($post)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('score');
|
$stmt->setColumn('score');
|
||||||
$stmt->setTable('post_score');
|
$stmt->setTable('post_score');
|
||||||
$stmt->setCriterion((new SqlConjunctionFunctor)
|
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('user_id', new SqlBinding($this->id)))
|
->add(new Sql\EqualsFunctor('user_id', new Sql\Binding($this->id)))
|
||||||
->add(new SqlEqualsFunctor('post_id', new SqlBinding($post->id))));
|
->add(new Sql\EqualsFunctor('post_id', new Sql\Binding($post->id))));
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
return intval($row['score']);
|
return intval($row['score']);
|
||||||
|
@ -136,28 +139,28 @@ class UserEntity extends AbstractEntity
|
||||||
|
|
||||||
public function getFavoriteCount()
|
public function getFavoriteCount()
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('user_id', new SqlBinding($this->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('user_id', new Sql\Binding($this->id)));
|
||||||
return Database::fetchOne($stmt)['count'];
|
return Database::fetchOne($stmt)['count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCommentCount()
|
public function getCommentCount()
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('commenter_id', new SqlBinding($this->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('commenter_id', new Sql\Binding($this->id)));
|
||||||
return Database::fetchOne($stmt)['count'];
|
return Database::fetchOne($stmt)['count'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPostCount()
|
public function getPostCount()
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('uploader_id', new SqlBinding($this->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('uploader_id', new Sql\Binding($this->id)));
|
||||||
return Database::fetchOne($stmt)['count'];
|
return Database::fetchOne($stmt)['count'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PostModel extends AbstractCrudModel
|
class PostModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
protected static $config;
|
protected static $config;
|
||||||
|
@ -48,49 +51,49 @@ class PostModel extends AbstractCrudModel
|
||||||
'source' => $post->source,
|
'source' => $post->source,
|
||||||
];
|
];
|
||||||
|
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
|
|
||||||
foreach ($bindings as $key => $value)
|
foreach ($bindings as $key => $value)
|
||||||
$stmt->setColumn($key, new SqlBinding($value));
|
$stmt->setColumn($key, new Sql\Binding($value));
|
||||||
|
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($post->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($post->id)));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
//tags
|
//tags
|
||||||
$tags = $post->getTags();
|
$tags = $post->getTags();
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('post_id', new SqlBinding($post->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('post_id', new Sql\Binding($post->id)));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
foreach ($tags as $postTag)
|
foreach ($tags as $postTag)
|
||||||
{
|
{
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
$stmt->setColumn('post_id', new SqlBinding($post->id));
|
$stmt->setColumn('post_id', new Sql\Binding($post->id));
|
||||||
$stmt->setColumn('tag_id', new SqlBinding($postTag->id));
|
$stmt->setColumn('tag_id', new Sql\Binding($postTag->id));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
//relations
|
//relations
|
||||||
$relations = $post->getRelations();
|
$relations = $post->getRelations();
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('crossref');
|
$stmt->setTable('crossref');
|
||||||
$binding = new SqlBinding($post->id);
|
$binding = new Sql\Binding($post->id);
|
||||||
$stmt->setCriterion((new SqlDisjunctionFunctor)
|
$stmt->setCriterion((new Sql\DisjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_id', $binding))
|
->add(new Sql\EqualsFunctor('post_id', $binding))
|
||||||
->add(new SqlEqualsFunctor('post2_id', $binding)));
|
->add(new Sql\EqualsFunctor('post2_id', $binding)));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
foreach ($relations as $relatedPost)
|
foreach ($relations as $relatedPost)
|
||||||
{
|
{
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('crossref');
|
$stmt->setTable('crossref');
|
||||||
$stmt->setColumn('post_id', new SqlBinding($post->id));
|
$stmt->setColumn('post_id', new Sql\Binding($post->id));
|
||||||
$stmt->setColumn('post2_id', new SqlBinding($relatedPost->id));
|
$stmt->setColumn('post2_id', new Sql\Binding($relatedPost->id));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -100,11 +103,11 @@ class PostModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($post)
|
Database::transaction(function() use ($post)
|
||||||
{
|
{
|
||||||
$binding = new SqlBinding($post->id);
|
$binding = new Sql\Binding($post->id);
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_score');
|
$stmt->setTable('post_score');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('post_id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('post_id', $binding));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
|
@ -117,13 +120,13 @@ class PostModel extends AbstractCrudModel
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt->setTable('crossref');
|
$stmt->setTable('crossref');
|
||||||
$stmt->setCriterion((new SqlDisjunctionFunctor)
|
$stmt->setCriterion((new Sql\DisjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_id', $binding))
|
->add(new Sql\EqualsFunctor('post_id', $binding))
|
||||||
->add(new SqlEqualsFunctor('post_id', $binding)));
|
->add(new Sql\EqualsFunctor('post_id', $binding)));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', $binding));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -133,10 +136,10 @@ class PostModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findByName($key, $throw = true)
|
public static function findByName($key, $throw = true)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('name', new SqlBinding($key)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('name', new Sql\Binding($key)));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -158,10 +161,10 @@ class PostModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findByHash($key, $throw = true)
|
public static function findByHash($key, $throw = true)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('file_hash', new SqlBinding($key)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('file_hash', new Sql\Binding($key)));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -189,11 +192,11 @@ class PostModel extends AbstractCrudModel
|
||||||
}
|
}
|
||||||
$postIds = array_unique(array_keys($postMap));
|
$postIds = array_unique(array_keys($postMap));
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->addColumn('comment.*');
|
$stmt->addColumn('comment.*');
|
||||||
$stmt->addColumn('post_id');
|
$stmt->addColumn('post_id');
|
||||||
$stmt->setCriterion(SqlInFunctor::fromArray('post_id', SqlBinding::fromArray($postIds)));
|
$stmt->setCriterion(Sql\InFunctor::fromArray('post_id', Sql\Binding::fromArray($postIds)));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
|
|
||||||
foreach ($rows as $row)
|
foreach ($rows as $row)
|
||||||
|
@ -230,12 +233,12 @@ class PostModel extends AbstractCrudModel
|
||||||
}
|
}
|
||||||
$postIds = array_unique(array_keys($postMap));
|
$postIds = array_unique(array_keys($postMap));
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setTable('tag');
|
$stmt->setTable('tag');
|
||||||
$stmt->addColumn('tag.*');
|
$stmt->addColumn('tag.*');
|
||||||
$stmt->addColumn('post_id');
|
$stmt->addColumn('post_id');
|
||||||
$stmt->addInnerJoin('post_tag', new SqlEqualsFunctor('post_tag.tag_id', 'tag.id'));
|
$stmt->addInnerJoin('post_tag', new Sql\EqualsFunctor('post_tag.tag_id', 'tag.id'));
|
||||||
$stmt->setCriterion(SqlInFunctor::fromArray('post_id', SqlBinding::fromArray($postIds)));
|
$stmt->setCriterion(Sql\InFunctor::fromArray('post_id', Sql\Binding::fromArray($postIds)));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
|
|
||||||
foreach ($rows as $row)
|
foreach ($rows as $row)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PropertyModel implements IModel
|
class PropertyModel implements IModel
|
||||||
{
|
{
|
||||||
const FeaturedPostId = 0;
|
const FeaturedPostId = 0;
|
||||||
|
@ -20,7 +23,7 @@ class PropertyModel implements IModel
|
||||||
{
|
{
|
||||||
self::$loaded = true;
|
self::$loaded = true;
|
||||||
self::$allProperties = [];
|
self::$allProperties = [];
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt ->setColumn('*');
|
$stmt ->setColumn('*');
|
||||||
$stmt ->setTable('property');
|
$stmt ->setTable('property');
|
||||||
foreach (Database::fetchAll($stmt) as $row)
|
foreach (Database::fetchAll($stmt) as $row)
|
||||||
|
@ -41,28 +44,47 @@ class PropertyModel implements IModel
|
||||||
self::loadIfNecessary();
|
self::loadIfNecessary();
|
||||||
Database::transaction(function() use ($propertyId, $value)
|
Database::transaction(function() use ($propertyId, $value)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('id');
|
$stmt->setColumn('id');
|
||||||
$stmt->setTable('property');
|
$stmt->setTable('property');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('prop_id', new SqlBinding($propertyId)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('prop_id', new Sql\Binding($propertyId)));
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
|
|
||||||
if ($row)
|
if ($row)
|
||||||
{
|
{
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('prop_id', new SqlBinding($propertyId)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('prop_id', new Sql\Binding($propertyId)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setColumn('prop_id', new SqlBinding($propertyId));
|
$stmt->setColumn('prop_id', new Sql\Binding($propertyId));
|
||||||
}
|
}
|
||||||
$stmt->setTable('property');
|
$stmt->setTable('property');
|
||||||
$stmt->setColumn('value', new SqlBinding($value));
|
$stmt->setColumn('value', new Sql\Binding($value));
|
||||||
|
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
self::$allProperties[$propertyId] = $value;
|
self::$allProperties[$propertyId] = $value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function featureNewPost()
|
||||||
|
{
|
||||||
|
$stmt = (new Sql\SelectStatement)
|
||||||
|
->setColumn('id')
|
||||||
|
->setTable('post')
|
||||||
|
->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
|
->add(new Sql\EqualsFunctor('type', new Sql\Binding(PostType::Image)))
|
||||||
|
->add(new Sql\EqualsFunctor('safety', new Sql\Binding(PostSafety::Safe))))
|
||||||
|
->setOrderBy(new Sql\RandomFunctor(), Sql\SelectStatement::ORDER_DESC);
|
||||||
|
$featuredPostId = Database::fetchOne($stmt)['id'];
|
||||||
|
if (!$featuredPostId)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
self::set(self::FeaturedPostId, $featuredPostId);
|
||||||
|
self::set(self::FeaturedPostDate, time());
|
||||||
|
self::set(self::FeaturedPostUserName, null);
|
||||||
|
return PostModel::findById($featuredPostId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
|
||||||
abstract class AbstractSearchParser
|
abstract class AbstractSearchParser
|
||||||
{
|
{
|
||||||
protected $statement;
|
protected $statement;
|
||||||
|
|
||||||
public function decorate(SqlSelectStatement $statement, $filterString)
|
public function decorate(Sql\SelectStatement $statement, $filterString)
|
||||||
{
|
{
|
||||||
$this->statement = $statement;
|
$this->statement = $statement;
|
||||||
|
|
||||||
|
@ -65,17 +67,17 @@ abstract class AbstractSearchParser
|
||||||
$orderByString = strtolower(array_shift($arr));
|
$orderByString = strtolower(array_shift($arr));
|
||||||
$orderDirString = strtolower(array_shift($arr));
|
$orderDirString = strtolower(array_shift($arr));
|
||||||
if ($orderDirString == 'asc')
|
if ($orderDirString == 'asc')
|
||||||
$orderDir = SqlSelectStatement::ORDER_ASC;
|
$orderDir = Sql\SelectStatement::ORDER_ASC;
|
||||||
elseif ($orderDirString == 'desc')
|
elseif ($orderDirString == 'desc')
|
||||||
$orderDir = SqlSelectStatement::ORDER_DESC;
|
$orderDir = Sql\SelectStatement::ORDER_DESC;
|
||||||
else
|
else
|
||||||
throw new SimpleException('Invalid search order direction: ' . $searchOrderDir);
|
throw new SimpleException('Invalid search order direction: ' . $searchOrderDir);
|
||||||
|
|
||||||
if ($neg)
|
if ($neg)
|
||||||
{
|
{
|
||||||
$orderDir = $orderDir == SqlSelectStatement::ORDER_ASC
|
$orderDir = $orderDir == Sql\SelectStatement::ORDER_ASC
|
||||||
? SqlSelectStatement::ORDER_DESC
|
? Sql\SelectStatement::ORDER_DESC
|
||||||
: SqlSelectStatement::ORDER_ASC;
|
: Sql\SelectStatement::ORDER_ASC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->processOrderToken($orderByString, $orderDir))
|
if (!$this->processOrderToken($orderByString, $orderDir))
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
|
||||||
class CommentSearchParser extends AbstractSearchParser
|
class CommentSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
protected function processSetup(&$tokens)
|
protected function processSetup(&$tokens)
|
||||||
{
|
{
|
||||||
$this->statement->addInnerJoin('post', new SqlEqualsFunctor('post_id', 'post.id'));
|
$this->statement->addInnerJoin('post', new Sql\EqualsFunctor('post_id', 'post.id'));
|
||||||
|
|
||||||
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
||||||
$this->statement->setCriterion(new SqlConjunctionFunctor());
|
$this->statement->setCriterion(new Sql\ConjunctionFunctor());
|
||||||
$this->statement->getCriterion()->add(SqlInFunctor::fromArray('post.safety', SqlBinding::fromArray($allowedSafety)));
|
$this->statement->getCriterion()->add(Sql\InFunctor::fromArray('post.safety', Sql\Binding::fromArray($allowedSafety)));
|
||||||
if (!PrivilegesHelper::confirm(Privilege::ListPosts, 'hidden'))
|
if (!PrivilegesHelper::confirm(Privilege::ListPosts, 'hidden'))
|
||||||
$this->statement->getCriterion()->add(new SqlNegationFunctor(new SqlStringExpression('hidden')));
|
$this->statement->getCriterion()->add(new Sql\NegationFunctor(new Sql\StringExpression('hidden')));
|
||||||
|
|
||||||
$this->statement->addOrderBy('comment.id', SqlSelectStatement::ORDER_DESC);
|
$this->statement->addOrderBy('comment.id', Sql\SelectStatement::ORDER_DESC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
|
||||||
class PostSearchParser extends AbstractSearchParser
|
class PostSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
private $tags;
|
private $tags;
|
||||||
|
@ -8,10 +10,10 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
$config = \Chibi\Registry::getConfig();
|
$config = \Chibi\Registry::getConfig();
|
||||||
|
|
||||||
$this->tags = [];
|
$this->tags = [];
|
||||||
$this->statement->setCriterion(new SqlConjunctionFunctor());
|
$this->statement->setCriterion(new Sql\ConjunctionFunctor());
|
||||||
|
|
||||||
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
||||||
$this->statement->getCriterion()->add(SqlInFunctor::fromArray('safety', SqlBinding::fromArray($allowedSafety)));
|
$this->statement->getCriterion()->add(Sql\InFunctor::fromArray('safety', Sql\Binding::fromArray($allowedSafety)));
|
||||||
|
|
||||||
if (\Chibi\Registry::getContext()->user->hasEnabledHidingDislikedPosts() and !in_array('special:disliked', array_map('strtolower', $tokens)))
|
if (\Chibi\Registry::getContext()->user->hasEnabledHidingDislikedPosts() and !in_array('special:disliked', array_map('strtolower', $tokens)))
|
||||||
$this->processComplexToken('special', 'disliked', true);
|
$this->processComplexToken('special', 'disliked', true);
|
||||||
|
@ -29,20 +31,20 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
list ($tagName, $neg) = $item;
|
list ($tagName, $neg) = $item;
|
||||||
$tag = TagModel::findByName($tagName);
|
$tag = TagModel::findByName($tagName);
|
||||||
$innerStmt = new SqlSelectStatement();
|
$innerStmt = new Sql\SelectStatement();
|
||||||
$innerStmt->setTable('post_tag');
|
$innerStmt->setTable('post_tag');
|
||||||
$innerStmt->setCriterion((new SqlConjunctionFunctor)
|
$innerStmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_tag.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('post_tag.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('post_tag.tag_id', new SqlBinding($tag->id))));
|
->add(new Sql\EqualsFunctor('post_tag.tag_id', new Sql\Binding($tag->id))));
|
||||||
$operator = new SqlExistsFunctor($innerStmt);
|
$operator = new Sql\ExistsFunctor($innerStmt);
|
||||||
if ($neg)
|
if ($neg)
|
||||||
$operator = new SqlNegationFunctor($operator);
|
$operator = new Sql\NegationFunctor($operator);
|
||||||
$this->statement->getCriterion()->add($operator);
|
$this->statement->getCriterion()->add($operator);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->statement->addOrderBy('post.id',
|
$this->statement->addOrderBy('post.id',
|
||||||
empty($this->statement->getOrderBy())
|
empty($this->statement->getOrderBy())
|
||||||
? SqlSelectStatement::ORDER_DESC
|
? Sql\SelectStatement::ORDER_DESC
|
||||||
: $this->statement->getOrderBy()[0][1]);
|
: $this->statement->getOrderBy()[0][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,85 +60,85 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
$ids = preg_split('/[;,]/', $value);
|
$ids = preg_split('/[;,]/', $value);
|
||||||
$ids = array_map('intval', $ids);
|
$ids = array_map('intval', $ids);
|
||||||
return SqlInFunctor::fromArray('post.id', SqlBinding::fromArray($ids));
|
return Sql\InFunctor::fromArray('post.id', Sql\Binding::fromArray($ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($key, ['fav', 'favs']))
|
elseif (in_array($key, ['fav', 'favs']))
|
||||||
{
|
{
|
||||||
$user = UserModel::findByNameOrEmail($value);
|
$user = UserModel::findByNameOrEmail($value);
|
||||||
$innerStmt = (new SqlSelectStatement)
|
$innerStmt = (new Sql\SelectStatement)
|
||||||
->setTable('favoritee')
|
->setTable('favoritee')
|
||||||
->setCriterion((new SqlConjunctionFunctor)
|
->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('favoritee.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('favoritee.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('favoritee.user_id', new SqlBinding($user->id))));
|
->add(new Sql\EqualsFunctor('favoritee.user_id', new Sql\Binding($user->id))));
|
||||||
return new SqlExistsFunctor($innerStmt);
|
return new Sql\ExistsFunctor($innerStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($key, ['comment', 'commenter']))
|
elseif (in_array($key, ['comment', 'commenter']))
|
||||||
{
|
{
|
||||||
$user = UserModel::findByNameOrEmail($value);
|
$user = UserModel::findByNameOrEmail($value);
|
||||||
$innerStmt = (new SqlSelectStatement)
|
$innerStmt = (new Sql\SelectStatement)
|
||||||
->setTable('comment')
|
->setTable('comment')
|
||||||
->setCriterion((new SqlConjunctionFunctor)
|
->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('comment.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('comment.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('comment.commenter_id', new SqlBinding($user->id))));
|
->add(new Sql\EqualsFunctor('comment.commenter_id', new Sql\Binding($user->id))));
|
||||||
return new SqlExistsFunctor($innerStmt);
|
return new Sql\ExistsFunctor($innerStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($key, ['submit', 'upload', 'uploader', 'uploaded']))
|
elseif (in_array($key, ['submit', 'upload', 'uploader', 'uploaded']))
|
||||||
{
|
{
|
||||||
$user = UserModel::findByNameOrEmail($value);
|
$user = UserModel::findByNameOrEmail($value);
|
||||||
return new SqlEqualsFunctor('uploader_id', new SqlBinding($user->id));
|
return new Sql\EqualsFunctor('uploader_id', new Sql\Binding($user->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($key, ['idmin', 'id_min']))
|
elseif (in_array($key, ['idmin', 'id_min']))
|
||||||
return new SqlEqualsOrGreaterFunctor('post.id', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrGreaterFunctor('post.id', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['idmax', 'id_max']))
|
elseif (in_array($key, ['idmax', 'id_max']))
|
||||||
return new SqlEqualsOrLesserFunctor('post.id', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrLesserFunctor('post.id', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['scoremin', 'score_min']))
|
elseif (in_array($key, ['scoremin', 'score_min']))
|
||||||
return new SqlEqualsOrGreaterFunctor('score', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrGreaterFunctor('score', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['scoremax', 'score_max']))
|
elseif (in_array($key, ['scoremax', 'score_max']))
|
||||||
return new SqlEqualsOrLesserFunctor('score', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrLesserFunctor('score', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['tagmin', 'tag_min']))
|
elseif (in_array($key, ['tagmin', 'tag_min']))
|
||||||
return new SqlEqualsOrGreaterFunctor('tag_count', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrGreaterFunctor('tag_count', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['tagmax', 'tag_max']))
|
elseif (in_array($key, ['tagmax', 'tag_max']))
|
||||||
return new SqlEqualsOrLesserFunctor('tag_count', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrLesserFunctor('tag_count', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['favmin', 'fav_min']))
|
elseif (in_array($key, ['favmin', 'fav_min']))
|
||||||
return new SqlEqualsOrGreaterFunctor('fav_count', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrGreaterFunctor('fav_count', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['favmax', 'fav_max']))
|
elseif (in_array($key, ['favmax', 'fav_max']))
|
||||||
return new SqlEqualsOrLesserFunctor('fav_count', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrLesserFunctor('fav_count', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['commentmin', 'comment_min']))
|
elseif (in_array($key, ['commentmin', 'comment_min']))
|
||||||
return new SqlEqualsOrGreaterFunctor('comment_count', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrGreaterFunctor('comment_count', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['commentmax', 'comment_max']))
|
elseif (in_array($key, ['commentmax', 'comment_max']))
|
||||||
return new SqlEqualsOrLesserFunctor('comment_count', new SqlBinding(intval($value)));
|
return new Sql\EqualsOrLesserFunctor('comment_count', new Sql\Binding(intval($value)));
|
||||||
|
|
||||||
elseif (in_array($key, ['date']))
|
elseif (in_array($key, ['date']))
|
||||||
{
|
{
|
||||||
list ($dateMin, $dateMax) = self::parseDate($value);
|
list ($dateMin, $dateMax) = self::parseDate($value);
|
||||||
return (new SqlConjunctionFunctor)
|
return (new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsOrLesserFunctor('upload_date', new SqlBinding($dateMax)))
|
->add(new Sql\EqualsOrLesserFunctor('upload_date', new Sql\Binding($dateMax)))
|
||||||
->add(new SqlEqualsOrGreaterFunctor('upload_date', new SqlBinding($dateMin)));
|
->add(new Sql\EqualsOrGreaterFunctor('upload_date', new Sql\Binding($dateMin)));
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($key, ['datemin', 'date_min']))
|
elseif (in_array($key, ['datemin', 'date_min']))
|
||||||
{
|
{
|
||||||
list ($dateMin, $dateMax) = self::parseDate($value);
|
list ($dateMin, $dateMax) = self::parseDate($value);
|
||||||
return new SqlEqualsOrGreaterFunctor('upload_date', new SqlBinding($dateMin));
|
return new Sql\EqualsOrGreaterFunctor('upload_date', new Sql\Binding($dateMin));
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($key, ['datemax', 'date_max']))
|
elseif (in_array($key, ['datemax', 'date_max']))
|
||||||
{
|
{
|
||||||
list ($dateMin, $dateMax) = self::parseDate($value);
|
list ($dateMin, $dateMax) = self::parseDate($value);
|
||||||
return new SqlEqualsOrLesserFunctor('upload_date', new SqlBinding($dateMax));
|
return new Sql\EqualsOrLesserFunctor('upload_date', new Sql\Binding($dateMax));
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif ($key == 'special')
|
elseif ($key == 'special')
|
||||||
|
@ -147,26 +149,26 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
if (!$this->statement->isTableJoined('post_score'))
|
if (!$this->statement->isTableJoined('post_score'))
|
||||||
{
|
{
|
||||||
$this->statement->addLeftOuterJoin('post_score', (new SqlConjunctionFunctor)
|
$this->statement->addLeftOuterJoin('post_score', (new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_score.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('post_score.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('post_score.user_id', new SqlBinding($context->user->id))));
|
->add(new Sql\EqualsFunctor('post_score.user_id', new Sql\Binding($context->user->id))));
|
||||||
}
|
}
|
||||||
return new SqlEqualsFunctor(new SqlIfNullFunctor('post_score.score', '0'), '1');
|
return new Sql\EqualsFunctor(new Sql\IfNullFunctor('post_score.score', '0'), '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif (in_array($value, ['disliked', 'dislikes']))
|
elseif (in_array($value, ['disliked', 'dislikes']))
|
||||||
{
|
{
|
||||||
if (!$this->statement->isTableJoined('post_score'))
|
if (!$this->statement->isTableJoined('post_score'))
|
||||||
{
|
{
|
||||||
$this->statement->addLeftOuterJoin('post_score', (new SqlConjunctionFunctor)
|
$this->statement->addLeftOuterJoin('post_score', (new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_score.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('post_score.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('post_score.user_id', new SqlBinding($context->user->id))));
|
->add(new Sql\EqualsFunctor('post_score.user_id', new Sql\Binding($context->user->id))));
|
||||||
}
|
}
|
||||||
return new SqlEqualsFunctor(new SqlIfNullFunctor('post_score.score', '0'), '-1');
|
return new Sql\EqualsFunctor(new Sql\IfNullFunctor('post_score.score', '0'), '-1');
|
||||||
}
|
}
|
||||||
|
|
||||||
elseif ($value == 'hidden')
|
elseif ($value == 'hidden')
|
||||||
return new SqlStringExpression('hidden');
|
return new Sql\StringExpression('hidden');
|
||||||
|
|
||||||
else
|
else
|
||||||
throw new SimpleException('Invalid special token: ' . $value);
|
throw new SimpleException('Invalid special token: ' . $value);
|
||||||
|
@ -184,7 +186,7 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
else
|
else
|
||||||
throw new SimpleException('Invalid post type: ' . $value);
|
throw new SimpleException('Invalid post type: ' . $value);
|
||||||
|
|
||||||
return new SqlEqualsFunctor('type', new SqlBinding($type));
|
return new Sql\EqualsFunctor('type', new Sql\Binding($type));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -197,7 +199,7 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ($neg)
|
if ($neg)
|
||||||
$criterion = new SqlNegationFunctor($criterion);
|
$criterion = new Sql\NegationFunctor($criterion);
|
||||||
|
|
||||||
$this->statement->getCriterion()->add($criterion);
|
$this->statement->getCriterion()->add($criterion);
|
||||||
return true;
|
return true;
|
||||||
|
@ -239,9 +241,9 @@ class PostSearchParser extends AbstractSearchParser
|
||||||
if (!isset($_SESSION['browsing-seed']))
|
if (!isset($_SESSION['browsing-seed']))
|
||||||
$_SESSION['browsing-seed'] = mt_rand();
|
$_SESSION['browsing-seed'] = mt_rand();
|
||||||
$seed = $_SESSION['browsing-seed'];
|
$seed = $_SESSION['browsing-seed'];
|
||||||
$orderColumn = new SqlSubstrFunctor(
|
$orderColumn = new Sql\SubstrFunctor(
|
||||||
new SqlMultiplicationFunctor('post.id', $seed),
|
new Sql\MultiplicationFunctor('post.id', $seed),
|
||||||
new SqlAdditionFunctor(new SqlLengthFunctor('post.id'), '2'));
|
new Sql\AdditionFunctor(new Sql\LengthFunctor('post.id'), '2'));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
|
||||||
class TagSearchParser extends AbstractSearchParser
|
class TagSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
protected function processSetup(&$tokens)
|
protected function processSetup(&$tokens)
|
||||||
{
|
{
|
||||||
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
$allowedSafety = PrivilegesHelper::getAllowedSafety();
|
||||||
$this->statement
|
$this->statement
|
||||||
->addInnerJoin('post_tag', new SqlEqualsFunctor('tag.id', 'post_tag.tag_id'))
|
->addInnerJoin('post_tag', new Sql\EqualsFunctor('tag.id', 'post_tag.tag_id'))
|
||||||
->addInnerJoin('post', new SqlEqualsFunctor('post.id', 'post_tag.post_id'))
|
->addInnerJoin('post', new Sql\EqualsFunctor('post.id', 'post_tag.post_id'))
|
||||||
->setCriterion((new SqlConjunctionFunctor)->add(SqlInFunctor::fromArray('safety', SqlBinding::fromArray($allowedSafety))))
|
->setCriterion((new Sql\ConjunctionFunctor)->add(Sql\InFunctor::fromArray('safety', Sql\Binding::fromArray($allowedSafety))))
|
||||||
->setGroupBy('tag.id');
|
->setGroupBy('tag.id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +22,7 @@ class TagSearchParser extends AbstractSearchParser
|
||||||
$value = '%' . $value;
|
$value = '%' . $value;
|
||||||
$value .= '%';
|
$value .= '%';
|
||||||
|
|
||||||
$this->statement->getCriterion()->add(new SqlNoCaseFunctor(new SqlLikeFunctor('tag.name', new SqlBinding($value))));
|
$this->statement->getCriterion()->add(new Sql\NoCaseFunctor(new Sql\LikeFunctor('tag.name', new Sql\Binding($value))));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
|
||||||
class UserSearchParser extends AbstractSearchParser
|
class UserSearchParser extends AbstractSearchParser
|
||||||
{
|
{
|
||||||
protected function processSimpleToken($value, $neg)
|
protected function processSimpleToken($value, $neg)
|
||||||
|
@ -8,9 +10,9 @@ class UserSearchParser extends AbstractSearchParser
|
||||||
|
|
||||||
if ($value == 'pending')
|
if ($value == 'pending')
|
||||||
{
|
{
|
||||||
$this->statement->setCriterion((new SqlDisjunctionFunctor)
|
$this->statement->setCriterion((new Sql\DisjunctionFunctor)
|
||||||
->add(new SqlIsFunctor('staff_confirmed', new SqlNullFunctor()))
|
->add(new Sql\IsFunctor('staff_confirmed', new Sql\NullFunctor()))
|
||||||
->add(new SqlEqualsFunctor('staff_confirmed', '0')));
|
->add(new Sql\EqualsFunctor('staff_confirmed', '0')));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -19,7 +21,7 @@ class UserSearchParser extends AbstractSearchParser
|
||||||
protected function processOrderToken($orderByString, $orderDir)
|
protected function processOrderToken($orderByString, $orderDir)
|
||||||
{
|
{
|
||||||
if ($orderByString == 'alpha')
|
if ($orderByString == 'alpha')
|
||||||
$this->statement->setOrderBy(new SqlNoCaseFunctor('name'), $orderDir);
|
$this->statement->setOrderBy(new Sql\NoCaseFunctor('name'), $orderDir);
|
||||||
elseif ($orderByString == 'date')
|
elseif ($orderByString == 'date')
|
||||||
$this->statement->setOrderBy('join_date', $orderDir);
|
$this->statement->setOrderBy('join_date', $orderDir);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
abstract class AbstractSearchService
|
abstract class AbstractSearchService
|
||||||
{
|
{
|
||||||
protected static function getModelClassName()
|
protected static function getModelClassName()
|
||||||
|
@ -15,23 +18,23 @@ abstract class AbstractSearchService
|
||||||
return $parserClassName;
|
return $parserClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function decorateParser(SqlSelectStatement $stmt, $searchQuery)
|
protected static function decorateParser(Sql\SelectStatement $stmt, $searchQuery)
|
||||||
{
|
{
|
||||||
$parserClassName = self::getParserClassName();
|
$parserClassName = self::getParserClassName();
|
||||||
(new $parserClassName)->decorate($stmt, $searchQuery);
|
(new $parserClassName)->decorate($stmt, $searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function decorateCustom(SqlSelectStatement $stmt)
|
protected static function decorateCustom(Sql\SelectStatement $stmt)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function decoratePager(SqlSelectStatement $stmt, $perPage, $page)
|
protected static function decoratePager(Sql\SelectStatement $stmt, $perPage, $page)
|
||||||
{
|
{
|
||||||
if ($perPage === null)
|
if ($perPage === null)
|
||||||
return;
|
return;
|
||||||
$stmt->setLimit(
|
$stmt->setLimit(
|
||||||
new SqlBinding($perPage),
|
new Sql\Binding($perPage),
|
||||||
new SqlBinding(($page - 1) * $perPage));
|
new Sql\Binding(($page - 1) * $perPage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getEntitiesRows($searchQuery, $perPage = null, $page = 1)
|
public static function getEntitiesRows($searchQuery, $perPage = null, $page = 1)
|
||||||
|
@ -39,7 +42,7 @@ abstract class AbstractSearchService
|
||||||
$modelClassName = self::getModelClassName();
|
$modelClassName = self::getModelClassName();
|
||||||
$table = $modelClassName::getTableName();
|
$table = $modelClassName::getTableName();
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn($table . '.*');
|
$stmt->setColumn($table . '.*');
|
||||||
$stmt->setTable($table);
|
$stmt->setTable($table);
|
||||||
static::decorateParser($stmt, $searchQuery);
|
static::decorateParser($stmt, $searchQuery);
|
||||||
|
@ -61,14 +64,14 @@ abstract class AbstractSearchService
|
||||||
$modelClassName = self::getModelClassName();
|
$modelClassName = self::getModelClassName();
|
||||||
$table = $modelClassName::getTableName();
|
$table = $modelClassName::getTableName();
|
||||||
|
|
||||||
$innerStmt = new SqlSelectStatement();
|
$innerStmt = new Sql\SelectStatement();
|
||||||
$innerStmt->setTable($table);
|
$innerStmt->setTable($table);
|
||||||
static::decorateParser($innerStmt, $searchQuery);
|
static::decorateParser($innerStmt, $searchQuery);
|
||||||
static::decorateCustom($innerStmt);
|
static::decorateCustom($innerStmt);
|
||||||
$innerStmt->resetOrderBy();
|
$innerStmt->resetOrderBy();
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn(new SqlAliasFunctor(new SqlCountFunctor('1'), 'count'));
|
$stmt->setColumn(new Sql\AliasFunctor(new Sql\CountFunctor('1'), 'count'));
|
||||||
$stmt->setSource($innerStmt);
|
$stmt->setSource($innerStmt);
|
||||||
|
|
||||||
return Database::fetchOne($stmt)['count'];
|
return Database::fetchOne($stmt)['count'];
|
||||||
|
|
|
@ -1,30 +1,33 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class PostSearchService extends AbstractSearchService
|
class PostSearchService extends AbstractSearchService
|
||||||
{
|
{
|
||||||
public static function getPostIdsAround($searchQuery, $postId)
|
public static function getPostIdsAround($searchQuery, $postId)
|
||||||
{
|
{
|
||||||
return Database::transaction(function() use ($searchQuery, $postId)
|
return Database::transaction(function() use ($searchQuery, $postId)
|
||||||
{
|
{
|
||||||
$stmt = new SqlRawStatement('CREATE TEMPORARY TABLE IF NOT EXISTS post_search(id INTEGER PRIMARY KEY, post_id INTEGER)');
|
$stmt = new Sql\RawStatement('CREATE TEMPORARY TABLE IF NOT EXISTS post_search(id INTEGER PRIMARY KEY, post_id INTEGER)');
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_search');
|
$stmt->setTable('post_search');
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$innerStmt = new SqlSelectStatement($searchQuery);
|
$innerStmt = new Sql\SelectStatement($searchQuery);
|
||||||
$innerStmt->setColumn('post.id');
|
$innerStmt->setColumn('post.id');
|
||||||
$innerStmt->setTable('post');
|
$innerStmt->setTable('post');
|
||||||
self::decorateParser($innerStmt, $searchQuery);
|
self::decorateParser($innerStmt, $searchQuery);
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('post_search');
|
$stmt->setTable('post_search');
|
||||||
$stmt->setSource(['post_id'], $innerStmt);
|
$stmt->setSource(['post_id'], $innerStmt);
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setTable('post_search');
|
$stmt->setTable('post_search');
|
||||||
$stmt->setColumn('id');
|
$stmt->setColumn('id');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('post_id', new SqlBinding($postId)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('post_id', new Sql\Binding($postId)));
|
||||||
$rowId = Database::fetchOne($stmt)['id'];
|
$rowId = Database::fetchOne($stmt)['id'];
|
||||||
|
|
||||||
//it's possible that given post won't show in search results:
|
//it's possible that given post won't show in search results:
|
||||||
|
@ -35,10 +38,10 @@ class PostSearchService extends AbstractSearchService
|
||||||
$rowId = intval($rowId);
|
$rowId = intval($rowId);
|
||||||
$stmt->setColumn('post_id');
|
$stmt->setColumn('post_id');
|
||||||
|
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($rowId - 1)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($rowId - 1)));
|
||||||
$nextPostId = Database::fetchOne($stmt)['post_id'];
|
$nextPostId = Database::fetchOne($stmt)['post_id'];
|
||||||
|
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($rowId + 1)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($rowId + 1)));
|
||||||
$prevPostId = Database::fetchOne($stmt)['post_id'];
|
$prevPostId = Database::fetchOne($stmt)['post_id'];
|
||||||
|
|
||||||
return [$prevPostId, $nextPostId];
|
return [$prevPostId, $nextPostId];
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class TagSearchService extends AbstractSearchService
|
class TagSearchService extends AbstractSearchService
|
||||||
{
|
{
|
||||||
public static function decorateCustom(SqlSelectStatement $stmt)
|
public static function decorateCustom(Sql\SelectStatement $stmt)
|
||||||
{
|
{
|
||||||
$stmt->addColumn(new SqlAliasFunctor(new SqlCountFunctor('post_tag.post_id'), 'post_count'));
|
$stmt->addColumn(new Sql\AliasFunctor(new Sql\CountFunctor('post_tag.post_id'), 'post_count'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getMostUsedTag()
|
public static function getMostUsedTag()
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
$stmt->addColumn('tag_id');
|
$stmt->addColumn('tag_id');
|
||||||
$stmt->addColumn(new SqlAliasFunctor(new SqlCountFunctor('post_tag.post_id'), 'post_count'));
|
$stmt->addColumn(new Sql\AliasFunctor(new Sql\CountFunctor('post_tag.post_id'), 'post_count'));
|
||||||
$stmt->setGroupBy('post_tag.tag_id');
|
$stmt->setGroupBy('post_tag.tag_id');
|
||||||
$stmt->setOrderBy('post_count', SqlSelectStatement::ORDER_DESC);
|
$stmt->setOrderBy('post_count', Sql\SelectStatement::ORDER_DESC);
|
||||||
$stmt->setLimit(1, 0);
|
$stmt->setLimit(1, 0);
|
||||||
return Database::fetchOne($stmt);
|
return Database::fetchOne($stmt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class TagModel extends AbstractCrudModel
|
class TagModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
public static function getTableName()
|
public static function getTableName()
|
||||||
|
@ -12,10 +15,10 @@ class TagModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
self::forgeId($tag, 'tag');
|
self::forgeId($tag, 'tag');
|
||||||
|
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setTable('tag');
|
$stmt->setTable('tag');
|
||||||
$stmt->setColumn('name', new SqlBinding($tag->name));
|
$stmt->setColumn('name', new Sql\Binding($tag->name));
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($tag->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($tag->id)));
|
||||||
|
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
|
@ -24,16 +27,16 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function remove($tag)
|
public static function remove($tag)
|
||||||
{
|
{
|
||||||
$binding = new SqlBinding($tag->id);
|
$binding = new Sql\Binding($tag->id);
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('tag_id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('tag_id', $binding));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('tag');
|
$stmt->setTable('tag');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', $binding));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,28 +65,28 @@ class TagModel extends AbstractCrudModel
|
||||||
if ($sourceTag->id == $targetTag->id)
|
if ($sourceTag->id == $targetTag->id)
|
||||||
throw new SimpleException('Source and target tag are the same');
|
throw new SimpleException('Source and target tag are the same');
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('post.id');
|
$stmt->setColumn('post.id');
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$stmt->setCriterion(
|
$stmt->setCriterion(
|
||||||
(new SqlConjunctionFunctor)
|
(new Sql\ConjunctionFunctor)
|
||||||
->add(
|
->add(
|
||||||
new SqlExistsFunctor(
|
new Sql\ExistsFunctor(
|
||||||
(new SqlSelectStatement)
|
(new Sql\SelectStatement)
|
||||||
->setTable('post_tag')
|
->setTable('post_tag')
|
||||||
->setCriterion(
|
->setCriterion(
|
||||||
(new SqlConjunctionFunctor)
|
(new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_tag.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('post_tag.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('post_tag.tag_id', new SqlBinding($sourceTag->id))))))
|
->add(new Sql\EqualsFunctor('post_tag.tag_id', new Sql\Binding($sourceTag->id))))))
|
||||||
->add(
|
->add(
|
||||||
new SqlNegationFunctor(
|
new Sql\NegationFunctor(
|
||||||
new SqlExistsFunctor(
|
new Sql\ExistsFunctor(
|
||||||
(new SqlSelectStatement)
|
(new Sql\SelectStatement)
|
||||||
->setTable('post_tag')
|
->setTable('post_tag')
|
||||||
->setCriterion(
|
->setCriterion(
|
||||||
(new SqlConjunctionFunctor)
|
(new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_tag.post_id', 'post.id'))
|
->add(new Sql\EqualsFunctor('post_tag.post_id', 'post.id'))
|
||||||
->add(new SqlEqualsFunctor('post_tag.tag_id', new SqlBinding($targetTag->id))))))));
|
->add(new Sql\EqualsFunctor('post_tag.tag_id', new Sql\Binding($targetTag->id))))))));
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
$postIds = array_map(function($row) { return $row['id']; }, $rows);
|
$postIds = array_map(function($row) { return $row['id']; }, $rows);
|
||||||
|
|
||||||
|
@ -91,10 +94,10 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
foreach ($postIds as $postId)
|
foreach ($postIds as $postId)
|
||||||
{
|
{
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('post_tag');
|
$stmt->setTable('post_tag');
|
||||||
$stmt->setColumn('post_id', new SqlBinding($postId));
|
$stmt->setColumn('post_id', new Sql\Binding($postId));
|
||||||
$stmt->setColumn('tag_id', new SqlBinding($targetTag->id));
|
$stmt->setColumn('tag_id', new Sql\Binding($targetTag->id));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -103,11 +106,11 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findAllByPostId($key)
|
public static function findAllByPostId($key)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('tag.*');
|
$stmt->setColumn('tag.*');
|
||||||
$stmt->setTable('tag');
|
$stmt->setTable('tag');
|
||||||
$stmt->addInnerJoin('post_tag', new SqlEqualsFunctor('post_tag.tag_id', 'tag.id'));
|
$stmt->addInnerJoin('post_tag', new Sql\EqualsFunctor('post_tag.tag_id', 'tag.id'));
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('post_tag.post_id', new SqlBinding($key)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('post_tag.post_id', new Sql\Binding($key)));
|
||||||
|
|
||||||
$rows = Database::fetchAll($stmt);
|
$rows = Database::fetchAll($stmt);
|
||||||
if ($rows)
|
if ($rows)
|
||||||
|
@ -117,10 +120,10 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findByName($key, $throw = true)
|
public static function findByName($key, $throw = true)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('tag.*');
|
$stmt->setColumn('tag.*');
|
||||||
$stmt->setTable('tag');
|
$stmt->setTable('tag');
|
||||||
$stmt->setCriterion(new SqlNoCaseFunctor(new SqlEqualsFunctor('name', new SqlBinding($key))));
|
$stmt->setCriterion(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('name', new Sql\Binding($key))));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -135,14 +138,14 @@ class TagModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function removeUnused()
|
public static function removeUnused()
|
||||||
{
|
{
|
||||||
$stmt = (new SqlDeleteStatement)
|
$stmt = (new Sql\DeleteStatement)
|
||||||
->setTable('tag')
|
->setTable('tag')
|
||||||
->setCriterion(
|
->setCriterion(
|
||||||
new SqlNegationFunctor(
|
new Sql\NegationFunctor(
|
||||||
new SqlExistsFunctor(
|
new Sql\ExistsFunctor(
|
||||||
(new SqlSelectStatement)
|
(new Sql\SelectStatement)
|
||||||
->setTable('post_tag')
|
->setTable('post_tag')
|
||||||
->setCriterion(new SqlEqualsFunctor('post_tag.tag_id', 'tag.id')))));
|
->setCriterion(new Sql\EqualsFunctor('post_tag.tag_id', 'tag.id')))));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class TokenModel extends AbstractCrudModel
|
class TokenModel extends AbstractCrudModel
|
||||||
implements IModel
|
|
||||||
{
|
{
|
||||||
public static function getTableName()
|
public static function getTableName()
|
||||||
{
|
{
|
||||||
|
@ -20,29 +22,27 @@ implements IModel
|
||||||
'expires' => $token->expires,
|
'expires' => $token->expires,
|
||||||
];
|
];
|
||||||
|
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setTable('user_token');
|
$stmt->setTable('user_token');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($token->id)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($token->id)));
|
||||||
|
|
||||||
foreach ($bindings as $key => $val)
|
foreach ($bindings as $key => $val)
|
||||||
$stmt->setColumn($key, new SqlBinding($val));
|
$stmt->setColumn($key, new Sql\Binding($val));
|
||||||
|
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function findByToken($key, $throw = true)
|
public static function findByToken($key, $throw = true)
|
||||||
{
|
{
|
||||||
if (empty($key))
|
if (empty($key))
|
||||||
throw new SimpleNotFoundException('Invalid security token');
|
throw new SimpleNotFoundException('Invalid security token');
|
||||||
|
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setTable('user_token');
|
$stmt->setTable('user_token');
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('token', new SqlBinding($key)));
|
$stmt->setCriterion(new Sql\EqualsFunctor('token', new Sql\Binding($key)));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -53,8 +53,6 @@ implements IModel
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function checkValidity($token)
|
public static function checkValidity($token)
|
||||||
{
|
{
|
||||||
if (empty($token))
|
if (empty($token))
|
||||||
|
@ -67,8 +65,6 @@ implements IModel
|
||||||
throw new SimpleException('This token has expired');
|
throw new SimpleException('This token has expired');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function forgeUnusedToken()
|
public static function forgeUnusedToken()
|
||||||
{
|
{
|
||||||
$tokenText = '';
|
$tokenText = '';
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
use \Chibi\Sql as Sql;
|
||||||
|
use \Chibi\Database as Database;
|
||||||
|
|
||||||
class UserModel extends AbstractCrudModel
|
class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
const SETTING_SAFETY = 1;
|
const SETTING_SAFETY = 1;
|
||||||
|
@ -40,12 +43,12 @@ class UserModel extends AbstractCrudModel
|
||||||
'banned' => $user->banned
|
'banned' => $user->banned
|
||||||
];
|
];
|
||||||
|
|
||||||
$stmt = (new SqlUpdateStatement)
|
$stmt = (new Sql\UpdateStatement)
|
||||||
->setTable('user')
|
->setTable('user')
|
||||||
->setCriterion(new SqlEqualsFunctor('id', new SqlBinding($user->id)));
|
->setCriterion(new Sql\EqualsFunctor('id', new Sql\Binding($user->id)));
|
||||||
|
|
||||||
foreach ($bindings as $key => $val)
|
foreach ($bindings as $key => $val)
|
||||||
$stmt->setColumn($key, new SqlBinding($val));
|
$stmt->setColumn($key, new Sql\Binding($val));
|
||||||
|
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
|
@ -55,30 +58,30 @@ class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($user)
|
Database::transaction(function() use ($user)
|
||||||
{
|
{
|
||||||
$binding = new SqlBinding($user->id);
|
$binding = new Sql\Binding($user->id);
|
||||||
|
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_score');
|
$stmt->setTable('post_score');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('user_id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('user_id', $binding));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt->setTable('user');
|
$stmt->setTable('user');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('id', $binding));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setTable('comment');
|
$stmt->setTable('comment');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('commenter_id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('commenter_id', $binding));
|
||||||
$stmt->setColumn('commenter_id', new SqlNullFunctor());
|
$stmt->setColumn('commenter_id', new Sql\NullFunctor());
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
|
|
||||||
$stmt = new SqlUpdateStatement();
|
$stmt = new Sql\UpdateStatement();
|
||||||
$stmt->setTable('post');
|
$stmt->setTable('post');
|
||||||
$stmt->setCriterion(new SqlEqualsFunctor('uploader_id', $binding));
|
$stmt->setCriterion(new Sql\EqualsFunctor('uploader_id', $binding));
|
||||||
$stmt->setColumn('uploader_id', new SqlNullFunctor());
|
$stmt->setColumn('uploader_id', new Sql\NullFunctor());
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -87,10 +90,10 @@ class UserModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findByName($key, $throw = true)
|
public static function findByName($key, $throw = true)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setTable('user');
|
$stmt->setTable('user');
|
||||||
$stmt->setCriterion(new SqlNoCaseFunctor(new SqlEqualsFunctor('name', new SqlBinding(trim($key)))));
|
$stmt->setCriterion(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('name', new Sql\Binding(trim($key)))));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -103,12 +106,12 @@ class UserModel extends AbstractCrudModel
|
||||||
|
|
||||||
public static function findByNameOrEmail($key, $throw = true)
|
public static function findByNameOrEmail($key, $throw = true)
|
||||||
{
|
{
|
||||||
$stmt = new SqlSelectStatement();
|
$stmt = new Sql\SelectStatement();
|
||||||
$stmt->setColumn('*');
|
$stmt->setColumn('*');
|
||||||
$stmt->setTable('user');
|
$stmt->setTable('user');
|
||||||
$stmt->setCriterion((new SqlDisjunctionFunctor)
|
$stmt->setCriterion((new Sql\DisjunctionFunctor)
|
||||||
->add(new SqlNoCaseFunctor(new SqlEqualsFunctor('name', new SqlBinding(trim($key)))))
|
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('name', new Sql\Binding(trim($key)))))
|
||||||
->add(new SqlNoCaseFunctor(new SqlEqualsFunctor('email_confirmed', new SqlBinding(trim($key))))));
|
->add(new Sql\NoCaseFunctor(new Sql\EqualsFunctor('email_confirmed', new Sql\Binding(trim($key))))));
|
||||||
|
|
||||||
$row = Database::fetchOne($stmt);
|
$row = Database::fetchOne($stmt);
|
||||||
if ($row)
|
if ($row)
|
||||||
|
@ -125,20 +128,20 @@ class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($user, $post, $score)
|
Database::transaction(function() use ($user, $post, $score)
|
||||||
{
|
{
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('post_score');
|
$stmt->setTable('post_score');
|
||||||
$stmt->setCriterion((new SqlConjunctionFunctor)
|
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_id', new SqlBinding($post->id)))
|
->add(new Sql\EqualsFunctor('post_id', new Sql\Binding($post->id)))
|
||||||
->add(new SqlEqualsFunctor('user_id', new SqlBinding($user->id))));
|
->add(new Sql\EqualsFunctor('user_id', new Sql\Binding($user->id))));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
$score = intval($score);
|
$score = intval($score);
|
||||||
if ($score != 0)
|
if ($score != 0)
|
||||||
{
|
{
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('post_score');
|
$stmt->setTable('post_score');
|
||||||
$stmt->setColumn('post_id', new SqlBinding($post->id));
|
$stmt->setColumn('post_id', new Sql\Binding($post->id));
|
||||||
$stmt->setColumn('user_id', new SqlBinding($user->id));
|
$stmt->setColumn('user_id', new Sql\Binding($user->id));
|
||||||
$stmt->setColumn('score', new SqlBinding($score));
|
$stmt->setColumn('score', new Sql\Binding($score));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -149,10 +152,10 @@ class UserModel extends AbstractCrudModel
|
||||||
Database::transaction(function() use ($user, $post)
|
Database::transaction(function() use ($user, $post)
|
||||||
{
|
{
|
||||||
self::removeFromUserFavorites($user, $post);
|
self::removeFromUserFavorites($user, $post);
|
||||||
$stmt = new SqlInsertStatement();
|
$stmt = new Sql\InsertStatement();
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
$stmt->setColumn('post_id', new SqlBinding($post->id));
|
$stmt->setColumn('post_id', new Sql\Binding($post->id));
|
||||||
$stmt->setColumn('user_id', new SqlBinding($user->id));
|
$stmt->setColumn('user_id', new Sql\Binding($user->id));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -161,11 +164,11 @@ class UserModel extends AbstractCrudModel
|
||||||
{
|
{
|
||||||
Database::transaction(function() use ($user, $post)
|
Database::transaction(function() use ($user, $post)
|
||||||
{
|
{
|
||||||
$stmt = new SqlDeleteStatement();
|
$stmt = new Sql\DeleteStatement();
|
||||||
$stmt->setTable('favoritee');
|
$stmt->setTable('favoritee');
|
||||||
$stmt->setCriterion((new SqlConjunctionFunctor)
|
$stmt->setCriterion((new Sql\ConjunctionFunctor)
|
||||||
->add(new SqlEqualsFunctor('post_id', new SqlBinding($post->id)))
|
->add(new Sql\EqualsFunctor('post_id', new Sql\Binding($post->id)))
|
||||||
->add(new SqlEqualsFunctor('user_id', new SqlBinding($user->id))));
|
->add(new Sql\EqualsFunctor('user_id', new Sql\Binding($user->id))));
|
||||||
Database::exec($stmt);
|
Database::exec($stmt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlAdditionFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '+';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlAliasFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return 'AS';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return self::surroundBraces($this->subjects[0])
|
|
||||||
. ' ' . $this->getOperator()
|
|
||||||
. ' ' . $this->subjects[1]->getAsString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlAdditionFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '/';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlEqualsFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '=';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlEqualsOrGreaterFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '>=';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlEqualsOrLesserFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '<=';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlGreaterFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '>';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlIsFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return 'IS';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlLesserFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '<';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlLikeFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return 'LIKE';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlMultiplicationFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '*';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlSubtractionFunctor extends SqlBinaryOperatorFunctor
|
|
||||||
{
|
|
||||||
protected function getOperator()
|
|
||||||
{
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlAbsFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'ABS';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlCountFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'COUNT';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlExistsFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'EXISTS';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return $this->getFunctionName() . ' (' . $this->subjects[0]->getAsString() . ')';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlIfNullFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'IFNULL';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlLengthFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'LENGTH';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlMaxFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'MAX';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlNegationFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'NOT';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlNoCaseFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
throw new Exception('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return $this->subjects[0]->getAsString() . ' COLLATE NOCASE';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlRandomFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
$config = \Chibi\Registry::getConfig();
|
|
||||||
return $config->main->dbDriver == 'sqlite'
|
|
||||||
? 'RANDOM'
|
|
||||||
: 'RAND';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlSubstrFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
return 'SUBSTR';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return [2, 3];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlConjunctionFunctor extends SqlVariableFunctor
|
|
||||||
{
|
|
||||||
public function getAsStringEmpty()
|
|
||||||
{
|
|
||||||
return '1';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsStringNonEmpty()
|
|
||||||
{
|
|
||||||
return '(' . join(' AND ', array_map(function($subject)
|
|
||||||
{
|
|
||||||
return self::surroundBraces($subject);
|
|
||||||
}, $this->subjects)) . ')';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlDisjunctionFunctor extends SqlVariableFunctor
|
|
||||||
{
|
|
||||||
public function getAsStringEmpty()
|
|
||||||
{
|
|
||||||
return '1';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsStringNonEmpty()
|
|
||||||
{
|
|
||||||
return '(' . join(' OR ', array_map(function($subject)
|
|
||||||
{
|
|
||||||
return self::surroundBraces($subject);
|
|
||||||
}, $this->subjects)) . ')';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlInFunctor extends SqlVariableFunctor
|
|
||||||
{
|
|
||||||
protected $subject;
|
|
||||||
|
|
||||||
public function __construct($subject)
|
|
||||||
{
|
|
||||||
$this->subject = $this->attachExpression($subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsStringEmpty()
|
|
||||||
{
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsStringNonEmpty()
|
|
||||||
{
|
|
||||||
return self::surroundBraces($this->subject) . ' IN (' . join(', ', array_map(function($subject)
|
|
||||||
{
|
|
||||||
return self::surroundBraces($subject);
|
|
||||||
}, $this->subjects)) . ')';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlNullFunctor extends SqlFunctor
|
|
||||||
{
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return 'NULL';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
abstract class SqlBinaryOperatorFunctor extends SqlFunctionFunctor
|
|
||||||
{
|
|
||||||
public function getFunctionName()
|
|
||||||
{
|
|
||||||
throw new Exception('Not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getArgumentCount()
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return self::surroundBraces($this->subjects[0])
|
|
||||||
. ' ' . $this->getOperator()
|
|
||||||
. ' ' . self::surroundBraces($this->subjects[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract function getOperator();
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
abstract class SqlFunctionFunctor extends SqlFunctor
|
|
||||||
{
|
|
||||||
protected $subjects;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$subjects = func_get_args();
|
|
||||||
$expectedArgumentCount = (array) $this->getArgumentCount();
|
|
||||||
if (!in_array(count($subjects), $expectedArgumentCount))
|
|
||||||
throw new Exception('Unepxected argument count for ' . get_called_class());
|
|
||||||
|
|
||||||
foreach ($subjects as $subject)
|
|
||||||
$this->subjects []= $this->attachExpression($subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract function getFunctionName();
|
|
||||||
protected abstract function getArgumentCount();
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return $this->getFunctionName()
|
|
||||||
. ' ('
|
|
||||||
. join(', ', array_map(function($subject)
|
|
||||||
{
|
|
||||||
return self::surroundBraces($subject);
|
|
||||||
}, $this->subjects))
|
|
||||||
. ')';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?php
|
|
||||||
abstract class SqlFunctor extends SqlExpression
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?php
|
|
||||||
abstract class SqlVariableFunctor extends SqlFunctor
|
|
||||||
{
|
|
||||||
protected $subjects;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->subjects = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function add($subject)
|
|
||||||
{
|
|
||||||
$this->subjects []= $this->attachExpression($subject);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract function getAsStringNonEmpty();
|
|
||||||
public abstract function getAsStringEmpty();
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
if (empty(array_filter($this->subjects, function($x) { return !empty($x->getAsString()); })))
|
|
||||||
return $this->getAsStringEmpty();
|
|
||||||
|
|
||||||
return $this->getAsStringNonEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
//variable arguments
|
|
||||||
public static function fromArray()
|
|
||||||
{
|
|
||||||
$args = func_get_args();
|
|
||||||
$subjects = array_pop($args);
|
|
||||||
$instance = (new ReflectionClass(get_called_class()))->newInstanceArgs($args);
|
|
||||||
foreach ($subjects as $subject)
|
|
||||||
$instance->add($subject);
|
|
||||||
return $instance;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlBinding
|
|
||||||
{
|
|
||||||
protected $content;
|
|
||||||
protected $name;
|
|
||||||
private static $bindingCount = 0;
|
|
||||||
|
|
||||||
public function __construct($content)
|
|
||||||
{
|
|
||||||
$this->content = $content;
|
|
||||||
$this->name = ':p' . (self::$bindingCount ++);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getValue()
|
|
||||||
{
|
|
||||||
return $this->content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromArray(array $contents)
|
|
||||||
{
|
|
||||||
return array_map(function($content)
|
|
||||||
{
|
|
||||||
return new SqlBinding($content);
|
|
||||||
}, $contents);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
<?php
|
|
||||||
abstract class SqlExpression
|
|
||||||
{
|
|
||||||
abstract public function getAsString();
|
|
||||||
|
|
||||||
protected $bindings = [];
|
|
||||||
protected $subExpressions = [];
|
|
||||||
|
|
||||||
private function bind($key, $val)
|
|
||||||
{
|
|
||||||
$this->bindings[$key] = $val;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function surroundBraces(SqlExpression $object)
|
|
||||||
{
|
|
||||||
if ($object instanceof SqlStatement)
|
|
||||||
return '(' . $object->getAsString() . ')';
|
|
||||||
return $object->getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBindings()
|
|
||||||
{
|
|
||||||
$bindings = $this->bindings;
|
|
||||||
foreach ($this->subExpressions as $subExpression)
|
|
||||||
$bindings = array_merge($bindings, $subExpression->getBindings());
|
|
||||||
return $bindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attachExpression($object)
|
|
||||||
{
|
|
||||||
if ($object instanceof SqlBinding)
|
|
||||||
{
|
|
||||||
$expr = new SqlStringExpression($object->getName());
|
|
||||||
$expr->bind($object->getName(), $object->getValue());
|
|
||||||
$this->subExpressions []= $expr;
|
|
||||||
return $expr;
|
|
||||||
}
|
|
||||||
else if ($object instanceof SqlExpression)
|
|
||||||
{
|
|
||||||
$this->subExpressions []= $object;
|
|
||||||
return $object;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new SqlStringExpression((string) $object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlStringExpression extends SqlExpression
|
|
||||||
{
|
|
||||||
protected $text;
|
|
||||||
|
|
||||||
public function __construct($text)
|
|
||||||
{
|
|
||||||
$this->text = $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return $this->text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlDeleteStatement extends SqlStatement
|
|
||||||
{
|
|
||||||
protected $table;
|
|
||||||
protected $criterion;
|
|
||||||
|
|
||||||
public function getTable()
|
|
||||||
{
|
|
||||||
return $this->table;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTable($table)
|
|
||||||
{
|
|
||||||
$this->table = new SqlStringExpression($table);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCriterion()
|
|
||||||
{
|
|
||||||
return $this->criterion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCriterion($criterion)
|
|
||||||
{
|
|
||||||
$this->criterion = $this->attachExpression($criterion);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
$sql = 'DELETE FROM ' . $this->table->getAsString() . ' ';
|
|
||||||
|
|
||||||
if (!empty($this->criterion) and !empty($this->criterion->getAsString()))
|
|
||||||
$sql .= ' WHERE ' . $this->criterion->getAsString();
|
|
||||||
|
|
||||||
return $sql;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlInsertStatement extends SqlStatement
|
|
||||||
{
|
|
||||||
protected $table;
|
|
||||||
protected $columns;
|
|
||||||
protected $source;
|
|
||||||
|
|
||||||
public function getTable()
|
|
||||||
{
|
|
||||||
return $this->table;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTable($table)
|
|
||||||
{
|
|
||||||
$this->table = new SqlStringExpression($table);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setColumn($column, $what)
|
|
||||||
{
|
|
||||||
$this->columns[$column] = $this->attachExpression($what);
|
|
||||||
$this->source = null;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSource($columns, $what)
|
|
||||||
{
|
|
||||||
$this->source = $this->attachExpression($what);
|
|
||||||
$this->columns = $columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
$sql = 'INSERT INTO ' . $this->table->getAsString() . ' ';
|
|
||||||
if (!empty($this->source))
|
|
||||||
{
|
|
||||||
$sql .= ' (' . join(', ', $this->columns) . ')';
|
|
||||||
$sql .= ' ' . $this->source->getAsString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (empty($this->columns))
|
|
||||||
{
|
|
||||||
$config = \Chibi\Registry::getConfig();
|
|
||||||
if ($config->main->dbDriver == 'sqlite')
|
|
||||||
$sql .= ' DEFAULT VALUES';
|
|
||||||
else
|
|
||||||
$sql .= ' VALUES()';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$sql .= ' (' . join(', ', array_keys($this->columns)) . ')';
|
|
||||||
|
|
||||||
$sql .= ' VALUES (' . join(', ', array_map(function($val)
|
|
||||||
{
|
|
||||||
return '(' . $val->getAsString() . ')';
|
|
||||||
}, array_values($this->columns))) . ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $sql;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlRawStatement extends SqlStatement
|
|
||||||
{
|
|
||||||
protected $text;
|
|
||||||
|
|
||||||
public function __construct($text)
|
|
||||||
{
|
|
||||||
$this->text = $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
return $this->text;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,213 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlSelectStatement extends SqlStatement
|
|
||||||
{
|
|
||||||
const ORDER_ASC = 1;
|
|
||||||
const ORDER_DESC = 2;
|
|
||||||
|
|
||||||
protected $columns = null;
|
|
||||||
protected $source = null;
|
|
||||||
protected $innerJoins = [];
|
|
||||||
protected $leftOuterJoins = [];
|
|
||||||
protected $criterion = null;
|
|
||||||
protected $orderBy = [];
|
|
||||||
protected $limit = null;
|
|
||||||
protected $offset = null;
|
|
||||||
protected $groupBy = null;
|
|
||||||
|
|
||||||
public function getColumns()
|
|
||||||
{
|
|
||||||
return $this->columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetColumns()
|
|
||||||
{
|
|
||||||
$this->columns = [];
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setColumn($what)
|
|
||||||
{
|
|
||||||
$this->setColumns([$what]);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addColumn($what)
|
|
||||||
{
|
|
||||||
$this->columns []= $this->attachExpression($what);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setColumns($what)
|
|
||||||
{
|
|
||||||
$this->resetColumns();
|
|
||||||
foreach ($what as $item)
|
|
||||||
$this->addColumn($item);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTable()
|
|
||||||
{
|
|
||||||
return $this->source;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTable($table)
|
|
||||||
{
|
|
||||||
$this->source = new SqlStringExpression($table);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSource(SqlExpression $source)
|
|
||||||
{
|
|
||||||
$this->source = $this->attachExpression($source);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addInnerJoin($table, SqlExpression $expression)
|
|
||||||
{
|
|
||||||
$this->innerJoins []= [$table, $this->attachExpression($expression)];
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addLeftOuterJoin($table, $expression)
|
|
||||||
{
|
|
||||||
$this->leftOuterJoins []= [$table, $this->attachExpression($expression)];
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getJoinedTables()
|
|
||||||
{
|
|
||||||
$tables = [];
|
|
||||||
foreach (array_merge($this->innerJoins, $this->leftOuterJoins) as $join)
|
|
||||||
{
|
|
||||||
list ($table, $joinExpression) = $join;
|
|
||||||
$tables []= $table;
|
|
||||||
}
|
|
||||||
return array_unique($tables);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isTableJoined($table)
|
|
||||||
{
|
|
||||||
return in_array($table, $this->getJoinedTables());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCriterion()
|
|
||||||
{
|
|
||||||
return $this->criterion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCriterion($criterion)
|
|
||||||
{
|
|
||||||
$this->criterion = $this->attachExpression($criterion);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetOrderBy()
|
|
||||||
{
|
|
||||||
$this->orderBy = [];
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setOrderBy($what, $dir = self::ORDER_ASC)
|
|
||||||
{
|
|
||||||
$this->resetOrderBy();
|
|
||||||
$this->addOrderBy($this->attachExpression($what), $dir);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addOrderBy($what, $dir = self::ORDER_ASC)
|
|
||||||
{
|
|
||||||
$this->orderBy []= [$this->attachExpression($what), $dir];
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOrderBy()
|
|
||||||
{
|
|
||||||
return $this->orderBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetLimit()
|
|
||||||
{
|
|
||||||
$this->limit = null;
|
|
||||||
$this->offset = null;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setLimit($limit, $offset = null)
|
|
||||||
{
|
|
||||||
$this->limit = $this->attachExpression($limit);
|
|
||||||
$this->offset = $this->attachExpression($offset);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setGroupBy($groupBy)
|
|
||||||
{
|
|
||||||
$this->groupBy = $this->attachExpression($groupBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
$sql = 'SELECT ';
|
|
||||||
if (!empty($this->columns))
|
|
||||||
$sql .= join(', ', array_map(function($column)
|
|
||||||
{
|
|
||||||
return $column->getAsString();
|
|
||||||
}, $this->columns));
|
|
||||||
else
|
|
||||||
$sql .= '1';
|
|
||||||
$sql .= ' FROM ' . self::surroundBraces($this->source);
|
|
||||||
|
|
||||||
foreach ($this->innerJoins as $join)
|
|
||||||
{
|
|
||||||
list ($table, $criterion) = $join;
|
|
||||||
$sql .= ' INNER JOIN ' . $table . ' ON ' . $criterion->getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->leftOuterJoins as $outerJoin)
|
|
||||||
{
|
|
||||||
list ($table, $criterion) = $outerJoin;
|
|
||||||
$sql .= ' LEFT OUTER JOIN ' . $table . ' ON ' . $criterion->getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->criterion) and !empty($this->criterion->getAsString()))
|
|
||||||
$sql .= ' WHERE ' . $this->criterion->getAsString();
|
|
||||||
|
|
||||||
if (!empty($this->groupBy) and !empty($this->groupBy->getAsString()))
|
|
||||||
{
|
|
||||||
$sql .= ' GROUP BY ' . $this->groupBy->getAsString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->orderBy))
|
|
||||||
{
|
|
||||||
$f = true;
|
|
||||||
foreach ($this->orderBy as $orderBy)
|
|
||||||
{
|
|
||||||
$sql .= $f ? ' ORDER BY' : ', ';
|
|
||||||
$f = false;
|
|
||||||
list ($orderColumn, $orderDir) = $orderBy;
|
|
||||||
$sql .= ' ' . $orderColumn->getAsString();
|
|
||||||
switch ($orderDir)
|
|
||||||
{
|
|
||||||
case self::ORDER_DESC:
|
|
||||||
$sql .= ' DESC';
|
|
||||||
break;
|
|
||||||
case self::ORDER_ASC:
|
|
||||||
$sql .= ' ASC';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->limit) and !empty($this->limit->getAsString()))
|
|
||||||
{
|
|
||||||
$sql .= ' LIMIT ';
|
|
||||||
$sql .= $this->limit->getAsString();
|
|
||||||
if (!empty($this->offset))
|
|
||||||
{
|
|
||||||
$sql .= ' OFFSET ';
|
|
||||||
$sql .= $this->offset->getAsString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sql;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?php
|
|
||||||
abstract class SqlStatement extends SqlExpression
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
<?php
|
|
||||||
class SqlUpdateStatement extends SqlStatement
|
|
||||||
{
|
|
||||||
protected $table;
|
|
||||||
protected $criterion;
|
|
||||||
protected $columns;
|
|
||||||
|
|
||||||
public function getTable()
|
|
||||||
{
|
|
||||||
return $this->table;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTable($table)
|
|
||||||
{
|
|
||||||
$this->table = new SqlStringExpression($table);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCriterion()
|
|
||||||
{
|
|
||||||
return $this->criterion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCriterion($criterion)
|
|
||||||
{
|
|
||||||
$this->criterion = $this->attachExpression($criterion);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setColumn($column, $what)
|
|
||||||
{
|
|
||||||
$this->columns[$column] = $this->attachExpression($what);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAsString()
|
|
||||||
{
|
|
||||||
$sql = 'UPDATE ' . $this->table->getAsString();
|
|
||||||
|
|
||||||
if (!empty($this->columns))
|
|
||||||
{
|
|
||||||
$sql .= ' SET ' . join(', ', array_map(function($key)
|
|
||||||
{
|
|
||||||
return $key . ' = (' . $this->columns[$key]->getAsString() . ')';
|
|
||||||
}, array_keys($this->columns)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->criterion) and !empty($this->criterion->getAsString()))
|
|
||||||
$sql .= ' WHERE ' . $this->criterion->getAsString();
|
|
||||||
|
|
||||||
return $sql;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php CustomAssetViewDecorator::addStylesheet('debug.css') ?>
|
<?php CustomAssetViewDecorator::addStylesheet('debug.css') ?>
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<?php foreach (Database::getLogs() as $log): ?>
|
<?php foreach (\Chibi\Database::getLogs() as $log): ?>
|
||||||
<div class="debug">
|
<div class="debug">
|
||||||
<?php
|
<?php
|
||||||
$query = $log->statement->getAsString();
|
$query = $log->getStatement()->getAsString();
|
||||||
$query = str_replace('(', '<span>(', $query);
|
$query = str_replace('(', '<span>(', $query);
|
||||||
$query = str_replace(')', ')</span>', $query);
|
$query = str_replace(')', ')</span>', $query);
|
||||||
?>
|
?>
|
||||||
|
@ -11,13 +11,13 @@
|
||||||
|
|
||||||
<pre class="bindings"><?php echo join(', ', array_map(function($key) use ($log)
|
<pre class="bindings"><?php echo join(', ', array_map(function($key) use ($log)
|
||||||
{
|
{
|
||||||
return $key . '=<span class="value">' . $log->statement->getBindings()[$key] . '</span>';
|
return $key . '=<span class="value">' . $log->getStatement()->getBindings()[$key] . '</span>';
|
||||||
},
|
},
|
||||||
array_keys($log->statement->getBindings()))) ?></pre>
|
array_keys($log->getStatement()->getBindings()))) ?></pre>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr><td>Execution:</td><td><?php echo sprintf('%.05fs', $log->timeExec) ?></td></tr>
|
<tr><td>Execution:</td><td><?php echo sprintf('%.05fs', $log->getExecutionTime()) ?></td></tr>
|
||||||
<tr><td>Retrieval:</td><td><?php echo sprintf('%.05fs', $log->timeFetch) ?></td></tr>
|
<tr><td>Retrieval:</td><td><?php echo sprintf('%.05fs', $log->getRetrievalTime()) ?></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
|
|
@ -37,7 +37,7 @@ CustomAssetViewDecorator::addScript('core.js');
|
||||||
<div class="main-wrapper">
|
<div class="main-wrapper">
|
||||||
<hr>
|
<hr>
|
||||||
<span>Load: <?php echo sprintf('%.05f', microtime(true) - $this->context->startTime) ?>s</span>
|
<span>Load: <?php echo sprintf('%.05f', microtime(true) - $this->context->startTime) ?>s</span>
|
||||||
<span>Queries: <?php echo count(Database::getLogs()) ?></span>
|
<span>Queries: <?php echo count(\Chibi\Database::getLogs()) ?></span>
|
||||||
<span><a href="<?php echo SZURU_LINK ?>">szurubooru v<?php echo SZURU_VERSION ?></a></span>
|
<span><a href="<?php echo SZURU_LINK ?>">szurubooru v<?php echo SZURU_VERSION ?></a></span>
|
||||||
<?php if (PrivilegesHelper::confirm(Privilege::ListLogs)): ?>
|
<?php if (PrivilegesHelper::confirm(Privilege::ListLogs)): ?>
|
||||||
<span><a href="<?php echo \Chibi\UrlHelper::route('log', 'list') ?>">Logs</a></span>
|
<span><a href="<?php echo \Chibi\UrlHelper::route('log', 'list') ?>">Logs</a></span>
|
||||||
|
|
|
@ -13,7 +13,7 @@ ini_set('memory_limit', '128M');
|
||||||
//basic include calls, autoloader init
|
//basic include calls, autoloader init
|
||||||
require_once $rootDir . 'lib' . DS . 'php-markdown' . DS . 'Michelf' . DS . 'Markdown.php';
|
require_once $rootDir . 'lib' . DS . 'php-markdown' . DS . 'Michelf' . DS . 'Markdown.php';
|
||||||
require_once $rootDir . 'lib' . DS . 'chibi-core' . DS . 'Facade.php';
|
require_once $rootDir . 'lib' . DS . 'chibi-core' . DS . 'Facade.php';
|
||||||
\Chibi\AutoLoader::init(__DIR__);
|
\Chibi\AutoLoader::init([__DIR__, $rootDir . 'lib' . DS . 'chibi-sql']);
|
||||||
|
|
||||||
//load config manually
|
//load config manually
|
||||||
$configPaths =
|
$configPaths =
|
||||||
|
@ -39,7 +39,11 @@ $context = \Chibi\Registry::getContext();
|
||||||
$context->startTime = $startTime;
|
$context->startTime = $startTime;
|
||||||
$context->rootDir = $rootDir;
|
$context->rootDir = $rootDir;
|
||||||
|
|
||||||
Database::connect($config->main->dbDriver, TextHelper::absolutePath($config->main->dbLocation), $config->main->dbUser, $config->main->dbPass);
|
\Chibi\Database::connect(
|
||||||
|
$config->main->dbDriver,
|
||||||
|
TextHelper::absolutePath($config->main->dbLocation),
|
||||||
|
$config->main->dbUser,
|
||||||
|
$config->main->dbPass);
|
||||||
|
|
||||||
//wire models
|
//wire models
|
||||||
foreach (\Chibi\AutoLoader::getAllIncludablePaths() as $path)
|
foreach (\Chibi\AutoLoader::getAllIncludablePaths() as $path)
|
||||||
|
|
|
@ -57,7 +57,7 @@ foreach ($upgrades as $upgradePath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Database::exec(new SqlRawStatement($query));
|
\Chibi\Database::exec(new \Chibi\Sql\RawStatement($query));
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue