Ferreteria/v0.6/clade/Sys/Data/Engine/Oper/MyMar/@removed
Jump to navigation
Jump to search
|
Removed Code
|
2025-12-28
Removed some time ago:
#
public function DoExport(string $sSchema, RecvBuffClass $oInBuff) : CommOpIface {
$oConnDB = $this->OConn(); // DB connection
$oSockDB = $oConnDB->OSock();
$oConnSh = $oSockDB->OPlug();
$sCred = $oConnDB->CredsForCmd(); // DB connection string from DB-local shell
$sCmd = "mysqldump $sCred --quick $sSchema"; // "--quick" does line-at-a-time rather than buffering entire table
// should we also try "--single-transaction"? "To dump large tables, you should combine the --single-transaction option with --quick."
// Send dump command directly to shell, not to DB engine:
$oAct = $oConnSh->DoCommand($sCmd,$oInBuff,new CommOpClass);
return $oAct;
}
2025-12-07
I decided to substantially change this class's lifecycle ops, so here is the entire previous version:
// 2025-12-07 previous API
interface iMyMar extends BaseIface, ItWentIface {
// LIFECYCLE
function OpenEngine(string $sAddr, string $sUser, string $sPass, ?string $sSchema, ?int $nzPort) : ActionIface;
function ShutEngine() : ActionIface;
// INFO
function SchemaExists(string $sName) : bool; // 2025-05-30 Eventually, will want a base-class for all multi-schema engines.
}
abstract class caMyMar extends BaseClass implements iMyMar {
use ItWentTrait;
// ++ CONFIG ++ //
protected function CommOpClass() : string { return CommOpClass::class; } // specialize later
protected function SchemaClass() : string { return SchemaClass::class; }
protected function ScribeClass() : string { return ScribeClass::class; }
// -- CONFIG -- //
// ++ SETTINGS ++ //
private $eFmt = BkupModeEnum::USE_SQL; // DEFAULT
public function DataFormat(?BkupModeEnum $eMode=NULL) : BkupModeEnum { return is_object($eMode) ? ($this->eFmt = $eMode) : $this->eFmt; }
// -- SETTINGS -- //
// ++ LIFECYCLE ++ //
public function OpenEngine(string $sAddr, string $sUser, string $sPass, ?string $sSchema, ?int $nzPort) : ActionIface {
$oAct = $this->HowItWent(); // get an ItWent object
$oAct->Clear();
#$this->AmHere("ADDR: [$sAddr] - USER: [$sUser] - PASS: [$sPass]");
$onDB = new mysqli();
$this->QNative()->SetIt($onDB);
try {
$ok = $onDB->connect($sAddr,$sUser,$sPass,$sSchema,$nzPort); // open the DB connection
} catch(\Exception $e) {
$ok = FALSE;
#echo "EXCEPTION: ".$e.CRLF;
}
if ($ok) {
$oAct->SetOkay(TRUE);
} else {
// 2022-01-26 probably want a method to do all this
$oAct->SetOkay(FALSE);
#echo $this->ReflectThis()->Report();
$oAct->SetError($e->getCode());
$oAct->AddMsgString($e->getMessage());
}
return $oAct;
}
public function ShutEngine() : ActionIface {
$oAct = $this->HowItWent();
if ($oAct->GetOkay()) { // Did Engine actually get opened? (2025-12-06 We probably need a separate flag for this. TODO)
// close endpoint-to-engine connection
$onDB = $this->QNative()->GetIt();
$ok = $onDB->close();
// close code-to-endpoint connection
$oAct->SetOkay($ok);
}
return $oAct;
}
// -- LIFECYCLE -- //
// ++ ACTION: UI requests ++ //
public function DoDataRequest(DataReqIface $oReq) : PlayerIface {
$this->Open();
$sql = $oReq->SQL();
#echo "SQL: $sql".CRLF;
$onRes = $this->QNative()->GetIt()->query($sql);
$oReq->Action()->SetOkay(is_object($onRes));
$scScribe = $this->ScribeClass();
# echo $oReq->ReflectThis()->Report();
$oScribe = $scScribe::FromRequestAndNative($oReq,$onRes);
$oPlay = $oReq->MakePlayer($oScribe);
$this->Shut();
return $oPlay;
}
// ++ ACTION: Schema info ++ //
private $oaSchemas = NULL;
public function SchemaList() : SchemasIface { return $this->oaSchemas ?? ($this->oaSchemas = $this->NewSchemaList()); }
public function SchemaExists(string $sName) : bool { return $this->SchemaList()->HasIt($sName); }
protected function NewSchemaList() : SchemasIface {
$oConn = $this->OConn(); // get (remote|local) connection object
$oConn->Open(); // make sure it's open
$sqCmd = 'SHOW SCHEMAS;';
#$this->AmHere("DB COMMAND: $sqCmd");
$oBuff = new MemBufferClass;
#echo $oBuff->ReflectThis()->Report();
$oBuff->Open();
$oPlug = $oConn->OSock()->OPlug();
$oPlug->Open();
$oActConn = $oConn->DoCommand($sqCmd,$oBuff,new ($this->CommOpClass()));
$oActConn->HandleResults(); // deal with standard errors/warnings
$oPlug->Shut();
$oActApp = $this->CommOpStatus();
$oScrn = self::Screen();
$oaSchemas = SchemasClass::AsNew();
if ($oBuff->IsMore()) {
#$this->AmHere('GOT SCHEMA LIST');
$sNames = $oBuff->RemoveBytes();
$arNames = explode("\n",trim($sNames)); // we might want to ensure that CRLF, CR, and LF all work as EOL.
#$this->AmHere(' - ELEMENTS: '.count($arNames));
$sFirst = array_shift($arNames);
if ($sFirst == "Database") {
$oActApp->SetOkay(TRUE);
foreach ($arNames as $sName) {
$oSchema = $this->GetSchema($sName);
$oaSchemas->AddSchema($oSchema);
#$this->AmHere(" -- SCHEMA: [$sName]");
}
} else {
$oActApp->SetOkay(FALSE);
// "Database" is the standard header for list of databases (schemas).
// If we don't see this, then something isn't right.
$sMsg = $oScrn->ErrorIt('Problem').": Something's not right with the db list. Here's what we got:".CRLF.$sList;
$oActApp->AddMsgString($sMsg);
}
} else {
$sMsg = self::Screen()->ErrorIt('Problem').': the connection does not seem to be working.';
$oActApp->SetOkay(FALSE);
$oActApp->AddMsgString($sMsg);
}
$oConn->Shut();
return $oaSchemas;
}
// DOCS: https://wooz.dev/Ferreteria/v0.6/clade/Sys/Data/Engine/Oper/MyMar/@fx/DoExport
public function DoExport(string $sSchema, RecvBuffClass $oInBuff) : CommOpIface {
$oConnDB = $this->OConn(); // DB connection
$oSockDB = $oConnDB->OSock();
$oConnSh = $oSockDB->OPlug();
$sCred = $oConnDB->CredsForCmd(); // DB connection string from DB-local shell
$sCmd = "mysqldump $sCred --quick $sSchema"; // "--quick" does line-at-a-time rather than buffering entire table
// should we also try "--single-transaction"? "To dump large tables, you should combine the --single-transaction option with --quick."
// Send dump command directly to shell, not to DB engine:
$oAct = $oConnSh->DoCommand($sCmd,$oInBuff,new CommOpClass);
return $oAct;
}
// ++ ACTION: UI request callbacks ++ //
// SEE DOCS
public function DoTestAccess() {
$ok = $this->TestUserAccess();
if (!$ok) {
echo "(Since that didn't work, let's try unconfigured root.)".CRLF;
$ok = $this->TestRootAccess();
}
}
// SEE DOCS
public function DoUserSetup() {
$oScrn = self::Screen();
// 2025-03-30 has worked at least once now
#echo $oScrn->YellowIt('Warning').': This functionality has not been tested to the point of success yet. It may not work.'.CRLF;
$ok = $this->TestRootAccess();
if ($ok) {
echo $oScrn->GreenIt('Ok').': we seem to have unconfigured root access. Proceeding...'.CRLF;
} else {
echo $oScrn->ErrorIt('Error').': This DB engine is configured, and can only be accessed with credentials.'.CRLF;
exit;
}
$oCreds = $this->Creds();
$sDUser = $oCreds->QSUser()->GetIt();
$sDPass = $oCreds->QSPass()->GetIt();
$sDHost = $oCreds->QSHost()->GetIt();
// IN-SHELL COMMAND: sudo mysql "CREATE USER '<USERNAME>'@<HOST> IDENTIFIED BY '<PASSWORD>'"
$q = '"';
$sql = $q."ALTER USER '$sDUser'@$sDHost IDENTIFIED BY '$sDPass';$q";
$sCmd = "echo $sql | sudo mysql";
// DEBUGGING ONLY (shows password)
#echo $oScrn->BoldIt('Command').': '.$oScrn->BlueIt($sCmd).CRLF;
$oConnx = $this->Connx(); // shell (outside) connection details
echo "Adding initial user '$sDUser' on db server '$sDHost'...".CRLF;
// DEBUGGING ONLY
#echo "INSIDE COMMAND: $sCmd".CRLF; die();
#echo $oConnx->ReflectThis()->Report(); die();
$oBuff = new MemBufferClass;
echo 'Running the SQL to create the first user...'.CRLF;
$oAct = $oConnx->DoCommand($sCmd,$oBuff);
$ok = $oAct->GetOkay();
if (!$ok) {
// See if we can handle this condition...
$sMsg = $oAct->GetMessage();
if (str_contains($sMsg,'server is running with the --skip-grant-tables option')) {
// NOTE: It may be that what actually needs to happen is just "FLUSH PRIVILEGES;" and try again.
echo 'Apparently the server is in permissionless mode, so using alternative SQL.'.CRLF;
// SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
echo "(Full message: $sMsg)".CRLF;
// FOR DEBUGGING ONLY (shows password):
$sql = "ALTER USER '$sDUser'@'$sDHost' IDENTIFIED BY '$sDPass';";
echo "SQL: $sql".CRLF;
#$sCmd = "echo $sql | sudo mysql";
$sCmd = 'echo "$sql" | sudo mysql';
$oAct = $oConnx->DoCommand($sCmd,$oBuff);
$ok = $oAct->GetOkay();
if (!$ok) {
echo 'Meh, that failed too. Giving up for now.'.CRLF;
}
}
}
if ($ok) {
$oAct = $oConnx->DoCommand($sCmd,$oBuff);
$oConnx->Shut();
echo ' - ' . (($oAct->GetOkay() ? $oScrn->GreenIt('Done.') : ($oScrn->ErrorIt('Error: ').$oAct->GetMessage()))) . CRLF;
} else {
echo $oScrn->ErrorIt('Error: ')
.$oScrn->YellowIt($sMsg)
.' - The setup failed for some reason.'
.CRLF;
}
$oAct = $oBuff->Shut();
}
// ++ ACTION: UI pieces ++ //
// SEE DOCS
protected function TestUserAccess() {
$oScrn = self::Screen();
#echo $this->ReflectThis()->Report();
$sName = $this->ConnSlug();
$ftName = $oScrn->GreenIt($sName);
echo "[$ftName]: Testing configured credentials... ";
$sCreds = $this->OConn()->CredsForCmd(); // 2025-06-05 get this from the Creds object now.
return $this->TestAccess($sCreds);
}
// SEE DOCS
protected function TestRootAccess() : bool {
$oScrn = self::Screen();
$sName = $this->ObjectSlug();
$ftName = $oScrn->GreenIt($sName);
echo "Testing unconfigured root access on [$ftName]... ";
return $this->TestAccess('');
}
protected function TestAccess(string $sCreds) : bool {
$oScrn = self::Screen();
$sSQL = 'SHOW SCHEMAS;';
$bRoot = ($sCreds === '');
if ($bRoot) {
$sCmd = "echo $sSQL | sudo mysql";
$sMode = 'unconfigured root';
} else {
$sCmd = "echo $sSQL | mysql $sCreds";
$sMode = 'credentialed user';
}
$oConnx = $this->OConn(); // shell (outside) connection details
// DEBUGGING ONLY:
#echo 'SQL COMMAND: '.$sCmd.CRLF;
$oBuff = new MemBufferClass;
#$oConnx->CommOpClass(CommOpClass::class); // tell oConnx what class to use for Action
$oBuff->Open(); // keep buffer open for reading data
$oConnx->Open();
$oAct = $oConnx->DoCommand($sCmd,$oBuff,new CommOpClass);
$oAct->HandleResults();
$oConnx->Shut();
$ok = $oAct->GetOkay();
if ($ok) {
#echo $oScrn->GreenIt('Done.').CRLF;
$sList = $oBuff->RemoveBytes();
$arList = explode("\n",trim($sList)); // we might want to ensure that CRLF, CR, and LF all work as EOL.
// "Database" is the standard header for list of databases.
// If we don't see this, then something isn't right.
$sFirst = array_shift($arList);
if ($sFirst != "Database") {
self::GotToHere("Something's not right with the db list. Here's what we got:".CRLF.$sList); die();
}
$ftMode = $oScrn->BoldIt($sMode);
$ftStatus = $oScrn->GreenIt('Success');
$sSuggest = $bRoot ? ' ("setup" should work)' : '';
echo "$ftStatus: Access in $ftMode mode seems to be ok$sSuggest. Here's a list of schemas found:".CRLF;
$oList = $oScrn->NewList();
foreach ($arList as $sSchema) {
$oList->AddLine($sSchema);
}
echo $oList->Render();
} else {
$ftStatus = $oScrn->ErrorIt('Error');
$ftMsg = $oScrn->YellowIt($oAct->GetMessage());
$sSuggest = $bRoot ? ' (Try "setup"?)' : '';
echo "$ftStatus: We do not seem to have access.$sSuggest Error received was: ".CRLF.$ftMsg.CRLF;
}
$oBuff->Shut();
return $ok;
}
// ++ ACTION: internal ++ //
// -- ACTION -- //
// ++ OBJECTS ++ //
private $osNative;
protected function QNative() : QObjIface { return $this->osNative ?? ($this->osNative = QObjClass::AsNew()); }
// -- OBJECTS -- //
}
2025-09-25
- 2025-06-09 These need to be enabled by a "tunnel" mode or something. Otherwise, we're using CLI.
- 2025-06-10 Actually, these don't belong here at all; moved to Conn class (I was confused...) and commented out.
#
public function ActualOpen() : ActionIface {
$oa = new ($this->ActionClass()); // result object
$oSock = $this->OSock();
$oConn = $oSock->OPlug();
$oConn->Open();
$oCred = $oConn->Cred();
#echo $oCred->ReflectThis()->Report();
// 2025-06-03 This will need updating.
$onDB = new mysqli(
$oSock->OHost->SAddr(),
$oCred->QSUser()->GetIt(),
$oCred->QSPass()->GetIt(),
$oCred->QSSchema()->GetItNz(),
$oCred->QIPort()->GetItNz(),
); // open the connection natively
if (is_object($onDB)) {
$oa->SetOkay(TRUE);
$this->QNative()->SetIt($onDB);
} else {
// 2022-01-26 probably want a method to do all this
$oa->SetOkay(FALSE);
$oa->SetNumber($this->ErrorNumner());
$oa->AddMsgString($this->ErrorMessage());
}
return $oa;
}
public function ActualShut() : ActionIface {
// close endpoint-to-engine connection
$ok = $this->QNative()->GetIt()->close();
// close code-to-endpoint connection
$this->OSock()->OConn()->Shut();
$oAct = new ($this->ActionClass());
$oAct->SetOkay($ok);
return $oAct;
}