M
Maciej S.
Guest
I have a test table called Cities. Creation script is as follows:
ADD TABLE "Cities"
AREA "Schema Area"
LABEL "Cities"
DUMP-NAME "Cities"
ADD FIELD "ID" OF "Cities" AS integer
DESCRIPTION "ID"
INITIAL 0
LABEL "ID"
COLUMN-LABEL "ID"
ORDER 10
ADD FIELD "City" OF "Cities" AS character
DESCRIPTION "City name"
FORMAT "x(30)"
INITIAL ""
LABEL "Cities"
MAX-WIDTH 30
COLUMN-LABEL "Cities"
ORDER 20
ADD INDEX "IxID" ON "Cities"
AREA "Schema Area"
UNIQUE
PRIMARY
INDEX-FIELD "ID" ASCENDING
.
PSC
cpstream=1250
.
0002253205
I have added one record to this table:
create Cities.
assign
Cities.ID = 1
Cities.City = "Boston".
FOR EACH routine shows proper result with one record.
I have created some REST project with classic server settings for learning and testing purposes. All servers and configurations are standard as installator configured them. I have added some procedures to AppServer folder (file: test.p) and created temp-table within it. Full procedure code:
BLOCK-LEVEL ON ERROR UNDO, THROW.
DEFINE TEMP-TABLE ttCities LIKE Cities.
@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
PROCEDURE readCities:
DEFINE OUTPUT PARAMETER TABLE FOR ttCities.
FOR EACH Cities NO-LOCK:
CREATE ttCities.
BUFFER-COPY Cities TO ttCities.
END.
END PROCEDURE.
@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
PROCEDURE putCities:
DEFINE INPUT-OUTPUT PARAMETER TABLE FOR ttCities.
END PROCEDURE.
Procedure compiles well, annotations are added by Define Service Interface functionality in OpenEdge. In Defined Services node I have created mappings for parameters (I will omit readCities because it works well) for putCities and PUT verb:
My client code is very basic - taken from some Progress KB article and project has OpenEdge.Net.pl libraries included in PROPATH:
BLOCK-LEVEL ON ERROR UNDO, THROW.
USING Progress.Json.ObjectModel.JsonObject.
USING Progress.Json.ObjectModel.*.
USING Progress.Json.ObjectModel.ObjectModelParser.
USING Progress.Lang.Object.
USING OpenEdge.Core.WidgetHandle.
USING OpenEdge.Core.String.
USING OpenEdge.Net.HTTP.IHttpRequest.
USING OpenEdge.Net.HTTP.IHttpResponse.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.RequestBuilder.
DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
DEFINE VARIABLE oEntity AS Object NO-UNDO.
DEFINE VARIABLE lcHTML AS LONGCHAR NO-UNDO.
DEFINE VARIABLE hXmlDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hCities AS HANDLE NO-UNDO.
DEFINE VARIABLE oJson AS JsonObject NO-UNDO.
DEFINE VARIABLE lReturnValue AS LOGICAL NO-UNDO.
DEFINE TEMP-TABLE ttCities LIKE Cities.
hCities = TEMP-TABLE ttCities:HANDLE.
create ttCities.
assign
ttCities.ID = 1
ttCities.City = "Boston".
oJson = NEW JsonObject().
lReturnValue = oJson:Read(hCities).
oRequest = RequestBuilderut('http://127.0.0.1:8980/REST6/rest/REST6/PutCities', oJson):Request.
oResponse = ClientBuilder:Build():Client:Execute(oRequest).
MESSAGE oResponse:StatusCode oResponse:StatusReason VIEW-AS ALERT-BOX.
/* some other code to parse response */
This code compiles well, but calling it give this error: Cities already exists with ID 1.
I suppose that procedure is called on the server but can't update DB record because of this error. As far as I know calling PUT method should perform update on record - not creating new one. In addition changing ttCities.ID to value 2 creates new record.
So my question is simple: how to handle with this? Should I write my own custom logic in putCities procedure?
Any help will be appreciated.
Continue reading...
ADD TABLE "Cities"
AREA "Schema Area"
LABEL "Cities"
DUMP-NAME "Cities"
ADD FIELD "ID" OF "Cities" AS integer
DESCRIPTION "ID"
INITIAL 0
LABEL "ID"
COLUMN-LABEL "ID"
ORDER 10
ADD FIELD "City" OF "Cities" AS character
DESCRIPTION "City name"
FORMAT "x(30)"
INITIAL ""
LABEL "Cities"
MAX-WIDTH 30
COLUMN-LABEL "Cities"
ORDER 20
ADD INDEX "IxID" ON "Cities"
AREA "Schema Area"
UNIQUE
PRIMARY
INDEX-FIELD "ID" ASCENDING
.
PSC
cpstream=1250
.
0002253205
I have added one record to this table:
create Cities.
assign
Cities.ID = 1
Cities.City = "Boston".
FOR EACH routine shows proper result with one record.
I have created some REST project with classic server settings for learning and testing purposes. All servers and configurations are standard as installator configured them. I have added some procedures to AppServer folder (file: test.p) and created temp-table within it. Full procedure code:
BLOCK-LEVEL ON ERROR UNDO, THROW.
DEFINE TEMP-TABLE ttCities LIKE Cities.
@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
PROCEDURE readCities:
DEFINE OUTPUT PARAMETER TABLE FOR ttCities.
FOR EACH Cities NO-LOCK:
CREATE ttCities.
BUFFER-COPY Cities TO ttCities.
END.
END PROCEDURE.
@openapi.openedge.export(type="REST", useReturnValue="false", writeDataSetBeforeImage="false").
PROCEDURE putCities:
DEFINE INPUT-OUTPUT PARAMETER TABLE FOR ttCities.
END PROCEDURE.
Procedure compiles well, annotations are added by Define Service Interface functionality in OpenEdge. In Defined Services node I have created mappings for parameters (I will omit readCities because it works well) for putCities and PUT verb:
- Resources: /PutCities
- Verb Association: Verb='PUT' -> test..putCities
- Mapping Definitions for Input: parameter ttCities is connected to request HTTP Message -> Body section directly (not to body parameter)
- Mapping Definitions for Output: response ttCities is connected to Interface Parameters -> ttCities
My client code is very basic - taken from some Progress KB article and project has OpenEdge.Net.pl libraries included in PROPATH:
BLOCK-LEVEL ON ERROR UNDO, THROW.
USING Progress.Json.ObjectModel.JsonObject.
USING Progress.Json.ObjectModel.*.
USING Progress.Json.ObjectModel.ObjectModelParser.
USING Progress.Lang.Object.
USING OpenEdge.Core.WidgetHandle.
USING OpenEdge.Core.String.
USING OpenEdge.Net.HTTP.IHttpRequest.
USING OpenEdge.Net.HTTP.IHttpResponse.
USING OpenEdge.Net.HTTP.ClientBuilder.
USING OpenEdge.Net.HTTP.RequestBuilder.
DEFINE VARIABLE oRequest AS IHttpRequest NO-UNDO.
DEFINE VARIABLE oResponse AS IHttpResponse NO-UNDO.
DEFINE VARIABLE oEntity AS Object NO-UNDO.
DEFINE VARIABLE lcHTML AS LONGCHAR NO-UNDO.
DEFINE VARIABLE hXmlDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hCities AS HANDLE NO-UNDO.
DEFINE VARIABLE oJson AS JsonObject NO-UNDO.
DEFINE VARIABLE lReturnValue AS LOGICAL NO-UNDO.
DEFINE TEMP-TABLE ttCities LIKE Cities.
hCities = TEMP-TABLE ttCities:HANDLE.
create ttCities.
assign
ttCities.ID = 1
ttCities.City = "Boston".
oJson = NEW JsonObject().
lReturnValue = oJson:Read(hCities).
oRequest = RequestBuilderut('http://127.0.0.1:8980/REST6/rest/REST6/PutCities', oJson):Request.
oResponse = ClientBuilder:Build():Client:Execute(oRequest).
MESSAGE oResponse:StatusCode oResponse:StatusReason VIEW-AS ALERT-BOX.
/* some other code to parse response */
This code compiles well, but calling it give this error: Cities already exists with ID 1.
I suppose that procedure is called on the server but can't update DB record because of this error. As far as I know calling PUT method should perform update on record - not creating new one. In addition changing ttCities.ID to value 2 creates new record.
So my question is simple: how to handle with this? Should I write my own custom logic in putCities procedure?
Any help will be appreciated.
Continue reading...