Run a single Exec command. Commands are placed within <procdata> tags, which can appear in <xform> and <page>
| Return Type | Function name | Arguments |
|---|---|---|
| hzEcode | hdsExec::Exec | (hzChain&,hzHttpEvent*,) |
Declared in file: hzDissemino.h
Defined in file : hdsExec.cpp
Function Logic:
Function body:
hzEcode hdsExec::Exec (hzChain& errorReport)hzHttpEvent* pE,
{
// Run a single Exec command. Commands are placed within <procdata> tags, which can appear in <xform> and <page>
//
// Arguments: 1) error The error report chain
// 2) pE The HTTP event pointer
_hzfunc("hdsExec::Exec") ;
const hdbClass* pClass ; // Data class
const hdbMember* pMbr ; // Data class member
ifstream is ; // For data import
hdbObject* pCurObj ; // Single data class instance
hzAtom atom ; // Atom for fetching values
hzChain bval ; // Document or binary (if applicable)
hdbObjRepos* pRepos ; // Target repository
hdsInfo* pInfo ; // Session
hdbObject* pObj ; // Standalone object pointer (either that vested with the HTTP event or the user session)
hzString param1 ; // 1st parameter
hzString param2 ; // 2nd parameter
hzString param3 ; // 3rd parameter
hzString param4 ; // 4th parameter
hzString param5 ; // 5th parameter
hzString param6 ; // 6th parameter
hzString strVal ; // Used to derive real value of the step's input when specified as a variable name instead of a literal
hzString S ; // Temp string
hzString a ; // Content of parameter 1
hzString b ; // Content of parameter 2
// hdsUsertype utype ; // User type (for loging in)
// uint32_t n ; // Object value iterator
uint32_t objId = 0; // Object id
hzEcode rc = E_OK ; // Return code
if (!pE)
Fatal("%s. No HTTP event supplied\n", __func__) ;
// Obtain user session if any
pInfo = (hdsInfo*) pE->Session() ;
threadLog("%s Commencing with info %p -> ", Exec2Txt(m_Command), pInfo) ;
errorReport.Printf("%s Commencing with info %p -> ", Exec2Txt(m_Command), pInfo) ;
switch (m_Command)
{
case EXEC_SENDEMAIL: // Send an email. Params are sender, recipient, subject and msg.
rc = SendEmail(errorReport, pE) ;
break ;
case EXEC_SETVAR: if (!pInfo)
{ errorReport.Printf("EXEC_SETVAR No session in place\n") ; return E_CORRUPT ; }
// Get the value
param2 = m_pApp->m_ExecParams[m_FstParam+1];
if (param2[0]== CHAR_PERCENT)
rc = m_pApp->PcEntConv(atom, param2, pE) ;
else
rc = atom.SetValue(m_type, param2) ;
// Get the name
param1 = m_pApp->m_ExecParams[m_FstParam] ;
if (!pInfo->m_Sessvals.Exists(param1))
pInfo->m_Sessvals.Insert(param1, atom) ;
else
pInfo->m_Sessvals[param1] = atom ;
break ;
case EXEC_ADDUSER: // Explicitly create a new user as an executive step. See hdsExec::Adduser()
rc = Adduser(errorReport, pE) ;
break ;
case EXEC_LOGON: // Log a user in as admin. This is done without password checking. As the supplied m_Uname parameter is always a percent entity,
// this must be evaluated before use.
rc = Logon(errorReport, pE) ;
break ;
case EXEC_TEST: // Tests if a condition is true. Currently limited to testing if two parameters are equal
param1 = m_pApp->m_ExecParams[m_FstParam] ;
param2 = m_pApp->m_ExecParams[m_FstParam+1];
a = m_pApp->ConvertText(param1, pE) ;
b = m_pApp->ConvertText(param2, pE) ;
if (a == b)
errorReport.Printf("exec test OK: a = %s, b = %s\n", *a, *b) ;
else
{
errorReport.Printf("exec test FAIL: a = %s, b = %s\n", *a, *b) ;
rc = E_NOTFOUND ;
}
break ;
case EXEC_EXTRACT: // Perform a text extraction. The scenario will be that the input will be a file bound to the event (e.g. a file upload in a form
// submission). The m_Input member will name the field carrying the file.
rc = Extract(errorReport, pE) ;
break ;
case EXEC_OBJ_TEMP: // Create a temporary hdbObject and vest with the HTTP event (m_pContextObj)
param1 = m_pApp->m_ExecParams[m_FstParam] ;
param2 = m_pApp->m_ExecParams[m_FstParam+1];
threadLog("Got exec params of %s and %s\n", *param1, *param2) ;
pClass = m_pApp->m_ADP.GetPureClass(param2) ;
if (!pClass)
{ errorReport.Printf("EXEC_OBJ_TEMP FAIL: No such class as %s\n", *param2) ; rc = E_NOTFOUND ; break ; }
if (pE->m_pContextObj)
{ errorReport.Printf("EXEC_OBJ_TEMP FAIL: Already a temp object\n") ; rc = E_NOTFOUND ; break ; }
pE->m_pContextObj = pObj = new hdbObject() ;
pObj->Init(pClass) ;
pObj->SetName(param1) ;
errorReport.Printf("EXEC_OBJ_TEMP: Allocated a temp object of %s\n", *param1) ;
break ;
case EXEC_OBJ_START: // Assert the current user session object. This either finds the current object as null and sets it, or finds the right object in
// place. If the current object is not the right one, this is an error.
if (!pInfo)
{ errorReport.Printf("EXEC_OBJ_START FAIL: No user session\n") ; rc = E_NOINIT ; break ; }
threadLog("Got exec param of %d\n", m_FstParam) ;
param1 = m_pApp->m_ExecParams[m_FstParam] ;
threadLog("Got exec param of %d\n", m_FstParam) ;
threadLog("Got exec param of %s\n", *param1) ;
param2 = m_pApp->m_ExecParams[m_FstParam+1];
threadLog("Got exec param of %s\n", *param2) ;
pClass = m_pApp->m_ADP.GetPureClass(param2) ;
pInfo->ObjectAssert(param1, pClass) ; // m_pApp->m_SObj2Class[param1]) ;
break ;
case EXEC_OBJ_FETCH: // Load the current user session object from a repository
case EXEC_OBJ_IMPORT: // Load the current user session object from a JSON file
case EXEC_OBJ_EXPORT: // Save the current user session object to a JSON file
case EXEC_OBJ_SETMBR: // Set a data class member within the current object. The params are repository name, class name, member name and the data source.
case EXEC_OBJ_COMMIT: // Commit data in the named hdbObject instance (param1) to the named repository (param2). An object id of 0 effects an INSERT while
case EXEC_OBJ_CLOSE: // Closes the current user session object.
// First obtain existing user session or temp object
param1 = m_pApp->m_ExecParams[m_FstParam] ; // Object key
if (pE->m_pContextObj)
pCurObj = (hdbObject*) pE->m_pContextObj ;
else
{
if (!pInfo)
{ errorReport.Printf("%s FAIL: No user session\n", Exec2Txt(m_Command)) ; rc = E_NOINIT ; break ; }
pCurObj = pInfo->ObjectSelect(param1) ;
pCurObj = pInfo->m_pObj ;
if (!pInfo->m_pObj)
{ errorReport.Printf("%s FAIL: No current object\n", Exec2Txt(m_Command)) ; rc = E_NOINIT ; break ; }
}
// Then switch again on these object commands
switch (m_Command)
{
case EXEC_OBJ_FETCH: // Load the current user session object from a repository
break ;
case EXEC_OBJ_IMPORT: // Load the current user session object from a JSON file
param2 = m_pApp->m_ExecParams[m_FstParam+1]; // Source file name
strVal = m_pApp->ConvertText(param2, pE) ;
if (rc != E_OK)
{ errorReport.Printf("%s FAIL: String %s could not be converted\n", Exec2Txt(m_Command), *param2) ; rc = E_OPENFAIL ; break ; }
is.open(*strVal) ;
if (is.fail())
{ errorReport.Printf("%s FAIL: File %s could not be opened\n", Exec2Txt(m_Command), *strVal) ; ; rc = E_OPENFAIL ; break ; }
bval << is ;
is.close() ;
pCurObj->ImportJSON(bval) ;
break ;
case EXEC_OBJ_EXPORT: // Save the current user session object to a JSON file
param2 = m_pApp->m_ExecParams[m_FstParam+1]; // Traget file name
break ;
case EXEC_OBJ_SETMBR: // Set a data class member within the current object. The params are repository name, class name, member name and the data source.
param2 = m_pApp->m_ExecParams[m_FstParam+1]; // Class name
param3 = m_pApp->m_ExecParams[m_FstParam+2]; // Member name
param4 = m_pApp->m_ExecParams[m_FstParam+3]; // Data source
pClass = m_pApp->m_ADP.GetPureClass(param2) ;
if (!pClass)
{ errorReport.Printf("EXEC_OBJ_SETMBR FAIL: No such class as %s\n", *param2) ; rc = E_NOTFOUND ; break ; }
pMbr = pClass->GetMember(param3) ;
if (!pMbr)
{ errorReport.Printf("EXEC_OBJ_SETMBR FAIL: Class %s has no member of %s\n", *param2, *param3) ; rc = E_NOTFOUND ; break ; }
switch (pMbr->Basetype())
{
case BASETYPE_TXTDOC:
case BASETYPE_BINARY:
// The step is to set the object's member to the file content. The filename is got from the step input (naming the event variable) and
// from there, we lookup the actual file content in the event
if (pE->m_Uploads.Exists(param4))
{
hzHttpFile hf ; // External document/binary file
hf = pE->m_Uploads[param4] ;
strVal = m_pApp->ConvertText(param4, pE) ;
errorReport.Printf("Step %s=%s (fld %s file %s of %d bytes) mime=%d\n", *param3, *param4, *hf.m_fldname, *hf.m_filename, hf.m_file.Size(), hf.m_mime) ;
// rc = pCurObj->SetBinary(param3, hf.m_file) ;
rc = pCurObj->SetBinary(pMbr, hf.m_file) ;
}
if (pE->m_mapChains.Exists(param4))
{
bval = pE->m_mapChains[param4] ;
strVal.Clear() ;
errorReport.Printf("Step %s=%s (chain %d bytes)\n", *param3, *param4, bval.Size()) ;
// rc = pCurObj->SetBinary(param3, bval) ;
rc = pCurObj->SetBinary(pMbr, bval) ;
}
break ;
case BASETYPE_EMADDR:
case BASETYPE_URL:
case BASETYPE_STRING:
strVal = m_pApp->ConvertText(param4, pE) ;
errorReport.Printf("Strlike Step %s = %s (%s)\n", *param3, *param4, *strVal) ;
// rc = pCurObj->SetValue(pMbr->Posn(), strVal) ;
atom = strVal ;
rc = pCurObj->SetValue(pMbr, atom) ;
break ;
default: // Deal with num-like or numeric values
rc = m_pApp->PcEntConv(atom, param4, pE) ;
errorReport.Printf("Numlike Step %s = %s (%s)\n", *param3, *param4, atom.Show()) ;
// rc = pCurObj->SetValue(pMbr->Posn(), atom) ;
rc = pCurObj->SetValue(pMbr, atom) ;
break ;
}
break ;
case EXEC_OBJ_COMMIT: // Commit data in the named hdbObject instance (param1) to the named repository (param2). An object id of 0 effects an INSERT while
// a non-zero object id effects an UPDATE. The object id is derived from @resarg and is foud at this juncture by ....
if (!pCurObj)
{ errorReport.Printf("EXEC_OBJ_COMMIT FAIL: No current object\n") ; rc = E_NOINIT ; break ; }
pRepos = m_pApp->m_ADP.GetObjRepos(pCurObj->ReposId()) ;
if (!pRepos)
{ errorReport.Printf("EXEC_OBJ_COMMIT FAIL: Object %s No repository\n", *param1) ; rc = E_NOINIT ; break ; }
if (pCurObj->GetObjId())
rc = pRepos->Update(*pCurObj, pCurObj->GetObjId()) ;
else
rc = pRepos->Insert(objId, *pCurObj) ;
// Error?
if (rc != E_OK)
errorReport.Printf("EXEC_OBJ_COMMIT FAIL: Insert/Modify on repository of %s failed with error %s\n", *param2, Err2Txt(rc)) ;
break ;
case EXEC_OBJ_CLOSE: // Closes the current user session object.
break ;
}
break ;
// Tree Operations
case EXEC_TREE_DCL: // Declare a private tree and place it in the user session. This will have no effect if the user session already has the tree which
// is identified by name. If there is a different tree in the session, it will be deleted and replaced with the requested tree.
if (!pInfo)
{ errorReport.Printf("EXEC_TREE_DCL FAIL. No user session\n") ; return E_NOTFOUND ; }
param1 = m_pApp->m_ExecParams[m_FstParam] ; // Tree id
// param2 = m_pApp->m_ExecParams[m_FstParam+1] ; // Tree to copy (if applicable)
// Session has pvt tree?
if (pInfo->m_pTree)
{
if (pInfo->m_pTree->m_Groupname == param1)
break ;
delete pInfo->m_pTree ;
}
pInfo->m_pTree = new hdsNavtree() ;
pInfo->m_pTree->m_Groupname = param1 ;
threadLog("SET tree %s in session %p\n", *pInfo->m_pTree->m_Groupname, pInfo) ;
break ;
/*
** case EXEC_TREE_CPY: // If the current user session tree is empty, copy headings from the named public tree (if supplied) and copy entries from a source
** // object (if supplied). This command can only apply to the current user session tree. If this is not present or does not have the
** // supplied id, this is an error. The command will do nothing if the current user session tree is not empty. It is for initializing
** // values only.
**
** if (!pInfo)
** { errorReport.Printf("EXEC_TREE_CPY FAIL. No user session\n") ; return E_NOTFOUND ; }
**
** param1 = m_pApp->m_ExecParams[m_FstParam] ; // Tree id
** param2 = m_pApp->m_ExecParams[m_FstParam+1] ; // Tree to copy (if applicable)
** param3 = m_pApp->m_ExecParams[m_FstParam+2] ; // Object to copy (if applicable)
**
** // Check source tree if supplied
** if (param2)
** {
** pTree = m_pApp->m_ArticleGroups[param2] ;
** if (!pTree)
** { errorReport.Printf("EXEC_TREE_CPY FAIL. Named source tree %s not found\n", *param2) ; return E_NOTFOUND ; }
** }
**
** // Check source object if supplied
** if (param3)
** {
** }
**
** if (pInfo->m_pTree->Count())
** break ;
** */
case EXEC_TREE_HEAD: // Add a heading to the tree if it does not already exist. A heading is an empty article with no link.
if (!pE)
Fatal("No HTTP event supplied\n") ;
pInfo = (hdsInfo*) pE->Session() ;
if (!pInfo)
{ errorReport.Printf("EXEC_TREEOP FAIL. No user session\n") ; return E_NOTFOUND ; }
if (!pInfo->m_pTree)
{ errorReport.Printf("EXEC_TREEOP FAIL. No user tree\n") ; return E_NOTFOUND ; }
param1 = m_pApp->m_ExecParams[m_FstParam] ; // Tree id
param2 = m_pApp->m_ExecParams[m_FstParam+1]; // Parent item id
param3 = m_pApp->m_ExecParams[m_FstParam+2]; // Refname
param4 = m_pApp->m_ExecParams[m_FstParam+3]; // Headline
if (pInfo->m_pTree->m_Groupname != param1)
{ errorReport.Printf("EXEC_TREEOP FAIL. Wrong tree\n") ; return E_NOTFOUND ; }
// If a parent tree item is stated, check it exists
if (param2 && !pInfo->m_pTree->Exists(param2))
{ errorReport.Printf("EXEC_TREEOP FAIL. Stated parent (%s) does not exist\n", *param2) ; return E_NOTFOUND ; }
// Then add/delete the new item(s)
pInfo->m_pTree->AddHead(param2, param3, param4, false) ;
break ;
case EXEC_TREE_ITEM: // Add an article to the tree if it does not already exist.
if (!pE)
Fatal("No HTTP event supplied\n") ;
pInfo = (hdsInfo*) pE->Session() ;
if (!pInfo)
{ errorReport.Printf("EXEC_TREEOP FAIL. No user session\n") ; return E_NOTFOUND ; }
if (!pInfo->m_pTree)
{ errorReport.Printf("EXEC_TREEOP FAIL. No user tree\n") ; return E_NOTFOUND ; }
param1 = m_pApp->m_ExecParams[m_FstParam] ; // Tree id
param2 = m_pApp->m_ExecParams[m_FstParam+1]; // Parent item id
param3 = m_pApp->m_ExecParams[m_FstParam+2]; // Refname
param4 = m_pApp->m_ExecParams[m_FstParam+3]; // Headline
if (pInfo->m_pTree->m_Groupname != param1)
{ errorReport.Printf("EXEC_TREEOP FAIL. Wrong tree\n") ; return E_NOTFOUND ; }
// If a parent tree item is stated, check it exists
if (param2 && !pInfo->m_pTree->Exists(param2))
{ errorReport.Printf("EXEC_TREEOP FAIL. Stated parent (%s) does not exist\n", *param2) ; return E_NOTFOUND ; }
// Then add/delete the new item(s)
// pArt = new hdsArticleStd() ;
pInfo->m_pTree->AddItem(param2, param3, param4, 0,false) ;
break ;
case EXEC_TREE_FORM: // Add a form to the tree as an article.
if (!pInfo) { errorReport.Printf("EXEC_TREEOP FAIL. No user session\n") ; return E_NOTFOUND ; }
if (!pInfo->m_pTree) { errorReport.Printf("EXEC_TREEOP FAIL. No user tree\n") ; return E_NOTFOUND ; }
param1 = m_pApp->m_ExecParams[m_FstParam] ; // Tree id
param2 = m_pApp->m_ExecParams[m_FstParam+1]; // Parent item id
param3 = m_pApp->m_ExecParams[m_FstParam+2]; // Refname
param4 = m_pApp->m_ExecParams[m_FstParam+3]; // Headline
param5 = m_pApp->m_ExecParams[m_FstParam+4]; // Form reference
param6 = m_pApp->m_ExecParams[m_FstParam+5]; // Data class context
if (pInfo->m_pTree->m_Groupname != param1)
{ errorReport.Printf("EXEC_TREEOP FAIL. Wrong tree\n") ; return E_NOTFOUND ; }
hdsArticleStd* pArt ; // Article
hdsFormref* pFormRef ; // Form reference
// Create article
pArt = new hdsArticleStd() ;
pArt->m_Refname = param3 ;
pArt->m_Title = param4 ;
pArt->m_bFlags |= HZ_TREEITEM_FORM ;
pArt->m_bFlags |= HZ_TREEITEM_LINK ;
// Add form reference to the article
pFormRef = new hdsFormref(0);
pFormRef->m_Formname = param5 ;
pArt->AddFormref(pFormRef) ;
pArt->AddVisent(pFormRef) ;
// Add article to the tree
pInfo->m_pTree->AddItem(param2, param3, param4, pArt, false) ;
break ;
case EXEC_TREE_SYNC: // Sync the tree to a standalone object.
/*
** if (!pE)
** Fatal("No HTTP event supplied\n") ;
** pInfo = (hdsInfo*) pE->Session() ;
**
** if (!pInfo)
** { errorReport.Printf("EXEC_TREEOP FAIL. No user session\n") ; return E_NOTFOUND ; }
**
** if (!pInfo->m_pTree)
** { errorReport.Printf("EXEC_TREEOP FAIL. No user tree\n") ; return E_NOTFOUND ; }
**
** param1 = m_pApp->m_ExecParams[m_FstParam] ; // Tree id
** param2 = m_pApp->m_ExecParams[m_FstParam+1] ; // Object id
**
** if (pInfo->m_pTree->m_Groupname != param1)
** { errorReport.Printf("EXEC_TREEOP FAIL. Wrong tree\n") ; return E_NOTFOUND ; }
**
** // Then obtain existing user session or temp object
** if (pE->m_pContextObj)
** pCurObj = (hdbObject*) pE->m_pContextObj ;
** else
** {
** if (!pInfo)
** { errorReport.Printf("%s FAIL: No user session\n", Exec2Txt(m_Command)) ; rc = E_NOINIT ; break ; }
**
** pCurObj = pInfo->ObjectSelect(param2) ;
** pCurObj = pInfo->m_pObj ;
**
** if (!pInfo->m_pObj)
** { errorReport.Printf("%s FAIL: No current object\n", Exec2Txt(m_Command)) ; rc = E_NOINIT ; break ; }
** }
**
** pInfo->m_pTree->Sync(*pCurObj) ;
** */
break ;
case EXEC_TREE_DEL: break ;
case EXEC_TREE_EXP: break ;
case EXEC_TREE_CLR: break ;
case EXEC_SRCH_PAGES: // Conduct a document search and provide a list of document ids found. The search will either be of an inbuilt resource such as the
// site's 'indigionous' pages (those defined as <xpage> in the config plus any passive pages), or it will be of a specified class.
rc = SrchPages(errorReport, pE) ;
break ;
case EXEC_SRCH_REPOS: // Conduct a search on a repository and provide a list of object ids found. The search will either be of an inbuilt resource such as the
// site's 'indigionous' pages (those defined as <xpage> in the config plus any passive pages), or it will be of a specified class.
rc = SrchRepos(errorReport, pE) ;
break ;
case EXEC_FILESYS: // Execute a filesystem command to create, delete or list a directory or to write out or read in a binary object to/from a file (as
// opposed to storing it in a repository.
rc = Filesys(errorReport, pE) ;
break ;
}
return rc ;
}