Switchout DB to CockroachDB
This commit is contained in:
@@ -11,7 +11,7 @@ use Illuminate\Support\Facades\DB;
|
||||
|
||||
use App\Classes\FTN\Packet;
|
||||
use App\Http\Controllers\DomainController;
|
||||
use App\Traits\{ScopeActive,UsePostgres};
|
||||
use App\Traits\ScopeActive;
|
||||
|
||||
/**
|
||||
* @todo Need to stop this from happening:
|
||||
@@ -24,7 +24,9 @@ use App\Traits\{ScopeActive,UsePostgres};
|
||||
*/
|
||||
class Address extends Model
|
||||
{
|
||||
use ScopeActive,SoftDeletes,UsePostgres;
|
||||
use ScopeActive,SoftDeletes;
|
||||
|
||||
protected $with = ['zone'];
|
||||
|
||||
/* SCOPES */
|
||||
|
||||
@@ -337,6 +339,21 @@ class Address extends Model
|
||||
return ($o && $o->system->active) ? $o : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Netmail waiting to be sent to this system
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function echomailWaiting(): Collection
|
||||
{
|
||||
return Echomail::select(['echomails.*'])
|
||||
->join('echomail_seenby',['echomail_seenby.echomail_id'=>'echomails.id'])
|
||||
->where('echomail_seenby.address_id',$this->id)
|
||||
->whereNull('echomail_seenby.sent_at')
|
||||
->whereNotNull('echomail_seenby.export_at')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get echomail for this node
|
||||
*
|
||||
@@ -346,23 +363,17 @@ class Address extends Model
|
||||
{
|
||||
$pkt = NULL;
|
||||
|
||||
$echomail = DB::table('address_echomail')
|
||||
->select('echomail_id')
|
||||
->where('address_id',$this->id)
|
||||
->whereNull('sent_date')
|
||||
->get();
|
||||
|
||||
if (($x=Echomail::select('*')
|
||||
->whereIn('_id',$echomail->pluck('echomail_id')))
|
||||
if (($x=$this->echomailWaiting())
|
||||
->count())
|
||||
{
|
||||
$pkt = $this->getPacket($x->get());
|
||||
$pkt = $this->getPacket($x);
|
||||
|
||||
DB::table('address_echomail')
|
||||
->whereIn('echomail_id',$echomail->pluck('echomail_id'))
|
||||
DB::table('echomail_seenby')
|
||||
->whereIn('echomail_id',$x->pluck('id'))
|
||||
->where('address_id',$this->id)
|
||||
->whereNull('sent_date')
|
||||
->update(['sent_date'=>Carbon::now()]);
|
||||
->whereNull('sent_at')
|
||||
->whereNotNull('echomail_seenby.export_at')
|
||||
->update(['sent_at'=>Carbon::now(),'packet'=>$pkt->name]);
|
||||
}
|
||||
|
||||
return $pkt;
|
||||
@@ -375,18 +386,19 @@ class Address extends Model
|
||||
*/
|
||||
public function getNetmail(): ?Packet
|
||||
{
|
||||
if (($x=Netmail::whereIn('tftn_id',(($x=$this->children) ? $x->pluck('id') : collect())->push($this->id))
|
||||
->where(function($q) {
|
||||
return $q->whereNull('sent')
|
||||
->orWhere('sent',FALSE);
|
||||
}))
|
||||
->whereNull('local')
|
||||
$pkt = NULL;
|
||||
|
||||
if (($x=$this->netmailWaiting())
|
||||
->count())
|
||||
{
|
||||
return $this->getPacket($x->get());
|
||||
$pkt = $this->getPacket($x);
|
||||
|
||||
DB::table('netmails')
|
||||
->whereIn('id',$x->pluck('id'))
|
||||
->update(['sent_at'=>Carbon::now(),'sent_pkt'=>$pkt->name]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return $pkt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -411,6 +423,18 @@ class Address extends Model
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Netmail waiting to be sent to this system
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function netmailWaiting(): Collection
|
||||
{
|
||||
return Netmail::whereIn('tftn_id',(($x=$this->children) ? $x->pluck('id') : collect())->push($this->id))
|
||||
->whereNull('sent_at')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and split it out as an FTN array
|
||||
*
|
||||
|
@@ -7,13 +7,15 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use MongoDB\BSON\UTCDateTime;
|
||||
|
||||
use App\Traits\ScopeActive;
|
||||
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
||||
|
||||
class Domain extends Model
|
||||
{
|
||||
use HasFactory,ScopeActive;
|
||||
use HasFactory,ScopeActive,QueryCacheableConfig;
|
||||
|
||||
private const CACHE_TIME = 3600;
|
||||
private const STATS_MONTHS = 6;
|
||||
|
||||
@@ -65,17 +67,19 @@ class Domain extends Model
|
||||
|
||||
$key = sprintf('%s_%d','daily_area_stats',$this->id);
|
||||
|
||||
return Cache::driver('redis')->remember($key,self::CACHE_TIME,function() {
|
||||
$where = [
|
||||
'echoarea_id'=>$this->echoareas->pluck('id')->toArray(),
|
||||
'datetime' => ['$gte',new UTCDateTime(Carbon::now()->subMonths(self::STATS_MONTHS)->startOfMonth())],
|
||||
];
|
||||
Cache::forget($key);
|
||||
return Cache::remember($key,self::CACHE_TIME,function() {
|
||||
$gb ="CONCAT(EXTRACT('year',datetime)::string,'-',LPAD(EXTRACT('month',datetime)::string,2,'0'),'-',LPAD(EXTRACT('day',datetime)::string,2,'0')) AS datetime";
|
||||
|
||||
$echostats = Echomail::countGroupBy(['datetime',['datetime'=>'%Y-%m-%d']],$where);
|
||||
$echostats = Echomail::select([DB::raw($gb),DB::raw('COUNT(*)')])
|
||||
->whereIn('id',$this->echoareas->pluck('id')->toArray())
|
||||
->where('datetime','>=',Carbon::now()->subMonths(self::STATS_MONTHS)->startOfMonth())
|
||||
->groupBy('datetime')
|
||||
->orderBy('datetime')
|
||||
->get();
|
||||
|
||||
return $echostats
|
||||
->sortBy(function($item) { return $item->id->datetime; })
|
||||
->map(function($item) { return ['x'=>Carbon::createFromFormat('Y-m-d',$item->id->datetime)->timestamp*1000,'y'=>$item->count]; })
|
||||
->map(function($item) { return ['x'=>$item->datetime->timestamp*1000,'y'=>$item->count]; })
|
||||
->values();
|
||||
});
|
||||
}
|
||||
@@ -87,17 +91,19 @@ class Domain extends Model
|
||||
|
||||
$key = sprintf('%s_%d-%d','daily_echoarea_stats',$this->id,$o->id);
|
||||
|
||||
return Cache::driver('redis')->remember($key,self::CACHE_TIME,function() use ($o) {
|
||||
$where = [
|
||||
'echoarea_id'=>[$o->id],
|
||||
'datetime' => ['$gte',new UTCDateTime(Carbon::now()->subMonths(self::STATS_MONTHS)->startOfMonth())],
|
||||
];
|
||||
Cache::forget($key);
|
||||
return Cache::remember($key,self::CACHE_TIME,function() use ($o) {
|
||||
$gb ="CONCAT(EXTRACT('year',datetime)::string,'-',LPAD(EXTRACT('month',datetime)::string,2,'0'),'-',LPAD(EXTRACT('day',datetime)::string,2,'0')) AS datetime";
|
||||
|
||||
$echostats = Echomail::countGroupBy(['datetime',['datetime'=>'%Y-%m-%d']],$where);
|
||||
$echostats = Echomail::select([DB::raw($gb),DB::raw('COUNT(*)')])
|
||||
->whereIn('echoarea_id',[$o->id])
|
||||
->where('datetime','>=',Carbon::now()->subMonths(self::STATS_MONTHS)->startOfMonth())
|
||||
->groupBy('datetime')
|
||||
->orderBy('datetime')
|
||||
->get();
|
||||
|
||||
return $echostats
|
||||
->sortBy(function($item) { return $item->id->datetime; })
|
||||
->map(function($item) { return ['x'=>Carbon::createFromFormat('Y-m-d',$item->id->datetime)->timestamp*1000,'y'=>$item->count]; })
|
||||
->map(function($item) { return ['x'=>$item->datetime->timestamp*1000,'y'=>$item->count]; })
|
||||
->values();
|
||||
});
|
||||
}
|
||||
|
@@ -3,14 +3,16 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Traits\{ScopeActive,UsePostgres};
|
||||
|
||||
use App\Traits\ScopeActive;
|
||||
|
||||
class Echoarea extends Model
|
||||
{
|
||||
use SoftDeletes,ScopeActive,UsePostgres;
|
||||
use SoftDeletes,ScopeActive;
|
||||
|
||||
private const CACHE_TIME = 3600;
|
||||
|
||||
@@ -28,28 +30,24 @@ class Echoarea extends Model
|
||||
|
||||
public function echomail()
|
||||
{
|
||||
return Echomail::select('*')
|
||||
->where('echoarea_id',$this->id);
|
||||
return $this->hasMany(Echomail::class)
|
||||
->orderBy('datetime','ASC');
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
public function getLastMessageAttribute(): ?Carbon
|
||||
{
|
||||
$key = sprintf('%s_%d','echo_last_message',$this->id);
|
||||
|
||||
return Cache::driver('redis')->remember($key,self::CACHE_TIME,function() {
|
||||
return ($x=$this->echomail()->orderBy('datetime','DESC')->first()) ? $x->datetime : NULL;
|
||||
});
|
||||
return $this->echomail?->last()->datetime;
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function messages_count(int $period): int
|
||||
{
|
||||
$key = sprintf('%s_%d_%d','echo_mesages_count',$this->id,$period);
|
||||
$key = sprintf('%s_%d_%d','echo_messages_count',$this->id,$period);
|
||||
|
||||
return Cache::driver('redis')->remember($key,self::CACHE_TIME,function() use ($period) {
|
||||
return Cache::remember($key,self::CACHE_TIME,function() use ($period) {
|
||||
switch ($period) {
|
||||
case 1: // day
|
||||
return $this->echomail()->where('datetime','>=',Carbon::now()->startOfday()->subDay())->count();
|
||||
@@ -62,4 +60,20 @@ class Echoarea extends Model
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of messages waiting for address
|
||||
*
|
||||
* @param Address $ao
|
||||
* @return Collection
|
||||
*/
|
||||
public function waiting(Address $ao): Collection
|
||||
{
|
||||
return $this->echomail()
|
||||
->join('echomail_seenby',['echomail_seenby.echomail_id'=>'echomails.id'])
|
||||
->whereNull('sent_at')
|
||||
->whereNotNull('export_at')
|
||||
->where('address_id',$ao->id)
|
||||
->get();
|
||||
}
|
||||
}
|
@@ -3,25 +3,29 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
|
||||
|
||||
use App\Classes\FTN\Message;
|
||||
use App\Interfaces\Packet;
|
||||
use App\Traits\{EncodeUTF8,MsgID,UseMongo};
|
||||
use App\Traits\{EncodeUTF8,MsgID};
|
||||
|
||||
final class Echomail extends Model implements Packet
|
||||
{
|
||||
use SoftDeletes,MsgID,UseMongo,EncodeUTF8;
|
||||
use SoftDeletes,EncodeUTF8,MsgID;
|
||||
|
||||
private const LOGKEY = 'ME-';
|
||||
private array $set_seenby = [];
|
||||
private array $set_path = [];
|
||||
private ?string $set_packet = NULL;
|
||||
|
||||
protected $collection = FALSE;
|
||||
|
||||
protected $casts = [ 'kludges' => 'json' ];
|
||||
protected $casts = [
|
||||
'kludges' => 'json',
|
||||
'rogue_seenby' => 'json',
|
||||
'rogue_path' => 'json',
|
||||
];
|
||||
|
||||
private const cast_utf8 = [
|
||||
'to',
|
||||
@@ -35,6 +39,20 @@ final class Echomail extends Model implements Packet
|
||||
|
||||
protected $dates = ['datetime'];
|
||||
|
||||
public function __set($key, $value)
|
||||
{
|
||||
switch ($key) {
|
||||
case 'set_path':
|
||||
case 'set_packet':
|
||||
case 'set_seenby':
|
||||
$this->{$key} = $value;
|
||||
break;
|
||||
|
||||
default:
|
||||
parent::__set($key,$value);
|
||||
}
|
||||
}
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
@@ -46,29 +64,43 @@ final class Echomail extends Model implements Packet
|
||||
return;
|
||||
}
|
||||
|
||||
// See if we need to export this message.
|
||||
$exportto = $model->echoarea->addresses->pluck('system')->diff($model->seenby->pluck('system'));
|
||||
|
||||
$export_ao = collect();
|
||||
foreach ($model->echoarea->domain->zones as $zo) {
|
||||
foreach ($exportto as $so) {
|
||||
$export_ao = $export_ao->merge($so->match($zo));
|
||||
}
|
||||
}
|
||||
|
||||
// Add to export
|
||||
foreach ($export_ao as $ao) {
|
||||
Log::info(sprintf('%s:- Exporting message [%s] to [%s]',self::LOGKEY,$model->id,$ao->ftn));
|
||||
|
||||
DB::table('address_echomail')->insert([
|
||||
'address_id'=>$ao->id,
|
||||
'echomail_id'=>$model->id,
|
||||
'export_date'=>Carbon::now()
|
||||
// Save the seenby
|
||||
foreach ($model->set_seenby as $aoid) {
|
||||
DB::insert('INSERT INTO echomail_seenby (echomail_id,address_id,packet) VALUES (?,?,?)',[
|
||||
$model->id,
|
||||
$aoid,
|
||||
$model->set_packet,
|
||||
]);
|
||||
}
|
||||
|
||||
$model->seenby = $model->seenby->merge($export_ao)->pluck('id')->toArray();
|
||||
$model->save();
|
||||
// Save the Path
|
||||
$ppoid = NULL;
|
||||
foreach ($model->set_path as $aoid) {
|
||||
$po = DB::select('INSERT INTO echomail_path (echomail_id,address_id,parent_id) VALUES (?,?,?) RETURNING id',[
|
||||
$model->id,
|
||||
$aoid,
|
||||
$ppoid,
|
||||
]);
|
||||
|
||||
$ppoid = $po[0]->id;
|
||||
}
|
||||
|
||||
// See if we need to export this message.
|
||||
$exportto = $model->echoarea->addresses->pluck('id')->diff($model->set_seenby);
|
||||
|
||||
if ($exportto->count()) {
|
||||
Log::debug(sprintf('%s:- Exporting message [%s] to [%s]',self::LOGKEY,$model->id,$exportto->join(',')));
|
||||
|
||||
// Save the seenby for the exported systems
|
||||
$export_at = Carbon::now();
|
||||
foreach ($exportto as $aoid) {
|
||||
DB::insert('INSERT INTO echomail_seenby (echomail_id,address_id,export_at) VALUES (?,?,?)',[
|
||||
$model->id,
|
||||
$aoid,
|
||||
$export_at,
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -81,35 +113,19 @@ final class Echomail extends Model implements Packet
|
||||
|
||||
public function fftn()
|
||||
{
|
||||
return $this
|
||||
->setConnection('pgsql')
|
||||
->belongsTo(Address::class)
|
||||
return $this->belongsTo(Address::class)
|
||||
->withTrashed();
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
public function getKludgesAttribute(?string $value): Collection
|
||||
public function seenby()
|
||||
{
|
||||
return collect($this->castAttribute('kludges',$value));
|
||||
return $this->belongsToMany(Address::class,'echomail_seenby')
|
||||
->ftnOrder();
|
||||
}
|
||||
|
||||
public function getPathAttribute(?array $value): Collection
|
||||
public function path()
|
||||
{
|
||||
if (is_null($value))
|
||||
return collect();
|
||||
|
||||
return Address::whereIn('id',$value)
|
||||
->orderBy(DB::raw(sprintf("position (id::text in '(%s)')",join(',',$value))))
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getSeenByAttribute(?array $value): Collection
|
||||
{
|
||||
if (is_null($value))
|
||||
return collect();
|
||||
|
||||
return Address::whereIn('id',$value)->get();
|
||||
return $this->belongsToMany(Address::class,'echomail_path');
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
@@ -149,11 +165,11 @@ final class Echomail extends Model implements Packet
|
||||
if ($this->kludges)
|
||||
$o->kludge = $this->kludges;
|
||||
|
||||
$o->kludge->put('mid',$this->id);
|
||||
$o->kludge->put('dbid',$this->id);
|
||||
|
||||
$o->msgid = $this->msgid;
|
||||
if ($this->reply)
|
||||
$o->reply = $this->reply;
|
||||
if ($this->replyid)
|
||||
$o->replyid = $this->replyid;
|
||||
|
||||
$o->message = $this->msg;
|
||||
|
||||
|
@@ -3,19 +3,19 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Jenssegers\Mongodb\Eloquent\SoftDeletes;
|
||||
|
||||
use App\Classes\FTN\Message;
|
||||
use App\Interfaces\Packet;
|
||||
use App\Traits\{EncodeUTF8,UseMongo};
|
||||
use App\Traits\EncodeUTF8;
|
||||
|
||||
final class Netmail extends Model implements Packet
|
||||
{
|
||||
private const LOGKEY = 'MN-';
|
||||
|
||||
use SoftDeletes,UseMongo,EncodeUTF8;
|
||||
use SoftDeletes,EncodeUTF8;
|
||||
|
||||
private const cast_utf8 = [
|
||||
'to',
|
||||
@@ -80,8 +80,8 @@ final class Netmail extends Model implements Packet
|
||||
$o->flags = $this->flags;
|
||||
|
||||
$o->msgid = sprintf('%s %08x',$this->fftn->ftn3d,crc32($this->id));
|
||||
if ($this->reply)
|
||||
$o->reply = $this->reply;
|
||||
if ($this->replyid)
|
||||
$o->replyid = $this->replyid;
|
||||
|
||||
$o->message = $this->msg;
|
||||
$o->tagline = $this->tagline;
|
||||
|
@@ -8,10 +8,11 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use App\Http\Controllers\DomainController;
|
||||
use App\Traits\QueryCacheableConfig;
|
||||
|
||||
class System extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasFactory,QueryCacheableConfig;
|
||||
|
||||
protected $dates = ['last_session'];
|
||||
|
||||
@@ -37,10 +38,7 @@ class System extends Model
|
||||
public function addresses()
|
||||
{
|
||||
return $this->hasMany(Address::class)
|
||||
->orderBy('region_id')
|
||||
->orderBy('host_id')
|
||||
->orderBy('node_id')
|
||||
->orderBy('point_id');
|
||||
->FTNorder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -4,11 +4,11 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
use App\Traits\ScopeActive;
|
||||
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
||||
|
||||
class Zone extends Model
|
||||
{
|
||||
use ScopeActive;
|
||||
use ScopeActive,QueryCacheableConfig;
|
||||
|
||||
/* SCOPES */
|
||||
|
||||
|
Reference in New Issue
Block a user