std::shared_ptr<Procedure> ProcedureController::CreateTemplateProcedure(qint32 projectTypeId, const QString &description)
{
    std::unique_ptr<Procedure> proc(new Procedure());
    proc->SetDescription(description);
    proc->SetProjectTypeId(projectTypeId);
    proc->SetTemplateProcedure(true);
    proc->SetPureTemplateProcedure(true);

    QSqlQuery insertProcedure = GetDb().CreateQuery();
    insertProcedure.prepare("INSERT INTO \"Procedure\" "
        "(\"Description\", \"ProjectTypeId\") "
        "VALUES(:description, :projectTypeId) "
        "RETURNING \"ProcedureId\";");
    insertProcedure.bindValue(":description", description);
    insertProcedure.bindValue(":projectTypeId", projectTypeId);
    if(!insertProcedure.exec())
    {
        return std::shared_ptr<Procedure>();
    }
    insertProcedure.next();

    qint32 procedureId = insertProcedure.value("ProcedureId").toInt();
    proc->SetProcedureId(procedureId);

    auto sharedPtr = std::shared_ptr<Procedure>(std::move(proc));
    ProcedureCacheKey key(ProcedureType::PT_PROJECT_TYPE, procedureId);
    AddProcedure(key, sharedPtr);

    emit sigProcedureAdded(*sharedPtr);
    AddProjectProceduresFromTemplate(procedureId);

    return sharedPtr;
}
std::vector<std::shared_ptr<Procedure>> ProcedureController::GetProceduresFromQuery(QSqlQuery &query, bool isTypeProcedure)
{
    std::vector<std::shared_ptr<Procedure>> result;

    if(!query.exec())
    {
        return result;
    }

    while(query.next())
    {
        auto newProc = std::unique_ptr<Procedure>(new Procedure());
        newProc->SetTemplateProcedure(!(query.value("ProjectTypeId").isNull()));
        newProc->SetPureTemplateProcedure(isTypeProcedure);
        newProc->SetProjectId(query.value("ProjectId").toInt());
        newProc->SetProcedureId(query.value("ProcedureId").toInt());
        newProc->SetProjectProcedureId(query.value("ProjectProcedureId").toInt());
        newProc->SetDescription(query.value("Description").toString());
        newProc->SetDoneState(query.value("IsDone").toInt() != 0);

        ProcedureCacheKey key = GetCacheKey(*newProc);
        std::shared_ptr<Procedure> sharedPtr = m_cache.Lookup(key);

        if(!sharedPtr)
        {
            sharedPtr = std::shared_ptr<Procedure>(std::move(newProc));
            AddProcedure(key, sharedPtr);
        }

        result.push_back(sharedPtr);
    }

    return result;
}
void XMLProcedureCall::AddDirectSQL(const char * sql)
{
	AddProcedure("DirectSQL");

	// causes CXMLRequest::m_strValue to contain the SQL in the Transaction
	m_pCurrentProcedure->SetObjectValue(sql,-1,3);

	// Force the SQL to go through the tranasction handler
	// of the XML data server since the direct sql will not
	// have a file that describes the XML result set.

	//	ForceTransaction();
	
	// when ForceTransaction() is there, a square html view falls into
	// the TransactSQL() handler in the server, it should hit the
	// GetHTMLMarkup() in the server.  I can either reorder the attribute 
	// presidence or remove the "Transaction=yes" attribute here..... 

}
void XMLProcedureCall::AddProcedure(const char * ProcName, const char *ProcValue)
{
	AddProcedure(ProcName);
	m_pCurrentProcedure->SetObjectValue(ProcValue,-1,3);
}