mirror of
https://github.com/lkddi/nexusphp.git
synced 2026-04-27 14:17:23 +08:00
announce support pg
This commit is contained in:
+12
-3
@@ -202,11 +202,20 @@ class Torrent extends NexusModel
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 重写获取 info_hash 的方法,确保从数据库读出时是正确的格式
|
* 重写获取 info_hash 的方法,确保从数据库读出时是正确的格式
|
||||||
|
* 注意:不要使用 getInfoHashAttribute(),不带缓存,第1次有值,第2次指针到头,数据是空!!!
|
||||||
*/
|
*/
|
||||||
public function getInfoHashAttribute($value): false|string
|
public function infoHash(): Attribute
|
||||||
{
|
{
|
||||||
// PostgreSQL 返回 bytea 时可能是十六进制流或资源
|
return Attribute::make(
|
||||||
return is_resource($value) ? stream_get_contents($value) : $value;
|
get: function ($value) {
|
||||||
|
// PostgreSQL 返回 bytea 时可能是十六进制流或资源
|
||||||
|
if (is_resource($value)) {
|
||||||
|
rewind($value);
|
||||||
|
return stream_get_contents($value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
)->shouldCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPickInfoAttribute()
|
public function getPickInfoAttribute()
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class CreatePeersTable extends Migration
|
|||||||
Schema::create('peers', function (Blueprint $table) {
|
Schema::create('peers', function (Blueprint $table) {
|
||||||
$table->bigIncrements('id');
|
$table->bigIncrements('id');
|
||||||
$table->unsignedMediumInteger('torrent')->default(0);
|
$table->unsignedMediumInteger('torrent')->default(0);
|
||||||
$table->char('peer_id', 20)->charset('binary')->index();
|
$table->binary('peer_id', 20)->index();
|
||||||
$table->string('ip', 64)->default('');
|
$table->string('ip', 64)->default('');
|
||||||
$table->unsignedSmallInteger('port')->default(0);
|
$table->unsignedSmallInteger('port')->default(0);
|
||||||
$table->unsignedBigInteger('uploaded')->default(0);
|
$table->unsignedBigInteger('uploaded')->default(0);
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ function sqlesc($value) {
|
|||||||
|
|
||||||
function hash_pad($hash) {
|
function hash_pad($hash) {
|
||||||
if (is_resource($hash)) {
|
if (is_resource($hash)) {
|
||||||
|
rewind($hash);
|
||||||
$hash = stream_get_contents($hash);
|
$hash = stream_get_contents($hash);
|
||||||
}
|
}
|
||||||
return str_pad($hash, 20);
|
return str_pad($hash, 20);
|
||||||
@@ -99,7 +100,14 @@ function hash_where($name, $hash) {
|
|||||||
// $shhash = preg_replace('/ *$/s', "", $hash);
|
// $shhash = preg_replace('/ *$/s', "", $hash);
|
||||||
// return "($name = " . sqlesc($hash) . " OR $name = " . sqlesc($shhash) . ")";
|
// return "($name = " . sqlesc($hash) . " OR $name = " . sqlesc($shhash) . ")";
|
||||||
// return sprintf("$name in (%s, %s)", sqlesc($hash), sqlesc($shhash));
|
// return sprintf("$name in (%s, %s)", sqlesc($hash), sqlesc($shhash));
|
||||||
return "$name = " . sqlesc($hash);
|
if (\Nexus\Database\NexusDB::isMysql()) {
|
||||||
|
return "$name = " . sqlesc($hash);
|
||||||
|
} elseif (Nexus\Database\NexusDB::isPgsql()) {
|
||||||
|
return "$name = decode(bin2hex('$hash'), 'hex')";
|
||||||
|
} else {
|
||||||
|
throw new \RuntimeException("Not supported database");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//no need any more...
|
//no need any more...
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Nexus\Database;
|
namespace Nexus\Database;
|
||||||
|
|
||||||
|
use PDOStatement;
|
||||||
|
|
||||||
interface DBInterface
|
interface DBInterface
|
||||||
{
|
{
|
||||||
public function connect($host, $username, $password, $database, $port, $driver = 'mysql');
|
public function connect($host, $username, $password, $database, $port, $driver = 'mysql');
|
||||||
@@ -29,4 +31,6 @@ interface DBInterface
|
|||||||
|
|
||||||
public function freeResult($result);
|
public function freeResult($result);
|
||||||
|
|
||||||
|
public function prepare(string $sql): PDOStatement;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,4 +92,9 @@ class DBMysqli implements DBInterface
|
|||||||
return $mysqliResult->free_result();
|
return $mysqliResult->free_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function prepare(string $sql): \PDOStatement
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("mysqli not supported");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,4 +125,9 @@ class DBPdo implements DBInterface
|
|||||||
return $stmt->closeCursor();
|
return $stmt->closeCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function prepare(string $sql): \PDOStatement
|
||||||
|
{
|
||||||
|
return $this->lastStmt = $this->pdo->prepare($sql);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,6 +151,11 @@ class NexusDB
|
|||||||
return $this->driver->freeResult($result);
|
return $this->driver->freeResult($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function prepare(string $sql)
|
||||||
|
{
|
||||||
|
return $this->driver->prepare($sql);
|
||||||
|
}
|
||||||
|
|
||||||
public function isConnected()
|
public function isConnected()
|
||||||
{
|
{
|
||||||
return $this->isConnected;
|
return $this->isConnected;
|
||||||
@@ -506,4 +511,15 @@ class NexusDB
|
|||||||
return compact('version', 'match', 'minVersion', 'dbType');
|
return compact('version', 'match', 'minVersion', 'dbType');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function unixTimestampField(string $field): string
|
||||||
|
{
|
||||||
|
if (self::isMysql()) {
|
||||||
|
return sprintf("UNIX_TIMESTAMP(%s)", $field);
|
||||||
|
} elseif (self::isPgsql()) {
|
||||||
|
return sprintf("EXTRACT(EPOCH FROM %s)", $field);
|
||||||
|
} else {
|
||||||
|
throw new \RuntimeException('Not supported database.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,3 +65,8 @@ function mysql_free_result($result)
|
|||||||
{
|
{
|
||||||
return NexusDB::getInstance()->freeResult($result);
|
return NexusDB::getInstance()->freeResult($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mysql_prepare(string $sql): \PDOStatement
|
||||||
|
{
|
||||||
|
return NexusDB::getInstance()->prepare($sql);
|
||||||
|
}
|
||||||
|
|||||||
+16
-9
@@ -172,11 +172,13 @@ elseif ($az['showclienterror'] == 'yes'){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check torrent based on info_hash
|
// check torrent based on info_hash
|
||||||
$checkTorrentSql = "SELECT torrents.id, size, owner, sp_state, seeders, leechers, times_completed, UNIX_TIMESTAMP(added) AS ts, added, banned, hr, approval_status, price, categories.mode FROM torrents left join categories on torrents.category = categories.id WHERE " . hash_where("info_hash", $info_hash);
|
$tsField = \Nexus\Database\NexusDB::unixTimestampField('added');
|
||||||
if (!$torrent = $Cache->get_value('torrent_hash_'.$info_hash.'_content')){
|
$checkTorrentSql = "SELECT torrents.id, size, owner, sp_state, seeders, leechers, times_completed, $tsField AS ts, added, banned, hr, approval_status, price, categories.mode FROM torrents left join categories on torrents.category = categories.id WHERE info_hash = decode(:info_hash, 'hex') limit 1";
|
||||||
$res = sql_query($checkTorrentSql);
|
if (!$torrent = $Cache->get_value('torrent_hash_'.$info_hash.'_content_111')){
|
||||||
|
$res = mysql_prepare($checkTorrentSql);
|
||||||
|
$res->execute(['info_hash' => bin2hex($info_hash)]);
|
||||||
$torrent = mysql_fetch_array($res);
|
$torrent = mysql_fetch_array($res);
|
||||||
$Cache->cache_value('torrent_hash_'.$info_hash.'_content', $torrent, 350);
|
$Cache->cache_value('torrent_hash_'.$info_hash.'_content', $torrent, 350);
|
||||||
}
|
}
|
||||||
if (!$torrent) {
|
if (!$torrent) {
|
||||||
$firstNeedle = "info_hash=";
|
$firstNeedle = "info_hash=";
|
||||||
@@ -226,7 +228,9 @@ if ($newnumpeers > $rsize)
|
|||||||
else $limit = "";
|
else $limit = "";
|
||||||
|
|
||||||
$announce_wait = \App\Repositories\TrackerRepository::MIN_ANNOUNCE_WAIT_SECOND;
|
$announce_wait = \App\Repositories\TrackerRepository::MIN_ANNOUNCE_WAIT_SECOND;
|
||||||
$fields = "id, seeder, peer_id, ip, ipv4, ipv6, port, uploaded, downloaded, userid, last_action, UNIX_TIMESTAMP(last_action) as last_action_unix_timestamp, prev_action, (".TIMENOW." - UNIX_TIMESTAMP(last_action)) AS announcetime, UNIX_TIMESTAMP(prev_action) AS prevts";
|
$lastActionField = \Nexus\Database\NexusDB::unixTimestampField('last_action');
|
||||||
|
$prevActionField = \Nexus\Database\NexusDB::unixTimestampField('prev_action');
|
||||||
|
$fields = "id, seeder, peer_id, ip, ipv4, ipv6, port, uploaded, downloaded, userid, last_action, $lastActionField as last_action_unix_timestamp, prev_action, (".TIMENOW." - $lastActionField) AS announcetime, $prevActionField AS prevts";
|
||||||
//$peerlistsql = "SELECT ".$fields." FROM peers WHERE torrent = ".$torrentid." AND connectable = 'yes' ".$only_leech_query.$limit;
|
//$peerlistsql = "SELECT ".$fields." FROM peers WHERE torrent = ".$torrentid." AND connectable = 'yes' ".$only_leech_query.$limit;
|
||||||
/**
|
/**
|
||||||
* return all peers,include connectable no
|
* return all peers,include connectable no
|
||||||
@@ -286,11 +290,12 @@ if (isset($event) && $event == "stopped") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$selfwhere = "torrent = $torrentid AND " . hash_where("peer_id", $peer_id) . " AND userid = $userid";
|
$selfwhere = "torrent = $torrentid AND peer_id = decode(:peer_id, 'hex') AND userid = $userid";
|
||||||
//no found in the above random selection
|
//no found in the above random selection
|
||||||
if (!isset($self))
|
if (!isset($self))
|
||||||
{
|
{
|
||||||
$res = sql_query("SELECT $fields FROM peers WHERE $selfwhere LIMIT 1");
|
$res = mysql_prepare("SELECT $fields FROM peers WHERE $selfwhere LIMIT 1");
|
||||||
|
$res->execute(['peer_id' => bin2hex($peer_id)]);
|
||||||
$row = mysql_fetch_assoc($res);
|
$row = mysql_fetch_assoc($res);
|
||||||
if ($row)
|
if ($row)
|
||||||
{
|
{
|
||||||
@@ -500,8 +505,10 @@ elseif(isset($self))
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ($event != 'stopped') {
|
if ($event != 'stopped') {
|
||||||
$isPeerExistResultSet = sql_query("select id from peers where $selfwhere limit 1");
|
$stmt = mysql_prepare("select id from peers where $selfwhere limit 1");
|
||||||
if (mysql_num_rows($isPeerExistResultSet) == 0) {
|
$stmt->execute(['peer_id' => bin2hex($peer_id)]);
|
||||||
|
$isPeerExistResultSet = mysql_fetch_assoc($stmt);
|
||||||
|
if (empty($isPeerExistResultSet)) {
|
||||||
$connectable = "yes";
|
$connectable = "yes";
|
||||||
$insertPeerSql = "INSERT INTO peers (torrent, userid, peer_id, ip, port, connectable, uploaded, downloaded, to_go, started, last_action, seeder, agent, downloadoffset, uploadoffset, passkey, ipv4, ipv6, is_seed_box) VALUES ($torrentid, $userid, ".sqlesc($peer_id).", ".sqlesc($ip).", $port, '$connectable', $uploaded, $downloaded, $left, $dt, $dt, '$seeder', ".sqlesc($agent).", $downloaded, $uploaded, ".sqlesc($passkey).", ".sqlesc($ipv4).", ".sqlesc($ipv6).", ".intval($isIPSeedBox).")";
|
$insertPeerSql = "INSERT INTO peers (torrent, userid, peer_id, ip, port, connectable, uploaded, downloaded, to_go, started, last_action, seeder, agent, downloadoffset, uploadoffset, passkey, ipv4, ipv6, is_seed_box) VALUES ($torrentid, $userid, ".sqlesc($peer_id).", ".sqlesc($ip).", $port, '$connectable', $uploaded, $downloaded, $left, $dt, $dt, '$seeder', ".sqlesc($agent).", $downloaded, $uploaded, ".sqlesc($passkey).", ".sqlesc($ipv4).", ".sqlesc($ipv6).", ".intval($isIPSeedBox).")";
|
||||||
do_log("[INSERT PEER] peer not exists for $selfwhere, do insert with $insertPeerSql");
|
do_log("[INSERT PEER] peer not exists for $selfwhere, do insert with $insertPeerSql");
|
||||||
|
|||||||
Reference in New Issue
Block a user