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 if

To 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 if

Since 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 }