Adding Update and Delete
Description
Now we have a service endpoint that allows us to List, Create , Update and Delete Records from both a Customers and Products Tables.
To add other actions, we can change the contents of our JSON packet to include an 'action' member.
Add dim action as c = "get" Above the handling for the 'POST' method
Instead of assuming the JSON is the record to be added, change the packet to include the 'action' at the top level and move the content into a 'data' field.
dim jso as extension::JSON
jso.setJson(request.body)
action = jso.getProperty("action")
dim ti as sql::TableInfo
cn.GetTableInfo(ti,tablename)
if action = "insert" then
dim jsonData as c = jso.getPropertyString("data")
if jsonData <> "" then
dim jsd as extension::JSON
jsd.setJson(jsonData)
if jsd.isObject() then
dim columns as c = ""
dim values as c = ""
for i = 1 to ti.Column.Count
dim columnName as c = ti.Column[i].name
if jsd.hasProperty(columnName) then
args.Set(columnName,jsd.getProperty(columnName))
columns = columns + columnName + ","
values = values + ":" + columnName + ","
end if
next
if columns <> "" then
columns = rtrim(columns,",")
values = rtrim(values,",")
sql = "insert into "+tablename+" ("+columns+") values ("+values+")"
else
? "{ \"error\" : \"No columns specified \" }"
end
end if
end if
else
? "{ \"error\" : \"No data specified \" }"
end
end if
else if action = "update" then
dim jsonData as c = jso.getPropertyString("data")
if jsonData <> "" then
dim jsd as extension::JSON
jsd.setJson(jsonData)
if jsd.isObject() then
dim columns as c = ""
dim values as c = ""
for i = 1 to ti.Column.Count
dim columnName as c = ti.Column[i].name
if jsd.hasProperty(columnName) then
args.Set(columnName,jsd.getProperty(columnName))
columns = columns + columnName+" = :"+ columnName + ","
end if
next
if columns <> "" then
columns = rtrim(columns,",")
sql = "update "+tablename+" set "+columns+" where "+primaryKeyName+" = :PKey"
else
? "{ \"error\" : \"No columns specified \" }"
end
end if
end if
else
? "{ \"error\" : \"No data specified \" }"
end
end if
else if action = "delete" then
if primaryKeyName = "" then
? "{ \"error\" : \"Delete action requires primary key\" }"
end
end if
sql = "delete from "+tablename+" where "+primaryKeyName+" = :PKey"
else
? "{ \"error\" : \"must specify action of insert, update , or delete\" }"
end
end ifTo the logic that processes the result we now need to handle 'update and delete' separately from 'insert'.
dim rs as sql::ResultSet = cn.ResultSet
if action = "insert" then
if rs.CallResult.LastInsertedIdentity = "" then
? "{ \"identity\" : \"" + rs.Data(1) + "\" }"
else
? "{ \"identity\" : \""+rs.CallResult.LastInsertedIdentity+"\" }"
end if
else if action = "update" .or. action = "delete" then
? "{ \"handled\" : true }"
else
dim responseJson as c = rs.ToJSONObjectSyntax()
responseJson = "{ \"items\" : [" + strtran( alltrim(responseJson) , crlf(), ","+crlf() ) + "] }"
? json_reformat( responseJson )
end
end ifSince we are adding an extra level, with 'action' to specify the operation we want to do, the packet to insert the record from the previous example now becomes:
{
"action" : "insert" ,
"data" : {
"ProductName" : "Tennis Racket",
"UnitPrice" : "34.99"
}
}The Page with the added 'update' and 'delete' methods.
<%a5
dim tablename as c
dim primaryKeyName as c
' Validate the tablename
if eval_valid("request.variables.tablename") then
tablename = request.variables.tablename
if tablename <> "Customers" .and. tablename <> "Products" then
? "{ \"error\" : \"Cannot Access table "+tablename+"\" }"
end
end if
if tablename = "Products" then
primaryKeyName = "ProductID"
else
primaryKeyName = "CustomerID"
end if
else
? "{ \"error\" : \"No tablename specified \" }"
end
end if
dim args as sql::Arguments
dim sql as c = "select * from "+tablename
if eval_valid("request.variables.primarykey") then
args.Set("Pkey",request.variables.primarykey)
sql = sql + " where "+primaryKeyName+" = :PKey"
end if
dim action as c = "get"
dim cn as sql::Connection
cn.PortableSQLEnabled = .t.
if cn.Open("::Name::Northwind") then
if request.request_method = "POST" then
' Add a record
if json_validate(request.body) <> "" then
? "{ \"error\" : \"Body is not valid JSON \" }"
end
end if
dim jso as extension::JSON
jso.setJson(request.body)
action = jso.getProperty("action")
dim ti as sql::TableInfo
cn.GetTableInfo(ti,tablename)
if action = "insert" then
dim jsonData as c = jso.getPropertyString("data")
if jsonData <> "" then
dim jsd as extension::JSON
jsd.setJson(jsonData)
if jsd.isObject() then
dim columns as c = ""
dim values as c = ""
for i = 1 to ti.Column.Count
dim columnName as c = ti.Column[i].name
if jsd.hasProperty(columnName) then
args.Set(columnName,jsd.getProperty(columnName))
columns = columns + columnName + ","
values = values + ":" + columnName + ","
end if
next
if columns <> "" then
columns = rtrim(columns,",")
values = rtrim(values,",")
sql = "insert into "+tablename+" ("+columns+") values ("+values+")"
else
? "{ \"error\" : \"No columns specified \" }"
end
end if
end if
else
? "{ \"error\" : \"No data specified \" }"
end
end if
else if action = "update" then
dim jsonData as c = jso.getPropertyString("data")
if jsonData <> "" then
dim jsd as extension::JSON
jsd.setJson(jsonData)
if jsd.isObject() then
dim columns as c = ""
dim values as c = ""
for i = 1 to ti.Column.Count
dim columnName as c = ti.Column[i].name
if jsd.hasProperty(columnName) then
args.Set(columnName,jsd.getProperty(columnName))
columns = columns + columnName+" = :"+ columnName + ","
end if
next
if columns <> "" then
columns = rtrim(columns,",")
sql = "update "+tablename+" set "+columns+" where "+primaryKeyName+" = :PKey"
else
? "{ \"error\" : \"No columns specified \" }"
end
end if
end if
else
? "{ \"error\" : \"No data specified \" }"
end
end if
else if action = "delete" then
if primaryKeyName = "" then
? "{ \"error\" : \"Delete action requires primary key\" }"
end
end if
sql = "delete from "+tablename+" where "+primaryKeyName+" = :PKey"
else
? "{ \"error\" : \"must specify action of insert, update , or delete\" }"
end
end if
end if
if cn.Execute(sql,args) then
dim rs as sql::ResultSet = cn.ResultSet
if action = "insert" then
if rs.CallResult.LastInsertedIdentity = "" then
? "{ \"identity\" : \"" + rs.Data(1) + "\" }"
else
? "{ \"identity\" : \""+rs.CallResult.LastInsertedIdentity+"\" }"
end if
else if action = "update" .or. action = "delete" then
? "{ \"handled\" : true }"
else
dim responseJson as c = rs.ToJSONObjectSyntax()
responseJson = "{ \"items\" : [" + strtran( alltrim(responseJson) , crlf(), ","+crlf() ) + "] }"
? json_reformat( responseJson )
end
end if
else
dim resp.error as c = cn.CallResult.Text
? json_generate(resp)
end if
else
dim resp.error as c = cn.CallResult.Text
? json_generate(resp)
end if
%>Now update the record we added in the previous example using the new 'update' action.
>curl -d "{ \"action\" : \"update\" , \"data\" : { \"UnitPrice\" : \"3.99\" } }" "http://127.0.0.1:8081/service_endpoint.a5w?tablename=products&primarykey=90"
{ "handled" : true }