/*------------------------------------------------------------------------ File : usersHandler Purpose : Syntax : Description : Author(s) : walter.riechsteiner Created : Fri Nov 21 11:31:01 CET 2025 Notes : ----------------------------------------------------------------------*/ BLOCK-LEVEL ON ERROR UNDO, THROW. USING Progress.Json.ObjectModel.JsonObject FROM PROPATH. USING Progress.Json.ObjectModel.JsonArray FROM PROPATH. USING utilities.utilitiesHandler FROM PROPATH. USING Progress.Json.ObjectModel.ObjectModelParser FROM PROPATH. USING OpenEdge.DataAdmin.IIndex FROM PROPATH. USING OpenEdge.Web.DataObject.Writer.JsonObjectValueWriter FROM PROPATH. CLASS admin.adminprogsHandler FINAL: DEFINE VARIABLE oJsonData AS JsonObject NO-UNDO. DEFINE VARIABLE oJsonArray AS JsonArray NO-UNDO. DEFINE VARIABLE oParser AS ObjectModelParser NO-UNDO. DEFINE VARIABLE cuser_name AS CHARACTER NO-UNDO. DEFINE VARIABLE ccompany AS CHARACTER NO-UNDO. DEFINE VARIABLE lcJsonString AS LONGCHAR NO-UNDO. DEFINE VARIABLE iLanguage_id AS INTEGER NO-UNDO. DEFINE VARIABLE oRecords AS JsonArray NO-UNDO. DEFINE VARIABLE oJsonPosition AS JsonObject NO-UNDO. DEFINE VARIABLE cFileName AS CHARACTER NO-UNDO. DEFINE VARIABLE lCompany AS LOGICAL NO-UNDO. DEFINE VARIABLE lActive AS LOGICAL NO-UNDO. DEFINE VARIABLE lWordindex AS LOGICAL NO-UNDO. DEFINE VARIABLE cActiveSelection AS CHARACTER NO-UNDO. DEFINE VARIABLE cSortField AS CHARACTER NO-UNDO INIT ''. DEFINE VARIABLE cDirection AS CHARACTER NO-UNDO. DEFINE VARIABLE cFieldReplace AS CHARACTER NO-UNDO. DEFINE VARIABLE cKeyFieldReplace AS CHARACTER NO-UNDO. DEFINE VARIABLE cFilterReplace AS CHARACTER NO-UNDO. DEFINE VARIABLE cFileReplace AS CHARACTER NO-UNDO. DEFINE VARIABLE cKeyFields AS CHARACTER NO-UNDO. DEFINE VARIABLE cKeyValues AS CHARACTER NO-UNDO. DEFINE VARIABLE cWhere AS CHARACTER NO-UNDO. DEFINE VARIABLE cString AS CHARACTER NO-UNDO. DEFINE VARIABLE cMessage AS CHARACTER NO-UNDO. DEFINE VARIABLE lcMessage AS LONGCHAR NO-UNDO. DEFINE VARIABLE iAnzahlRecords AS INTEGER NO-UNDO. DEFINE VARIABLE iActualPage AS INTEGER NO-UNDO. DEFINE VARIABLE iMaxRecords AS INTEGER NO-UNDO INIT 20. DEFINE VARIABLE iStartPage AS INTEGER NO-UNDO. DEFINE VARIABLE iStartRecord AS INTEGER NO-UNDO. DEFINE VARIABLE iPageCounter AS INTEGER NO-UNDO. DEFINE VARIABLE iCurrentPosition AS INTEGER NO-UNDO. DEFINE VARIABLE cPrimaryKey AS CHARACTER NO-UNDO. DEFINE VARIABLE iIndex AS INTEGER NO-UNDO. DEFINE VARIABLE iStartIndex AS INTEGER NO-UNDO. DEFINE VARIABLE httTable AS HANDLE NO-UNDO. DEFINE VARIABLE ttTable AS HANDLE NO-UNDO. DEFINE VARIABLE hQuery AS HANDLE NO-UNDO. DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO. DEFINE TEMP-TABLE ttKeyFields FIELD iIndex AS INTEGER FIELD cLongName AS CHARACTER FIELD cFieldName AS CHARACTER FIELD cFileName AS CHARACTER FIELD cValue AS CHARACTER FIELD cDataType AS CHARACTER INDEX ttKeyFields-k1 IS PRIMARY iIndex cFieldName . DEFINE VARIABLE httKeyFields AS HANDLE NO-UNDO. DEFINE TEMP-TABLE ttPrimaryIndex FIELD iIndex AS INTEGER FIELD cFieldName AS CHARACTER FIELD cFileName AS CHARACTER FIELD cValue AS CHARACTER FIELD cDataType AS CHARACTER INDEX ttPrimaryIndex-k1 IS PRIMARY iIndex cFieldName . DEFINE VARIABLE httPrimaryIndex AS HANDLE NO-UNDO. DEFINE VARIABLE outilitiesHandler AS utilitiesHandler NO-UNDO. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC VOID buildWhere( INPUT oJsonIdent AS JsonObject ): DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE i1 AS INTEGER NO-UNDO. DEFINE VARIABLE lOK AS LOGICAL NO-UNDO. DEFINE VARIABLE cValue AS CHARACTER NO-UNDO. DEFINE VARIABLE cString AS CHARACTER NO-UNDO. DEFINE VARIABLE iNumerisch AS INTEGER NO-UNDO. DEFINE VARIABLE cSearchChars AS CHARACTER NO-UNDO INIT ''. DEFINE VARIABLE lSearch AS LOGICAL NO-UNDO. DEFINE VARIABLE cFields AS CHARACTER NO-UNDO EXTENT. DEFINE VARIABLE cField AS CHARACTER NO-UNDO. DEFINE VARIABLE cFilter AS CHARACTER NO-UNDO. DEFINE VARIABLE cDBField AS CHARACTER NO-UNDO. DEFINE VARIABLE cType AS CHARACTER NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). // // Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält // outilitiesHandler:evaluateFile( INPUT-OUTPUT oJsonIdent , OUTPUT cFileName , OUTPUT lCompany , OUTPUT lActive , OUTPUT lWordindex , INPUT-OUTPUT httKeyFields , INPUT-OUTPUT httPrimaryIndex ). cFieldReplace = SUBSTITUTE('&1_' , cFileName). cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName). cFilterReplace = SUBSTITUTE('filter_&1_' , cFileName). lOK = outilitiesHandler:getKeyFields( INPUT oJsonIdent , OUTPUT cKeyFields , OUTPUT cKeyValues ). CREATE BUFFER hBuffer FOR TABLE cFileName. cuser_name = oJsonIdent:GetCharacter('user_name'). ccompany = oJsonIdent:GetCharacter('company'). cSortField = ''. cDirection = ''. cWhere = ''. iStartPage = 1. iMaxRecords = 25. IF oJsonIdent:HAS('page') THEN iStartPage = INTEGER(oJsonIdent:GetCharacter('page')) NO-ERROR. IF oJsonIdent:HAS('limit') THEN iMaxRecords = INTEGER(oJsonIdent:GetCharacter('limit')) NO-ERROR. IF oJsonIdent:HAS('search') THEN DO: cSearchChars = oJsonIdent:GetCharacter('search'). cSearchChars = REPLACE(cSearchChars, '+', ' '). lSearch = TRUE. iMaxRecords = 100. END. iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1. IF lCompany THEN cWhere = SUBSTITUTE('WHERE &1.company = &2', cFileName, QUOTER(ccompany)). IF cKeyFields <> '' THEN DO: DO ii = 1 TO NUM-ENTRIES(cKeyFields, ';'): cString = ENTRY(ii, cKeyFields, ';'). cString = REPLACE(cString, cFieldReplace, ''). IF cString = 'company' AND lCompany THEN NEXT. IF cString = 'active' AND lActive THEN NEXT. cValue = ENTRY(ii, cKeyValues, CHR(01)). cString = SUBSTITUTE('&1.&2 = &3 ', cFileName, cString, cValue). cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ') + cString. END. END. // // hat es Sortierfelder ? // IF oJsonIdent:HAS('sortField') THEN DO: cSortField = REPLACE(oJsonIdent:GetCharacter('sortField'), cFieldReplace, ''). cDirection = oJsonIdent:GetCharacter('sortDirection'). END. // // Sortfeld(er) zu den User-Daten schreiben // outilitiesHandler:writeSortfields( INPUT oJsonIdent, INPUT cFileName , INPUT cSortField , INPUT cDirection ). // // Suche aus dem Suchfeld --> geht dann über Wordindex // IF lSearch THEN DO: DO ii = 1 TO NUM-ENTRIES(cSearchChars, ' '): cValue = ENTRY(ii, cSearchChars, ' '). iNumerisch = INTEGER(cValue) NO-ERROR. cWhere = cWhere + (IF cWhere = '' THEN ' WHERE ' ELSE 'AND '). IF NOT ERROR-STATUS:ERROR AND iNumerisch > 0 THEN cValue = SUBSTITUTE('&1&2&1', CHR(01), TRIM(STRING(iNumerisch,'>>>>>>>>9-'))). cWhere = cWhere + 'LOOKUP(' + QUOTER(cValue) + ', ' + cFileName + '.wordindex, " ") > 0 '. END. END. // // wenn nicht über Suchfeld, können Filter auf den einzelnen Tabellen-Spalten gesetzt sein // IF NOT lSearch THEN DO: cFields = oJsonIdent:GetNames(). DO i1 = 1 TO EXTENT(cFields): cField = cFields[i1]. IF NOT cField BEGINS 'filter_' THEN NEXT. cFilter = oJsonIdent:GetCharacter(cField). cField = REPLACE(cField, cFilterReplace, ''). cType = hBuffer:BUFFER-FIELD(cField):DATA-TYPE. MESSAGE 'Filter-Feld =' cField 'mit Type' cType 'und wert' cFilter. CASE cType: WHEN 'character' THEN cFilter = QUOTER(cFilter). WHEN 'logical' THEN cFilter = STRING(cFilter,'true/false'). WHEN 'date' THEN cFilter = STRING(DATE(cFilter),'99.99.9999'). END CASE. cDBField = SUBSTITUTE('&1.&2', cFileName, cField). cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ') + 'INDEX(' + cDBField + ', ' + cFilter + ') > 0 '. END. END. // // Die Tabelle hat das Feld "active" active = FALSE --> gelöscht (inaktiv) // IF lActive THEN DO: cActiveSelection = oJsonIdent:GetCharacter('activeFilter') NO-ERROR. CASE cActiveSelection: WHEN 'activeOnly' THEN lOK = TRUE. WHEN 'inactiveOnly' THEN lOK = FALSE. OTHERWISE lOK = ?. END CASE. IF lOK <> ? THEN cWhere = cWhere + (IF cWhere = '' THEN ' WHERE ' ELSE ' AND ') + SUBSTITUTE('&1.active = &2 ', cFileName, STRING(lOK,'true/false')). END. // // Sortierung im Where-Statement // IF NOT cDirection BEGINS 'des' THEN cDirection = ''. IF cSortField <> '' THEN cWhere = cWhere + 'BY ' + cSortField + ' ' + cDirection. // // TEMP-Table für die selektierten Datensätze, sollte ein Sortfeld vorhanden sein, wird dort der Primary-Index gesetzt // createTempTable( INPUT oJsonIdent ). RETURN. END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC LOGICAL createData( INPUT oJsonIdent AS JsonObject, INPUT oJsonRecord AS jsonObject, OUTPUT oJsonReturn AS JsonObject ): DEFINE VARIABLE oJsonMessage AS JsonObject NO-UNDO. DEFINE VARIABLE oJsonMessageBox AS JsonObject NO-UNDO. DEFINE VARIABLE lRetVal AS LOGICAL NO-UNDO. DEFINE VARIABLE lOK AS LOGICAL NO-UNDO. DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE i1 AS INTEGER NO-UNDO. DEFINE VARIABLE iIndex AS INTEGER NO-UNDO. DEFINE VARIABLE cWordIndex AS CHARACTER NO-UNDO. DEFINE VARIABLE hField AS HANDLE NO-UNDO. DEFINE VARIABLE htField AS HANDLE NO-UNDO. DEFINE VARIABLE cField AS CHARACTER NO-UNDO. DEFINE VARIABLE cValue AS CHARACTER NO-UNDO. DEFINE VARIABLE cIndexFields AS CHARACTER NO-UNDO. DEFINE VARIABLE rBuffer AS RECID NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). httKeyFields = TEMP-TABLE ttKeyFields :DEFAULT-BUFFER-HANDLE. httPrimaryIndex = TEMP-TABLE ttPrimaryIndex:DEFAULT-BUFFER-HANDLE. // // Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält // outilitiesHandler:evaluateFile( INPUT-OUTPUT oJsonIdent , OUTPUT cFileName , OUTPUT lCompany , OUTPUT lActive , OUTPUT lWordindex , INPUT-OUTPUT httKeyFields , INPUT-OUTPUT httPrimaryIndex ). cFieldReplace = SUBSTITUTE('&1_' , cFileName). cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName). cFilterReplace = SUBSTITUTE('filter_&1_' , cFileName). lOK = outilitiesHandler:getKeyFields( INPUT oJsonIdent , OUTPUT cKeyFields , OUTPUT cKeyValues ). createTempTable( INPUT oJsonIdent ). httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR. httTable:FIND-FIRST('', NO-LOCK). // // Primary-Index-Fields für WHERE-Statement // CREATE BUFFER hBuffer FOR TABLE cFileName. cIndexFields = outilitiesHandler:getPrimaryIndexFields( INPUT cFileName ). // // Erzeugen von Where-Statement für UNIQUE-Find // cWhere = ''. DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'): cField = ENTRY(i1, cIndexFields, ';'). hField = httTable:BUFFER-FIELD(cField):HANDLE. CASE hField:DATA-TYPE: WHEN 'character' THEN cValue = QUOTER(hField:BUFFER-VALUE). WHEN 'logical' THEN cValue = STRING(hField:BUFFER-VALUE,"true/false"). WHEN 'date' THEN cValue = STRING(DATE(hField:BUFFER-VALUE)). OTHERWISE cValue = hField:BUFFER-VALUE. END CASE. cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ') + SUBSTITUTE('&1.&2 = ', cFileName, cField) + cValue. END. lRetVal = FALSE. REPEAT TRANSACTION ON ERROR UNDO, LEAVE: lOK = hBuffer:FIND-UNIQUE(cWhere) NO-ERROR. IF hBuffer:AVAILABLE THEN DO: outilitiesHandler:createErrorBox( INPUT oJsonIdent , INPUT '2007' , INPUT '' , OUTPUT oJsonMessageBox ). oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('success' , FALSE ). oJsonReturn:ADD('showMessage' , oJsonMessageBox). RETURN TRUE. END. // // Datensatz erstellen / active setzen / wordindex erstellen // hBuffer:BUFFER-CREATE (). DO ii = 1 TO httTable:NUM-FIELDS: hField = hBuffer:BUFFER-FIELD(ii):HANDLE NO-ERROR. IF ERROR-STATUS:ERROR OR NOT VALID-HANDLE(hField) THEN NEXT. htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR. IF ERROR-STATUS:ERROR OR NOT VALID-HANDLE(hField) THEN NEXT. hField:BUFFER-VALUE = htField:BUFFER-VALUE. END. MESSAGE '1'. htField = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR. IF NOT ERROR-STATUS:ERROR AND VALID-HANDLE(htField) THEN htField:BUFFER-VALUE = TRUE. htField = hBuffer:BUFFER-FIELD('created_at'):HANDLE NO-ERROR. IF NOT ERROR-STATUS:ERROR AND VALID-HANDLE(htField) THEN htField:BUFFER-VALUE = NOW. htField = hBuffer:BUFFER-FIELD('wordindex'):HANDLE NO-ERROR. IF NOT ERROR-STATUS:ERROR AND VALID-HANDLE(htField) THEN DO: cWordIndex = outilitiesHandler:createWordindex( INPUT hBuffer ). htField:BUFFER-VALUE = cWordIndex. END. rBuffer = hBuffer:RECID. MESSAGE '2' rBuffer. hBuffer:BUFFER-RELEASE (). lRetVal = TRUE. LEAVE. END. // // Datensatz anhand der letzten Kriterien in der Tabelle finden und Pagination ermitteln // outilitiesHandler:readPosition( INPUT oJsonIdent, INPUT cFileName, OUTPUT iCurrentPosition, OUTPUT iStartPage, OUTPUT iMaxRecords ). DO WHILE lRetVal: outilitiesHandler:readLastcWhere( INPUT oJsonIdent, INPUT cFileName , OUTPUT cWhere ). ASSIGN ii = 0 i1 = 0 iAnzahlRecords = 0 iActualPage = 0 iCurrentPosition = 0 iStartRecord = 1. CREATE QUERY hQuery. hQuery:SET-BUFFERS (hBuffer) NO-ERROR. hQuery:QUERY-PREPARE (cWhere) NO-ERROR. hQuery:QUERY-OPEN (). iAnzahlRecords = hQuery:NUM-RESULTS. hQuery:GET-FIRST(NO-LOCK). lOK = FALSE. DO WHILE NOT hQuery:QUERY-OFF-END: ii = ii + 1. IF ii MOD iMaxRecords = 1 THEN iActualPage = iActualPage + 1. IF hBuffer:RECID <> rBuffer THEN DO: hQuery:GET-NEXT (NO-LOCK). NEXT. END. iIndex = ii MOD iMaxRecords. LEAVE. END. iStartPage = iActualPage. iStartRecord = (iStartPage - 1) * iMaxRecords + 1. LEAVE. END. hQuery:QUERY-CLOSE (). DELETE OBJECT hBuffer NO-ERROR. IF ii = 0 THEN RETURN FALSE. IF lRetVal THEN DO: oJsonPosition = NEW JsonObject(). oJsonPosition:ADD('page' , iActualPage). oJsonPosition:ADD('index', iIndex - 1). /* -1 weil in Java beginnt Index bei 0 */ oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('maxRecords', iAnzahlRecords). oJsonReturn:ADD('position' , oJsonPosition ). /* outilitiesHandler:writePosition(*/ /* INPUT oJsonIdent , */ /* INPUT cFileName , */ /* INPUT iCurrentPosition , */ /* INPUT iStartPage , */ /* INPUT iMaxRecords */ /* ). */ RETURN lRetVal. END. IF NOT lRetVal THEN DO: oJsonMessage = NEW JsonObject(). oJsonMessage:ADD('success', FALSE). oJsonMessage:ADD('message', lcMessage). oJsonMessage:WRITE(lcJsonString, FALSE). oJsonReturn = oJsonMessage. END. RETURN lRetVal. CATCH e AS Progress.Lang.Error: END CATCH. FINALLY: END FINALLY. END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC VOID createTempTable( INPUT oJsonIdent AS JsonObject ): DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE cFunction AS CHARACTER NO-UNDO. DEFINE VARIABLE cSerializeName AS CHARACTER NO-UNDO. DEFINE VARIABLE cttName AS CHARACTER NO-UNDO. CREATE TEMP-TABLE ttTable. ttTable:ADD-FIELDS-FROM (cFilename, 'wordindex'). /* Alle Felder aus dem Buffer, ausser wordindex */ IF cSortField <> '' THEN DO: ttTable:ADD-NEW-INDEX ('ttTable-k1', FALSE, TRUE). /* UNIQUE, PRIMARY */ IF cDirection BEGINS 'des' THEN ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField, 'desc'). ELSE ttTable:ADD-INDEX-FIELD ('ttTable-k1', cSortField). END. cFunction = oJsonIdent:GetCharacter('function'). CASE cFunction: WHEN 'delete' THEN cttName = 'record'. WHEN 'update' THEN cttName = 'record'. WHEN 'change' THEN cttName = 'record'. WHEN 'create' THEN cttName = 'record'. OTHERWISE cttName = 'records'. END CASE. ttTable:TEMP-TABLE-PREPARE (cttName). httTable = ttTable:DEFAULT-BUFFER-HANDLE. // // Den Feldnamen wird für das Front-End der Tabellenname vorhergestellt (Serialize-Name) // DO ii = 1 TO httTable:NUM-FIELDS: CASE httTable:BUFFER-FIELD(ii):NAME: WHEN 'active' THEN cSerializeName = 'active'. OTHERWISE cSerializeName = cFileName + '_' + httTable:BUFFER-FIELD(ii):NAME. END CASE. httTable:BUFFER-FIELD(ii):SERIALIZE-NAME = cSerializeName NO-ERROR. END. END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC LOGICAL deleteData( INPUT oJsonIdent AS JsonObject, INPUT oJsonRecord AS jsonObject, OUTPUT oJsonReturn AS JsonObject ): DEFINE VARIABLE oJsonMessage AS JsonObject NO-UNDO. DEFINE VARIABLE oJsonMessageBox AS JsonObject NO-UNDO. DEFINE VARIABLE lRetVal AS LOGICAL NO-UNDO. DEFINE VARIABLE lOK AS LOGICAL NO-UNDO. DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE i1 AS INTEGER NO-UNDO. DEFINE VARIABLE cString AS CHARACTER NO-UNDO. DEFINE VARIABLE iIndex AS INTEGER NO-UNDO. DEFINE VARIABLE cWordIndex AS CHARACTER NO-UNDO. DEFINE VARIABLE hField AS HANDLE NO-UNDO. DEFINE VARIABLE htField AS HANDLE NO-UNDO. DEFINE VARIABLE cField AS CHARACTER NO-UNDO. DEFINE VARIABLE cValue AS CHARACTER NO-UNDO. DEFINE VARIABLE cIndexFields AS CHARACTER NO-UNDO. DEFINE VARIABLE rBuffer AS RECID NO-UNDO. DEFINE VARIABLE cQueryWhere AS CHARACTER NO-UNDO. DEFINE VARIABLE cFunction AS CHARACTER NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). // // Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält // outilitiesHandler:evaluateFile( INPUT-OUTPUT oJsonIdent , OUTPUT cFileName , OUTPUT lCompany , OUTPUT lActive , OUTPUT lWordindex , INPUT-OUTPUT httKeyFields , INPUT-OUTPUT httPrimaryIndex ). cFieldReplace = SUBSTITUTE('&1_' , cFileName). cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName). cFilterReplace = SUBSTITUTE('filter_&1_' , cFileName). lOK = outilitiesHandler:getKeyFields( INPUT oJsonIdent , OUTPUT cKeyFields , OUTPUT cKeyValues ). createTempTable( INPUT oJsonIdent ). httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR. httTable:FIND-FIRST('', NO-LOCK). // // Primary-Index-Fields für WHERE-Statement // CREATE BUFFER hBuffer FOR TABLE cFileName. cIndexFields = outilitiesHandler:getPrimaryIndexFields( INPUT cFileName ). // // Erzeugen von Where-Statement für UNIQUE-Find // cWhere = ''. DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'): cField = ENTRY(i1, cIndexFields, ';'). hField = httTable:BUFFER-FIELD(cField):HANDLE. CASE hField:DATA-TYPE: WHEN 'character' THEN cValue = QUOTER(hField:BUFFER-VALUE). WHEN 'logical' THEN cValue = STRING(hField:BUFFER-VALUE,"true/false"). WHEN 'date' THEN cValue = STRING(DATE(hField:BUFFER-VALUE)). OTHERWISE cValue = hField:BUFFER-VALUE. END CASE. cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ') + SUBSTITUTE('&1.&2 = ', cFileName, cField) + cValue. END. lRetVal = FALSE. REPEAT TRANSACTION ON ERROR UNDO, LEAVE: lOK = hBuffer:FIND-UNIQUE(cWhere, NO-LOCK) NO-ERROR. IF NOT hBuffer:AVAILABLE THEN DO: outilitiesHandler:createErrorBox( INPUT oJsonIdent , INPUT '2000' , INPUT '' , OUTPUT oJsonMessageBox ). oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('success' , FALSE ). oJsonReturn:ADD('showMessage' , oJsonMessageBox). RETURN TRUE. END. rBuffer = hBuffer:RECID. hBuffer:BUFFER-RELEASE (). iStartPage = INTEGER(oJsonIdent:GetCharacter('page')) NO-ERROR. iIndex = INTEGER(oJsonIdent:GetCharacter('index')) NO-ERROR. // // Index in der Tabellenanzeige ermitteln // outilitiesHandler:readLastcWhere( INPUT oJsonIdent, INPUT cFileName, OUTPUT cQueryWhere). cQueryWhere = REPLACE(cQueryWhere, 'FOR', 'PRESELECT'). CREATE QUERY hQuery. hQuery:SET-BUFFERS(hBuffer). hQuery:QUERY-PREPARE (cQueryWhere). /* */ /* outilitiesHandler:readPosition( */ /* INPUT oJsonIdent, */ /* INPUT cFileName, */ /* OUTPUT iCurrentPosition, */ /* OUTPUT iStartPage , */ /* OUTPUT iMaxRecords */ /* ). */ hQuery:QUERY-OPEN (). ii = hQuery:NUM-RESULTS. /* iIndex = 0. */ /* hQuery:REPOSITION-FORWARD(iCurrentPosition - 1) NO-ERROR.*/ /* hQuery:GET-NEXT (NO-LOCK). */ /* DO WHILE NOT hQuery:QUERY-OFF-END: */ /* iIndex = iIndex + 1. */ /* IF hBuffer:RECID = rBuffer THEN LEAVE. */ /* IF iIndex >= iMaxRecords THEN LEAVE. */ /* hQuery:GET-NEXT (NO-LOCK). */ /* END. */ hQuery:QUERY-CLOSE (). hBuffer:BUFFER-RELEASE (). lOK = hBuffer:FIND-UNIQUE(cWhere, EXCLUSIVE-LOCK, NO-WAIT) NO-ERROR. IF hBuffer:LOCKED THEN DO: outilitiesHandler:createLockMessage( INPUT oJsonIdent, INPUT rBuffer , OUTPUT oJsonMessageBox ). lcMessage = oJsonMessageBox:GetLongchar('message'). LEAVE. END. DO WHILE lActive : hField = hBuffer:BUFFER-FIELD('active'):HANDLE NO-ERROR. IF ERROR-STATUS:ERROR OR NOT VALID-HANDLE(hField) THEN LEAVE. hField:BUFFER-VALUE = FALSE NO-ERROR. hField = hBuffer:BUFFER-FIELD('updated_at'):HANDLE NO-ERROR. IF NOT ERROR-STATUS:ERROR AND VALID-HANDLE(hField) THEN hField:BUFFER-VALUE = NOW. httTable:BUFFER-COPY(hBuffer). lRetVal = TRUE. LEAVE. END. DO WHILE NOT lRetVal: lRetVal = hBuffer:BUFFER-DELETE (). LEAVE. END. hBuffer:BUFFER-RELEASE () NO-ERROR. IF NOT lRetVal THEN LEAVE. LEAVE. END. IF lRetVal THEN DO: oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('success', TRUE). oJsonPosition = NEW JsonObject(). oJsonPosition:ADD('page' , iStartPage). oJsonPosition:ADD('index' , iIndex ). oJsonPosition:ADD('totalRecords', ii ). oJsonReturn:ADD('position', oJsonPosition). // oJsonReturn:WriteFile('C:\TEMP\adminprog_DELETE_Respons.json', TRUE). RETURN lRetVal. END. IF NOT lRetVal THEN DO: oJsonMessage = NEW JsonObject(). oJsonMessage:ADD('success', FALSE). oJsonMessage:ADD('message', lcMessage). oJsonMessage:WRITE(lcJsonString, FALSE). oJsonReturn = oJsonMessage. END. RETURN lRetVal. CATCH e AS Progress.Lang.Error: END CATCH. FINALLY: DELETE OBJECT oJsonArray NO-ERROR. DELETE OBJECT oJsonData NO-ERROR. END FINALLY. END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC LOGICAL getChanges( INPUT oJsonIdent AS JsonObject, OUTPUT oJsonResult AS JsonObject ): /* DEFINE VARIABLE lRetVal AS LOGICAL NO-UNDO. DEFINE VARIABLE cFunction AS CHARACTER NO-UNDO. DEFINE VARIABLE cField AS CHARACTER NO-UNDO. DEFINE VARIABLE cAction AS CHARACTER NO-UNDO. DEFINE VARIABLE cValue AS CHARACTER NO-UNDO. DEFINE VARIABLE lcJsonString AS LONGCHAR NO-UNDO. DEFINE VARIABLE cWhere AS CHARACTER NO-UNDO. DEFINE VARIABLE i1 AS INTEGER NO-UNDO. DEFINE VARIABLE i2 AS INTEGER NO-UNDO. DEFINE VARIABLE oJsonfieldUpdates AS JsonObject NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). cField = oJsonIdent:GetCharacter('field'). cAction = oJsonIdent:GetCharacter('action'). cValue = REPLACE(oJsonIdent:GetCharacter('value'), '+', ' '). oJsonResult = NEW JsonObject(). oJsonFieldUpdates = NEW JsonObject(). lRetVal = outilitiesHandler:getKeyFields( INPUT oJsonIdent , OUTPUT cKeyFields , OUTPUT cKeyValues ). cWhere = ''. lRetVal = FALSE. DO WHILE TRUE: DO i1 = 1 TO NUM-ENTRIES(cKeyFields, ';'): cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE 'AND ' ) + SUBSTITUTE('busers.&1 = &2 ', REPLACE(ENTRY(i1, cKeyFields, ';'), 'users_', ''), QUOTER (ENTRY(i1, cKeyValues, CHR(01)))). END. MESSAGE cWhere. hBuffer = BUFFER busers:HANDLE. lRetVal = hBuffer:FIND-UNIQUE(cWhere, NO-LOCK) NO-ERROR. IF lRetVal THEN DO: CASE cField: WHEN 'users_firstname' THEN DO: IF hBuffer::display_Name = '' THEN DO: cString = cValue + ' ' + hBuffer::lastname. oJsonfieldUpdates:ADD('users_display_name', cString). END. IF hBuffer::initials = '' THEN DO: cString = TRIM(SUBSTRING(cValue,01,02)) + TRIM(SUBSTRING(hBuffer::lastname,01,02)). oJsonfieldUpdates:ADD('users_initials', cString). END. END. END CASE. oJsonResult:ADD('fieldUpdates', oJsonfieldUpdates). END. lRetVal = TRUE. LEAVE. END. IF NOT lRetVal THEN DO: oJsonResult = NEW JsonObject(). oJsonResult:ADD('success', FALSE). oJsonResult:ADD('message', 'Fehler beim change'). END. RETURN lRetVal. */ END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC LOGICAL getData( INPUT oJsonIdent AS JsonObject, OUTPUT oJsonReturn AS JsonObject ): DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE iAnzRec AS INTEGER NO-UNDO. DEFINE VARIABLE lRetVal AS LOGICAL NO-UNDO. DEFINE VARIABLE lOK AS LOGICAL NO-UNDO. DEFINE VARIABLE cFunction AS CHARACTER NO-UNDO. DEFINE VARIABLE oRecords AS JsonArray NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). cFunction = oJsonIdent:GetCharacter('function'). httKeyFields = TEMP-TABLE ttKeyFields :DEFAULT-BUFFER-HANDLE. httPrimaryIndex = TEMP-TABLE ttPrimaryIndex:DEFAULT-BUFFER-HANDLE. MESSAGE 'httKeyFields' VALID-HANDLE(httKeyFields) 'httPrimaryIndex' VALID-HANDLE(httPrimaryIndex). IF cFunction = 'rebuild' THEN DO: iStartPage = 1. iMaxRecords = 25. IF oJsonIdent:HAS('page') THEN iStartPage = INTEGER(oJsonIdent:GetCharacter('page')) NO-ERROR. IF oJsonIdent:HAS('limit') THEN iMaxRecords = INTEGER(oJsonIdent:GetCharacter('limit')) NO-ERROR. iStartRecord = ((iStartPage - 1) * iMaxRecords) + 1. outilitiesHandler:readLastcWhere( INPUT oJsonIdent, INPUT cFileName , OUTPUT cWhere). createTempTable( INPUT oJsonIdent ). END. ELSE DO: iIndex = 0. buildWhere( INPUT oJsonIdent ). END. ii = 0. iAnzRec = 0. ttTable:EMPTY-TEMP-TABLE (). CREATE QUERY hQuery. IF cFunction = 'loaddata' THEN DO: cWhere = SUBSTITUTE('FOR EACH &1 NO-LOCK &2 ', cFileName, cWhere) NO-ERROR. outilitiesHandler:writeLastcWhere( INPUT oJsonIdent , INPUT cFileName , INPUT cWhere ). END. // // Für das Dynamische Query wird PRESELECT verwendet für die Pagination // cWhere = REPLACE(cWhere, 'FOR', 'PRESELECT'). hQuery:SET-BUFFERS (hBuffer) NO-ERROR. hQuery:QUERY-PREPARE (cWhere) NO-ERROR. hQuery:QUERY-OPEN (). ii = hQuery:NUM-RESULTS. hQuery:REPOSITION-FORWARD(iStartRecord - 1) NO-ERROR. hQuery:GET-NEXT (). iCurrentPosition = 0. DO WHILE NOT hQuery:QUERY-OFF-END: IF iCurrentPosition = 0 THEN iCurrentPosition = iStartRecord. iAnzRec = iAnzRec + 1. httTable:BUFFER-CREATE(). httTable:BUFFER-COPY(hBuffer). IF iAnzRec >= iMaxRecords THEN LEAVE. hQuery:GET-NEXT (). END. hQuery:QUERY-CLOSE (). DELETE OBJECT hQuery NO-ERROR. DELETE OBJECT hBuffer NO-ERROR. iPageCounter = ii / iMaxRecords. IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1. oRecords = NEW JsonArray(). httTable:WRITE-JSON('JsonArray', oRecords). oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('records' , oRecords ). oJsonReturn:ADD('currentPage' , iStartPage ). oJsonReturn:ADD('maxRecords' , ii ). oJsonReturn:ADD('pageCount' , iPageCounter ). oJsonReturn:ADD('recordCount' , iAnzRec ). oJsonReturn:ADD('currentIndex', iIndex ). outilitiesHandler:writePosition( INPUT oJsonIdent , INPUT cFileName , INPUT iCurrentPosition , INPUT iStartPage , INPUT iMaxRecords ). // oJsonReturn:WriteFile('C:\TEMP\getData_messages.json', TRUE). lRetVal = TRUE. RETURN lRetVal. END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC LOGICAL rebuildData( INPUT oJsonIdent AS JsonObject, OUTPUT oJsonReturn AS JsonObject ): DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE lRetVal AS LOGICAL NO-UNDO. DEFINE VARIABLE cValue AS CHARACTER NO-UNDO. DEFINE VARIABLE lOK AS LOGICAL NO-UNDO. DEFINE VARIABLE rBuffer AS RECID NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). buildWhere( INPUT oJsonIdent ). CREATE BUFFER hBuffer FOR TABLE cFileName. // // der letzte selektierte Datensatz vor dem rebuild // MESSAGE 'FIND-UNIQUE WIT cWHere' cWhere. lOK = hBuffer:FIND-FIRST(cWhere, NO-LOCK) NO-ERROR. IF lOK THEN DO: rBuffer = hBuffer:RECID. END. // // Letztes Sortfeld lesen // outilitiesHandler:readSortFields( INPUT oJsonIdent, INPUT cFileName , OUTPUT cSortField, OUTPUT cDirection ). DO WHILE cSortField <> '': IF oJsonIdent:HAS('sortField') THEN LEAVE. IF cDirection BEGINS 'asc' THEN cDirection = ''. oJsonIdent:ADD('sortField', cSortField). oJsonIdent:ADD('direction', cDirection). cWhere = cWhere + ' BY ' + cSortFIeld + ' ' + cDirection. LEAVE. END. outilitiesHandler:readLastcWhere( INPUT oJsonIdent, INPUT cFileName , OUTPUT cWhere ). cWhere = REPLACE(cWHere, 'FOR', 'PRESELECT'). CREATE QUERY hQuery. hQuery:SET-BUFFERS(hBuffer). hQuery:QUERY-PREPARE (cWhere). hQuery:QUERY-OPEN (). iAnzahlRecords = hQuery:NUM-RESULTS. iCurrentPosition = 0. DO WHILE NOT hQuery:QUERY-OFF-END: hQuery:GET-NEXT() NO-ERROR. IF hQuery:QUERY-OFF-END THEN LEAVE. iCurrentPosition = iCurrentPosition + 1. IF hBuffer:RECID = rBuffer THEN LEAVE. END. hQuery:QUERY-CLOSE (). DELETE OBJECT hQuery NO-ERROR. IF oJsonIdent:HAS('limit') THEN iMaxRecords = INTEGER(oJsonIdent:GetCharacter('limit')) NO-ERROR. iIndex = (iCurrentPosition MOD iMaxRecords) - 1. iStartPage = ((iCurrentPosition - (iCurrentPosition MOD iMaxRecords)) / iMaxRecords) + 1. iPageCounter = ii / iMaxRecords. IF (iPageCounter * iMaxRecords) < ii THEN iPageCounter = iPageCounter + 1. IF oJsonIdent:HAS('page') THEN oJsonIdent:SET('page', STRING(iStartPage)). ELSE oJsonIdent:ADD('page', STRING(iStartPage)). IF oJsonIdent:HAS('limit') THEN iMaxRecords = INTEGER(oJsonIdent:GetCharacter('limit')) NO-ERROR. lRetVal = getData( INPUT oJsonIdent , OUTPUT oJsonReturn ). RETURN lRetVal. END METHOD. /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ METHOD PUBLIC LOGICAL updateData( INPUT oJsonIdent AS JsonObject, INPUT oJsonRecord AS jsonObject, OUTPUT oJsonReturn AS JsonObject ): DEFINE VARIABLE oJsonMessage AS JsonObject NO-UNDO. DEFINE VARIABLE oJsonMessageBox AS JsonObject NO-UNDO. DEFINE VARIABLE lRetVal AS LOGICAL NO-UNDO. DEFINE VARIABLE lOK AS LOGICAL NO-UNDO. DEFINE VARIABLE ii AS INTEGER NO-UNDO. DEFINE VARIABLE i1 AS INTEGER NO-UNDO. DEFINE VARIABLE iIndex AS INTEGER NO-UNDO. DEFINE VARIABLE cWordIndex AS CHARACTER NO-UNDO. DEFINE VARIABLE hField AS HANDLE NO-UNDO. DEFINE VARIABLE htField AS HANDLE NO-UNDO. DEFINE VARIABLE cField AS CHARACTER NO-UNDO. DEFINE VARIABLE cValue AS CHARACTER NO-UNDO. DEFINE VARIABLE cIndexFields AS CHARACTER NO-UNDO. DEFINE VARIABLE cFunction AS CHARACTER NO-UNDO. outilitiesHandler = NEW utilitiesHandler(). // // Ermitteln des Tabellennamens, ob die Tabelle das Feld "company" und/oder das Feld "active" enthält // outilitiesHandler:evaluateFile( INPUT-OUTPUT oJsonIdent , OUTPUT cFileName , OUTPUT lCompany , OUTPUT lActive , OUTPUT lWordindex , INPUT-OUTPUT httKeyFields , INPUT-OUTPUT httPrimaryIndex ). cFieldReplace = SUBSTITUTE('&1_' , cFileName). cKeyFieldReplace = SUBSTITUTE('keyfield_&1_', cFileName). cFilterReplace = SUBSTITUTE('filter_&1_' , cFileName). lOK = outilitiesHandler:getKeyFields( INPUT oJsonIdent , OUTPUT cKeyFields , OUTPUT cKeyValues ). createTempTable( INPUT oJsonIdent ). httTable:READ-JSON('JsonObject', oJsonRecord) NO-ERROR. httTable:FIND-FIRST('', NO-LOCK). // // Primary-Index-Fields für WHERE-Statement // CREATE BUFFER hBuffer FOR TABLE cFileName. cIndexFields = outilitiesHandler:getPrimaryIndexFields( INPUT cFileName ). // // Erzeugen von Where-Statement für UNIQUE-Find // cWhere = ''. DO i1 = 1 TO NUM-ENTRIES(cIndexFields, ';'): cField = ENTRY(i1, cIndexFields, ';'). hField = httTable:BUFFER-FIELD(cField):HANDLE. CASE hField:DATA-TYPE: WHEN 'character' THEN cValue = QUOTER(hField:BUFFER-VALUE). WHEN 'logical' THEN cValue = STRING(hField:BUFFER-VALUE,"true/false"). WHEN 'date' THEN cValue = STRING(DATE(hField:BUFFER-VALUE)). OTHERWISE cValue = hField:BUFFER-VALUE. END CASE. cWhere = cWhere + (IF cWhere = '' THEN 'WHERE ' ELSE ' AND ') + SUBSTITUTE('&1.&2 = ', cFileName, cField) + cValue. END. lRetVal = FALSE. REPEAT TRANSACTION ON ERROR UNDO, LEAVE: lOK = hBuffer:FIND-UNIQUE(cWhere) NO-ERROR. IF NOT hBuffer:AVAILABLE THEN DO: outilitiesHandler:createErrorBox( INPUT oJsonIdent , INPUT '2000' , INPUT '' , OUTPUT oJsonMessageBox ). oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('success' , FALSE ). oJsonReturn:ADD('showMessage' , oJsonMessageBox). RETURN TRUE. END. DO WHILE lActive : hField = hBuffer:BUFFER-FIELD('active') NO-ERROR. IF NOT VALID-HANDLE(hField) THEN LEAVE. IF hField:BUFFER-VALUE = TRUE THEN LEAVE. htField = httTable:BUFFER-FIELD('active') NO-ERROR. IF NOT VALID-HANDLE(htField) THEN LEAVE. IF hField:BUFFER-VALUE = FALSE AND htField:BUFFER-VALUE = TRUE THEN LEAVE. outilitiesHandler:createQuestionBox( INPUT oJsonIdent , INPUT '2000' , INPUT '' , INPUT 'active' , INPUT 'true' , INPUT hBuffer , OUTPUT oJsonMessageBox ) NO-ERROR. oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('success' , TRUE ). oJsonReturn:ADD('record' , oJsonRecord:GetJsonObject('record') ). oJsonReturn:ADD('askQuestion' , oJsonMessageBox ). RETURN TRUE. END. DO ii = 1 TO httTable:NUM-FIELDS: hField = hBuffer:BUFFER-FIELD(ii):HANDLE NO-ERROR. IF ERROR-STATUS:ERROR OR NOT VALID-HANDLE(hField) THEN NEXT. htField = httTable:BUFFER-FIELD(ii):HANDLE NO-ERROR. IF htField:BUFFER-VALUE = hField:BUFFER-VALUE THEN NEXT. hField:BUFFER-VALUE = htField:BUFFER-VALUE. END. hField = hBuffer:BUFFER-FIELD('updated_at'):HANDLE NO-ERROR. IF NOT ERROR-STATUS:ERROR AND VALID-HANDLE(hField) THEN hField:BUFFER-VALUE = NOW. hField = hBuffer:BUFFER-FIELD('wordindex'):HANDLE NO-ERROR. IF NOT ERROR-STATUS:ERROR AND VALID-HANDLE(hField) THEN DO: cWordIndex = outilitiesHandler:createWordindex( INPUT hBuffer ). hField:BUFFER-VALUE = cWordIndex. END. oJsonData = NEW JsonObject(). oJsonArray = NEW JsonArray (). httTable:BUFFER-COPY(hBuffer). httTable:WRITE-JSON('JsonObject', oJsonData). oJsonArray = oJsonData:GetJsonArray('record'). oJsonData = oJsonArray:GetJsonObject(1). hBuffer:BUFFER-RELEASE (). lRetVal = TRUE. LEAVE. END. IF lRetVal THEN DO: oJsonReturn = NEW JsonObject(). oJsonReturn:ADD('success', TRUE ). oJsonReturn:ADD('record' , oJsonData). outilitiesHandler:createInfoBox( INPUT oJsonIdent , INPUT '2003' , INPUT '' , OUTPUT oJsonMessageBox ) NO-ERROR. oJsonReturn:ADD('showMessage' , oJsonMessageBox). END. IF NOT lRetVal THEN DO: oJsonMessage = NEW JsonObject(). oJsonMessage:ADD('success', FALSE). oJsonMessage:ADD('message', lcMessage). oJsonMessage:WRITE(lcJsonString, FALSE). oJsonReturn = oJsonMessage. END. RETURN lRetVal. CATCH e AS Progress.Lang.Error: END CATCH. FINALLY: END FINALLY. END METHOD. DESTRUCTOR PUBLIC adminprogsHandler ( ): END DESTRUCTOR. END CLASS.