void CEsperEngine::MsgEsperRead (const SArchonMessage &Msg) // MsgEsperRead // // Requests a read on the given connection. If we fail, we return an error // to the caller. { CDatum dConnection = Msg.dPayload.GetElement(0); CString sError; if (!m_Connections.BeginRead(Msg, dConnection, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_READ_FAILED, sError), Msg); if (m_bLogTrace) LogTrace(strPattern("[%x] Read failed: %s", CEsperInterface::ConnectionToFriendlyID(dConnection), sError)); return; } #ifdef DEBUG_SOCKET_OPS if (m_bLogTrace) LogTrace(strPattern("[%x] Read", CEsperInterface::ConnectionToFriendlyID(dConnection))); #endif // We reply when the async operation completes (or we get an error). }
void CEsperEngine::MsgEsperWrite (const SArchonMessage &Msg) // MsgEsperWrite // // Requests a write on the given connection. { CDatum dConnection = Msg.dPayload.GetElement(0); const CString &sData = Msg.dPayload.GetElement(1); CString sError; if (!m_Connections.BeginWrite(Msg, dConnection, sData, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_WRITE_FAILED, sError), Msg); if (m_bLogTrace) LogTrace(strPattern("[%x] Write failed (%d bytes): %s", CEsperInterface::ConnectionToFriendlyID(dConnection), sData.GetLength(), sError)); return; } #ifdef DEBUG_SOCKET_OPS if (m_bLogTrace) LogTrace(strPattern("[%x] Write %d bytes", CEsperInterface::ConnectionToFriendlyID(dConnection), sData.GetLength())); #endif // We reply when the async operation completes (or we get an error). }
bool CHyperionScheduler::IsSignalStop (const CString &sTask, CString *retsMessage) // IsSignalStop // // Returns TRUE if the task has been signalled to stop. { CSmartLock Lock(m_cs); STask *pTask = m_Tasks.GetAt(sTask); if (pTask == NULL || !pTask->bRunning) return false; // If the user signalled stop, then we should stop if (pTask->bSignalStop) { if (retsMessage) *retsMessage = strPattern(ERR_RUN_STOPPED, sTask); return true; } // If the task has exceeded its max run time, then stop it. CDateTime Now(CDateTime::Now); CDateTime StopAt = timeAddTime(pTask->LastRun, CTimeSpan(0, MAX_RUN_TIME)); if (StopAt <= Now) { if (retsMessage) *retsMessage = strPattern(ERR_RUN_TOO_LONG, sTask); return true; } // Otherwise, stop is not signalled return false; }
void CAeonEngine::MsgFileDirectory (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgFileDirectory // // Aeon.fileDirectory {filePath} {requestedFields} {options} { CString sError; // Get the filePath CString sTable; CString sFilePath; if (!CAeonTable::ParseFilePath(Msg.dPayload.GetElement(0), &sTable, &sFilePath, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_PARSING_FILE_PATH, sError), Msg); return; } // Make sure we are allowed access to this table if (!ValidateTableAccess(Msg, pSecurityCtx, sTable)) return; // Convert the filepath to a key CString sDirKey = CRowKey::FilePathToKey(sFilePath); // Get the table CAeonTable *pTable; if (!FindTable(sTable, &pTable)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return; } // Get the set of requested fields and options CDatum dRequestedFields = Msg.dPayload.GetElement(1); CDatum dOptions = Msg.dPayload.GetElement(2); // Do it CDatum dResult; if (!pTable->FileDirectory(sDirKey, dRequestedFields, dOptions, &dResult, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Reply SendMessageReply(MSG_REPLY_DATA, dResult, Msg); }
void CAeonEngine::MsgFileGetDesc (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgFileGetDesc // // Aeon.fileGetDesc {filePath} { CString sError; // Get the filePath CString sTable; CString sFilePath; if (!CAeonTable::ParseFilePath(Msg.dPayload.GetElement(0), &sTable, &sFilePath, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_PARSING_FILE_PATH, sError), Msg); return; } // Make sure we are allowed access to this table if (!ValidateTableAccess(Msg, pSecurityCtx, sTable)) return; // Get the table CAeonTable *pTable; if (!FindTable(sTable, &pTable)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return; } // Get the descriptor CDatum dFileDesc; if (!pTable->GetFileDesc(sFilePath, &dFileDesc, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Prepare the descriptor for return CDatum dNewFileDesc = CAeonTable::PrepareFileDesc(sTable, sFilePath, dFileDesc); // Done SendMessageReply(MSG_REPLY_DATA, dNewFileDesc, Msg); }
bool CAeonEngine::GetKeyRange (const SArchonMessage &Msg, const CString &sTable, int iCount) // GetKeyRange // // Processes a getKeyRange message { // If the table doesn't exist, then we can't continue CAeonTable *pTable; if (!FindTable(sTable, &pTable)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return false; } // Create an iterator CDatum dResult; CString sError; if (!pTable->GetKeyRange(iCount, &dResult, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return false; } // Reply SendMessageReply(MSG_AEON_RESULT_KEYS, dResult, Msg); return true; }
bool CAeonEngine::FlushTableRows (void) // FlushTableRows // // Save all in-memory rows to disk { int i; // Get a list of all tables TArray<CAeonTable *> AllTables; GetTables(&AllTables); // Loop over each table bool bAllSucceeded = true; for (i = 0; i < AllTables.GetCount(); i++) { CString sError; if (!AllTables[i]->Save(&sError)) { Log(MSG_LOG_ERROR, strPattern("Unable to save table %s: %s", AllTables[i]->GetName(), sError)); bAllSucceeded = false; // Continue saving other tables } } // Done return bAllSucceeded; }
bool CAeonEngine::ValidateTableAccess (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx, const CString &sTable) // ValidateTableAccess // // Returns TRUE if the security context allows access to the given table. { // If we're not ready, then error if (!m_bReady) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_NOT_READY, Msg); return false; } // Make sure we have access if (pSecurityCtx && !pSecurityCtx->IsNamespaceAccessible(sTable)) { SendMessageReplyError(MSG_ERROR_NOT_ALLOWED, strPattern(ERR_NOT_IN_SANDBOX, sTable, pSecurityCtx->GetSandboxName()), Msg); return false; } return true; }
bool CHexeMarkupEvaluator::ProcessEval (SHTTPRequestCtx &Ctx, TagTypes iDirective, const CString &sCode) // ProcessEval // // Process an evaluation. { // Remember what we're processing in case we need RPC. m_iProcessing = iDirective; // Compile the body into a function call CDatum dCode; CString sError; if (!CHexeDocument::ParseLispExpression(sCode, &dCode, &sError)) { m_Output.Write(strPattern("ERROR: %s", sError)); return true; } // Run CDatum dResult; CHexeProcess::ERunCodes iRun = m_pProcess->Run(dCode, &dResult); // Process the result if (!ProcessResult(Ctx, iRun, dResult)) return false; // Done return true; }
void CMnemosynthDb::RemoveMachineEndpoints (const CString &sName) // RemoveMachineEndpoints // // Removes all endpoints for the given machine. { CSmartLock Lock(m_cs); int i; // Look for endpoints that start with the machine name CString sPattern = strPattern("%s/", sName); // Delete them. We always start at 1 because the first endpoint is us // and can never be deleted. for (i = 1; i < m_Endpoints.GetCount(); i++) if (strStartsWith(m_Endpoints[i].sName, sPattern)) { #ifdef DEBUG_MNEMOSYNTH printf("[CMnemosynthDb::RemoveMachineEndpoints]: Remove %s\n", (LPSTR)m_Endpoints[i].sName); #endif m_Endpoints.Delete(i); i--; } }
bool CHyperionScheduler::SetSignalStop (const CString &sTask, CString *retsError) // SetSignalStop // // Tells the task to stop running. { CSmartLock Lock(m_cs); STask *pTask = m_Tasks.GetAt(sTask); if (pTask == NULL) { if (retsError) *retsError = strPattern(ERR_UNKNOWN_TASK, sTask); return false; } // If we're not running, then nothing to do. if (!pTask->bRunning) return true; // Set the state pTask->bSignalStop = true; return true; }
void CBlackBox::Log (const CString &sLine) // Log // // Log a line { CDateTime Now(CDateTime::Now); CString sOutput = strPattern("%s %s\r\n", Now.Format(CDateTime::dfShort, CDateTime::tfLong24), sLine); if (m_File.IsOpen()) { int iWritten = m_File.Write(sOutput); // LATER: Handle out of disk space // In Debug mode, we always output. #ifdef DEBUG printf(sOutput); #endif } else if (m_bConsoleOut) { // Write out to console // NOTE: We rely on the fact that we called SetConsoleOutputCP(65001), // which is UTF8. printf(sOutput); } }
void CEsperEngine::DeleteListener (const SArchonMessage &Msg) // DeleteListener // // Deletes the listener { CSmartLock Lock(m_cs); // Get the name CString sName = Msg.dPayload.GetElement(0); // Find the listener int iIndex; if (!FindListener(sName, &iIndex)) { // If we're in shutdown, then it is OK that we can't find // a listener. Otherwise we return an error if (!m_bShutdown) SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_LISTENER_NOT_FOUND, sName), Msg); return; } // Ask the listener to stop m_Listeners[iIndex]->SignalShutdown(); // Done (we will reply when the thread shuts down) }
void CEsperEngine::MsgEsperAMP1 (const SArchonMessage &Msg) // MsgEsperAMP1 // // Esper.amp1 {machine-address} {command} {data} { CString sFullAddress = Msg.dPayload.GetElement(0); CString sCommand = Msg.dPayload.GetElement(1); CDatum dData = Msg.dPayload.GetElement(2); CString sAuthName = Msg.dPayload.GetElement(3); CIPInteger AuthKey = Msg.dPayload.GetElement(4); // Don't log, because we might recurse when sending a log message #if 0 #ifdef DEBUG Log(MSG_LOG_DEBUG, strPattern("Send AMP1 %s to %s.", sCommand, sFullAddress)); #endif #endif CString sError; if (!m_Connections.BeginAMP1Request(Msg, sFullAddress, sCommand, dData, sAuthName, AuthKey, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // We reply when the async operation completes (or we get an error). }
CString CAeonInterface::EncodeFilePathComponent (const CString &sValue) // EncodeFilePathComponent // // Encodes a file path component by replacing any invalid characters with ~hh // (where hh is the hexcode). { char *pPos = sValue.GetParsePointer(); char *pEndPos = pPos + sValue.GetLength(); CStringBuffer Output; while (pPos < pEndPos) { if (!strIsASCIIAlpha(pPos) // alpha && !strIsDigit(pPos) // numbers && *pPos != '-' && *pPos != '_' && *pPos != '.' && *pPos != '~' && !strIsASCIIHigh(pPos)) // unicode characters { CString sChar = strPattern("~%x", (DWORD)(BYTE)*pPos); Output.Write(sChar); } else Output.Write(pPos, 1); pPos++; } // Done return CString::CreateFromHandoff(Output); }
bool CXMLElement::ParseEntityTable (IMemoryBlock &Stream, CExternalEntityTable *retEntityTable, CString *retsError) // ParseEntityTable // // This function parses only the entity table { // Initialize context ParserCtx Ctx(Stream, NULL); // Parse the prologue if (!ParsePrologue(&Ctx)) { *retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError); return false; } // Done if (retEntityTable) retEntityTable->AddTable(Ctx.EntityTable); return true; }
void CBlackBox::Boot (const CString &sPath) // Boot // // Prepare the log file { ASSERT(!m_File.IsOpen()); // Generate a filename using the current date and time CDateTime Now(CDateTime::Now); CString sFilename = strPattern("BlackBox_%04d%02d%02d_%02d%02d%02d.log", Now.Year(), Now.Month(), Now.Day(), Now.Hour(), Now.Minute(), Now.Second()); // Create the file CString sError; if (!m_File.Create(fileAppend(sPath, sFilename), CFile::FLAG_CREATE_ALWAYS, &sError)) // LATER: Handle error somehow. NULL; }
bool CCryptosaurEngine::ValidateAuthDescCreate (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx, CDatum dAuthDesc) // ValidateAuthDescCreate // // Make sure that the authDesc structure has the proper fields for creating // a new user (either admin or not). { if (!strEquals(dAuthDesc.GetElement(FIELD_TYPE), AUTH_TYPE_SHA1)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(ERR_INVALID_AUTHDESC_TYPE, dAuthDesc.GetElement(FIELD_TYPE).AsString()), Msg); return false; } if (dAuthDesc.GetElement(FIELD_CREDENTIALS).IsNil()) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_AUTHDESC_CREDENTIALS_REQUIRED, Msg); return false; } if (dAuthDesc.GetElement(FIELD_ACTUAL).IsNil()) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, ERR_AUTHDESC_ACTUAL_REQUIRED, Msg); return false; } return true; }
bool CXMLElement::ParseXML (IMemoryBlock &Stream, IXMLParserController *pController, CXMLElement **retpElement, CString *retsError, CExternalEntityTable *retEntityTable) // ParseXML // // Parses the block and returns an XML element { // Initialize context ParserCtx Ctx(Stream, pController); // Parse the prologue if (!ParsePrologue(&Ctx)) { *retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError); return false; } // Next token must be an element open tag if (Ctx.iToken != tkTagOpen) { *retsError = strPattern("Line(%d): root element expected.", Ctx.iLine); return false; } // Parse the root element if (!ParseElement(&Ctx, retpElement)) { *retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError); return false; } // Done if (retEntityTable) retEntityTable->AddTable(Ctx.EntityTable); return true; }
void CAeonEngine::MsgMutate (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgMutate // // Aeon.mutate {tableName} {rowPath} {data} {mutationDesc} { AEONERR error; const CString &sTable = Msg.dPayload.GetElement(0); CDatum dRowPath = Msg.dPayload.GetElement(1); CDatum dData = Msg.dPayload.GetElement(2); CDatum dMutateDesc = Msg.dPayload.GetElement(3); // Make sure we are allowed access to this table if (!ValidateTableAccess(Msg, pSecurityCtx, sTable)) return; // If the table doesn't exist, then we can't continue CAeonTable *pTable; if (!FindTable(sTable, &pTable)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return; } // Parse the path // // NOTE: We don't need to validate that this is a valid path for create // because we do that later inside Mutate. [Because Mutate accepts a nil // path when generating a unique key.] CString sError; CRowKey Path; if (!pTable->ParseDimensionPath(NULL_STR, dRowPath, &Path, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Mutate CDatum dResult; if (error = pTable->Mutate(Path, dData, dMutateDesc, &dResult, &sError)) { if (error == AEONERR_OUT_OF_DATE) SendMessageReplyError(MSG_ERROR_OUT_OF_DATE, sError, Msg); else SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Done SendMessageReply(MSG_REPLY_DATA, dResult, Msg); }
void CComplexDateTime::Serialize (CDatum::ESerializationFormats iFormat, IByteStream &Stream) const // Serialize // // Serialize to the given format. { switch (iFormat) { case CDatum::formatAEONScript: case CDatum::formatAEONLocal: { CString sDate = strPattern("#%d-%02d-%02dT%02d:%02d:%02d.%04d", m_DateTime.Year(), m_DateTime.Month(), m_DateTime.Day(), m_DateTime.Hour(), m_DateTime.Minute(), m_DateTime.Second(), m_DateTime.Millisecond()); Stream.Write(sDate); break; } case CDatum::formatJSON: { CString sDate = strPattern("\"%d-%02d-%02dT%02d:%02d:%02d.%04d\"", m_DateTime.Year(), m_DateTime.Month(), m_DateTime.Day(), m_DateTime.Hour(), m_DateTime.Minute(), m_DateTime.Second(), m_DateTime.Millisecond()); Stream.Write(sDate); break; } default: IComplexDatum::Serialize(iFormat, Stream); break; } }
CString CAeonInterface::CreateTableFilePath (const CString &sTable, const CString &sFilePath) // CreateTableFilePath // // Composes a full filepath. { return strPattern("/%s/%s", sTable, sFilePath); }
CString CMnemosynthDb::GenerateEndpointName (const CString &sMachine, const CString &sModule) // GenerateEndpointName // // Generates an endpoint name from machine and module { return strPattern("%s/%s", sMachine, sModule); }
bool CArchonProcess::SendMessage (const CString &sAddress, const SArchonMessage &Msg) // SendMessage // // Sends a message to the given address. If we fail, we reply as appropriate. { bool bSuccess; CMessagePort *pPort = Bind(sAddress); if (pPort) { bSuccess = pPort->SendMessage(Msg); } else { Log(MSG_LOG_ERROR, strPattern(ERR_CANT_BIND, sAddress)); bSuccess = false; } // If we failed to send the message, then we might want to reply to the // client. if (!bSuccess) { // If this is a notification port then we ignore the error (it just // means that no one is listening). if (!strEndsWith(sAddress, STR_NOTIFY_SUFFIX) && !strStartsWith(Msg.sMsg, MSG_ERROR_PREFIX)) { // Reply to client, if necessary if (!CMessagePort::IsNullAddr(Msg.sReplyAddr)) SendMessageCommand(Msg.sReplyAddr, MSG_ERROR_UNABLE_TO_COMPLY, NULL_STR, Msg.dwTicket, CDatum(strPattern(ERR_CANT_SEND_TO, sAddress))); else Log(MSG_LOG_ERROR, strPattern("Failed sending message to: %s.", sAddress)); } } // Done return bSuccess; }
bool CDatum::CreateFromFile (const CString &sFilespec, ESerializationFormats iFormat, CDatum *retdDatum, CString *retsError) // CreateFromFile // // Loads a datum from a file. { // Open the file CFileBuffer theFile; if (!theFile.OpenReadOnly(sFilespec)) { *retsError = strPattern(ERR_CANT_OPEN_FILE, sFilespec); return false; } // If unknown format, see if we can detect the format if (iFormat == formatUnknown) { if (!DetectFileFormat(sFilespec, theFile, &iFormat, retsError)) return false; // If format unknown, then error. if (iFormat == formatUnknown) { *retsError = strPattern(ERR_UNKNOWN_FORMAT, sFilespec); return false; } } // Parse it if (!Deserialize(iFormat, theFile, retdDatum)) { *retsError = strPattern(ERR_DESERIALIZE_ERROR, sFilespec); return false; } // Done return true; }
bool CXMLElement::ParseRootElement (IMemoryBlock &Stream, CXMLElement **retpRoot, CExternalEntityTable *retEntityTable, CString *retsError) // ParseRootElement // // Parses the entity definitions and the root element (but not the contents // of the root element). { // Initialize context ParserCtx Ctx(Stream, NULL); // Parse the prologue if (!ParsePrologue(&Ctx)) { *retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError); return false; } // Next token must be an element open tag if (Ctx.iToken != tkTagOpen) { *retsError = strPattern("Line(%d): Root element expected.", Ctx.iLine); return false; } // Parse the root element Ctx.m_bParseRootElement = true; if (!ParseElement(&Ctx, retpRoot)) { *retsError = strPattern("Line(%d): %s", Ctx.iLine, Ctx.sError); return false; } // Done if (retEntityTable) retEntityTable->AddTable(Ctx.EntityTable); return true; }
bool CHexeMarkupEvaluator::EvalInit (SHTTPRequestCtx &Ctx, const CHexeProcess &ProcessTemplate, const CHexeSecurityCtx &SecurityCtx, const TArray<CDatum> &HexeDefinitions, CDatum dFileDesc, CDatum dData) // EvalInit // // Initializes evaluation. Return TRUE if the message is ready; FALSE if we // need to wait for an RPC result. { CleanUp(); // Initialize the process that we'll use for evaluation m_pProcess = new CHexeProcess; // Clone from the template m_pProcess->InitFrom(ProcessTemplate); // Set some context m_pProcess->SetLibraryCtx(LIBRARY_HYPERION, Ctx.pSession->GetEngine()); m_pProcess->SetLibraryCtx(LIBRARY_SESSION, Ctx.pSession); m_pProcess->SetLibraryCtx(LIBRARY_SESSION_HTTP_BODY_BUILDER, &Ctx.BodyBuilder); m_pProcess->SetLibraryCtx(LIBRARY_SESSION_HTTP_REQUEST, &Ctx.Request); m_pProcess->SetSecurityCtx(SecurityCtx); // Definitions CString sError; if (!m_pProcess->LoadHexeDefinitions(HexeDefinitions, &sError)) { m_Output.Write(strPattern("<!DOCTYPE html><html lang='en'><body><h1>%s</h1></body></html>", htmlWriteText(sError))); return ComposeResponse(Ctx); } // Initialize parsing const CString &sData = dData; m_Parser.Init(sData.GetParsePointer(), sData.GetLength()); // Initialize state m_iProcessing = tagNone; m_iIfLevel = 0; m_iIfLevelEnd = 0; // Parse until we need to process an RPC message return ParseUntilRPC(Ctx); }
void CArchonTimer::LogTime (IArchonProcessCtx *pProcess, const CString &sText, DWORDLONG dwMinTime) const // LogTime // // Logs a time { DWORDLONG dwTime = ::sysGetTicksElapsed(m_dwStart); if (dwTime >= dwMinTime) pProcess->Log(MSG_LOG_INFO, strPattern("%s (%s ms)", sText, strFormatInteger((int)dwTime, -1, FORMAT_THOUSAND_SEPARATOR))); }
void CAeonEngine::MsgInsertNew (const SArchonMessage &Msg, const CHexeSecurityCtx *pSecurityCtx) // MsgInsertNew // // Aeon.insertNew {tableName} {rowPath} {data} // // {rowPath} is an array with as many elements as the table dimensions { AEONERR error; const CString &sTable = Msg.dPayload.GetElement(0); CDatum dRowPath = Msg.dPayload.GetElement(1); CDatum dData = Msg.dPayload.GetElement(2); // Make sure we are allowed access to this table if (!ValidateTableAccess(Msg, pSecurityCtx, sTable)) return; // If the table doesn't exist, then we can't continue CAeonTable *pTable; if (!FindTable(sTable, &pTable)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, strPattern(STR_ERROR_UNKNOWN_TABLE, sTable), Msg); return; } // Parse the path CString sError; CRowKey Path; if (!pTable->ParseDimensionPathForCreate(dRowPath, &Path, &sError)) { SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Insert if (error = pTable->Insert(Path, dData, true, &sError)) { if (error == AEONERR_ALREADY_EXISTS) SendMessageReplyError(MSG_ERROR_ALREADY_EXISTS, sError, Msg); else SendMessageReplyError(MSG_ERROR_UNABLE_TO_COMPLY, sError, Msg); return; } // Done SendMessageReply(MSG_OK, CDatum(), Msg); }
bool CAeonEngine::OpenTableDefinitions (void) // OpenTableDefinitions // // Opens and reads all tables in all volumes. Note that we have no idea what // could have happened since our last boot--someone could have copied files // all over the place. We make almost no assumptions. { CSmartLock Lock(m_cs); int i, j; CString sError; // Loop over all volumes and end up with a list of tables and volumes TSortMap<CString, TArray<CString>> Tables; for (i = 0; i < m_LocalVolumes.GetCount(); i++) { CString sVolume = m_LocalVolumes.GetVolume(i); TArray<CString> Dirs; fileGetFileList(fileAppend(m_LocalVolumes.GetPath(i), FILESPEC_TABLE_DIR_FILTER), FFL_FLAG_DIRECTORIES_ONLY | FFL_FLAG_RELATIVE_FILESPEC, &Dirs); for (j = 0; j < Dirs.GetCount(); j++) { TArray<CString> *pList = Tables.SetAt(Dirs[j]); pList->Insert(sVolume); } } // Open all tables for (i = 0; i < Tables.GetCount(); i++) { CString sName = Tables.GetKey(i); CAeonTable *pTable = new CAeonTable; if (!pTable->Open(GetProcessCtx(), &m_LocalVolumes, sName, Tables[i], &sError)) { Log(MSG_LOG_ERROR, strPattern("Unable to load %s: %s", sName, sError)); delete pTable; continue; } m_Tables.Insert(sName, pTable); } // Done return true; }