Populate Backend Database

Description

This Section demonstrates adding Post Method to Populate the Tables with new records.

Part of the http standard is the 'method' type on the http request.

When a user navigates to a web page, the http method has a value of 'GET'.

When a user hits the 'SUBMIT' button on a form, the http method is set to a value of 'POST'.

The http 'method' can be retrieved using the request.request_method field, and if the value is 'POST', the posted data can be retrieved through the request.body field.

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 ti as sql::TableInfo
	cn.GetTableInfo(ti,tablename)

	dim jsd as extension::JSON
	jsd.setJson(request.body)
	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

Note the use of the extension::JSON class to parse the JSON packet that is passed insert representing the fields we want to set in the record we add.

For example, if request.body contained the following JSON:

{
   "ProductName" : "Tennis Racket",
   "UnitPrice" : "34.99"
}

When 'ProductName' and 'UnitPrice' are retrieved from ti.column[i].name, since hasProperty() returns true for these fields since they exist in the JSON, the fields values will be retrieved with the jsd.GetProperty() call, and set into the SQL arguments.

While the SQL arguments are being populated, the column names and values (references to the arguments) are built as well.

In this case, the sql get set to insert into Products (ProductName,UnitPrice) values (:ProductName,:UnitPrice).

Now we have an A5W page that defines a service endpoint that can get records, as well as add new records.

The full page with the changes applied.

<%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 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 ti as sql::TableInfo
        cn.GetTableInfo(ti,tablename)

		dim jsd as extension::JSON
		jsd.setJson(request.body)
		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

	 if cn.Execute(sql,args) then
        dim rs as sql::ResultSet = cn.ResultSet
        if request.request_method = "POST" then
		    if rs.CallResult.LastInsertedIdentity = "" then
				? "{ \"identity\" : \"" + rs.Data(1) + "\" }"
			else      
	            ? "{ \"identity\" : \""+rs.CallResult.LastInsertedIdentity+"\" }"
			end if	
        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

Adding a Record using Curl Request

Now that the endpoint handles 'POST' we can use it to insert a record.

use the Curl '-d' option (followed by the JSON string) to send the POST record request to the service endpoint.

>curl -d "{ \"ProductName\" : \"Foozeball\" }" "http://127.0.0.1:8081/service_endpoint.a5w?tablename=products"
{ "identity" : "90" }

>curl "http://127.0.0.1:8081/service_endpoint2.a5w?tablename=products&primarykey=90"
{
    "items": [
        {
            "ProductID": "90",
            "ProductName": "Foozeball",
            "SupplierID": null,
            "CategoryID": null,
            "QuantityPerUnit": null,
            "UnitPrice": "0",
            "UnitsInStock": "0",
            "UnitsOnOrder": "0",
            "ReorderLevel": "0",
            "Discontinued": "F"
        }
    ]
}