API: Actn
Filename:
fwpActn_recordData.ctyp
Released With:
5.0.0
Current Version:
2.2.1
Status: Active
Min Lasso Tested: 8.1.0
Max Lasso Tested: 8.5.3
Related:
fwp_recordData->getRecordUsingLock
fwp_recordData->updateUsingLock
fwp_recordData->updateUsingKeyVal
fwp_recordData->deleteUsingLock
fwp_recordData->deleteUsingKeyVal
Still don't get it?
Check out the talk list archives, or join and ask your questions.
Documentation Error or Request?
Email documentation corrections or comments
The fwp_recordData custom type provides a general purpose interface for several data management tasks common to database driven web pages. It provides member tags for adding, deleting, updating, and selecting records, as well as some additional utility functions.
Currently fwp_recordData works for SQL databases only. For FileMaker, use the older fwp_rcrdData custom type. Eventually, the FMP interfacing may be updated to work as an adaptor to fwp_recordData, but fw_rcrdData is already very similar.
The fwp_recordData API is tiered into three components.

The first component is an application-specific table configuration file tableModel_{tableName}.cnfg which maps field names to form input names and lasso data types, and includes input validation rules for each field. These configuration files use an-demand loading so that their first access goes through a parsing routine to load them into a global var structure, but subsequent accesses go straight to the global var which we call a table mapper.
The second component is this custom type. The primary purpose for this custom type is to wrap supporting routines (which are called action shells) around the core database action to integrate comprehensive error management, data input validation, and record locking functionalities into a single, easy-to-use object. The fwp_recordData object also helps to automate several user interface responses to these actions. The code in fwp_recordData is ignorant of query syntax, and focuses strictly on inputs, interfacing logic, and results. The fwp_recordData data type doesn't know how to query a table. It only knows what type of query it needs at given points in its control logic. That brings us to the third layer.
The third component we call a database adaptor. This is the layer that contains the SQL syntax specifics. The fwp_recordData to adaptor interface is defined with a specific set of methods. Each method constructs a whole SQL query or a portion of query that the fwp_recordData ctype will request from the connector. Adaptors can be written for a specific database syntax to therefore support multiple database servers with little or no change to much of the application code which uses the fwp_recordData interface.
The fwp_recordData data type is not intended to be the only method a developer uses with the pageblocks framework to interface to a database, but rather it is a tool available to simplify the implementation of many commonly integrated functions. While the fwp_recordData API can handle complex SQL queries, there are going to be occassions where using Lasso's ability to communicate directly with the database will be advantageous. For example, transactions should be written out manually with Lasso's inline tags or a combination of the inline tag and fwp_recordData calls. The fwp_recordData member tags are not yet written to support transactions internally.
Aside from the logic integration capabilities, a main purpose of fwp_recordData is to automate the writing of INSERT, DELETE, UPDATE, and SELECT statements in response to form interaction and a few simple tag parameters. The SELECT actions can also be hand specified in detail to allow for complex relational SQL queries.
By consolidating these tasks and supporting routines into a single general purpose custom type, the programmer has a stable and easy-to-use interface for many data tasks, and can focus development efforts on the more complex data and object management issues that are application specific.
Data Storage and SELECT Options
This type's primary task is not to store data, but rather to simplify the interface for managing data actions, though there are some data storage features. Data retrieved for the object are stored in Lasso's named inline containers by default. Optionally, data can be stored to an array of arrays (essentially just a reference to LP8's records_array), or to an array of maps which provides an easier to read interface than records_array. Queries which result in single record selections can also generate an individual page var for each field.
Each dataset created by an fwp_recordData SELECT contains ->'foundCount', ->'showFirst', and ->'showLast' properties as equivalents to the built-in lasso tags. Also, each SELECT action returns the named inline name ->'inlinename' and other status data such as errors, query time, and more.
Subclassing for Custom Models
While the main goal of fwp_recordData is to provide a query interface, it can be subclassed so the developer can create custom models with all the SQL interfacing built in. This in fact is the preferred way to provide custom business rules that should be applied to data, and is the means by which the developer can write more complex methods for handling relational data models. (Eventually fwp_recordData will be extended to recognize models built from relational data, but for now, the developer will have to handle that).
We begin by creating a {link=table mapper configuration file:::/refc/tableModel_{tableName}} for each table that will be interfaced with using the fwp_recordData ctype.
With those config files in place, there are two steps to using the fwp_recordData custom type. First initializing a new object, and then using the member tags for that object to engage specific actions. To initialize a new object requires the following:
var:'objectVarName'=(fwp_recordData:tableName)
Each member tag of the type has unique parameter requirements, but the typical structure is seen in the ->select and ->upadteUsingLock member tags:
Selects a specific record:
$objectVarName->(select: -select = fieldList, -keyval = keyValue);
Selects a record set based on full SQL query
$objectVarName->(select: -select = fieldList, -from = full sql from clause, -where = full sql where clause, -limit = maxRcrds, -orderby = sortDetails);
Selects a record set based on form inputs:
$objectVarName->(select: -inputs = inputsList, -select = fieldList, -where = 'form');
Updates a specified record which was previously locked:
$objectVarName->(updateUsingLock: -lockval = keyValue, -confirm = fieldList);
Updates a specified record regardless of lock status:
$objectVarName->(update: -keyfld = and field name, -keyval = keyValue, -confirmFields = fieldList);
In each case, the query is built based on the variables from the table mapper which been declared. So, if the table has a field named firstName and a mapper input name for that field is m_nameF, then the query builder will detect the availability of $m_nameF and use that to build the specific SELECT, INSERT, or UPDATE syntax.
Detailed requirements for each member tag is available with the links below.
To create an object variable of the fwp_recordData type, only the actual name of the table is needed as an input.
Member Tags
->select = The select tag has a number of capabilities to execute literal queries or to automate a variety of queries. By leveraging the information in the tableModel_ config file, the select tag can fill in the blanks for just about anything not provided through parameters. This includes automating queries for complex form-driven searches. Results can be returned in any of four formats.
->getRecordUsingLock = selects a record and attempts to lock it to reserve it for updating or deleting. If lock is not possible (already locked), then data is still retrieved for use in an alternative display. Also can convert all fields to vars for use in the display.
->updateUsingLock = Updates a record identified by a lock value. The record must have already been locked, and that lock ID passed to this tag. This tag along with ->getRecordUsingLock provides full pessimistic lock control. The update sequence of events will include triggering the validation tags, updating the record, resetting the lock, logging the action (if turned on), and of course trapping any errors to report.
->updateUsingKeyVal = Updates a record identified by any key field/value pair. It is not necessary that the record have been previously locked. If the record has been locked, and that lock is still valid, the update will be aborted. This is considered honoring an active lock. This tag offers the opportunity to do a hybrid of optimistic/pessimistic lock control. The update sequence of events will include triggering the validation tags, updating the record, resetting the lock, logging the action (if turned on), and of course trapping any errors to report.
->update = Updates a record identified by any key field/value pair. It is not necessary that the record have been previously locked. This is an "update at will" process. If the record has been locked, and that lock is still valid, this tag will ignore that lock. This tag offers the opportunity to do no lock control at all or to use optimistic lock control if the developer includes his own code to maintain an update counter field. The update sequence of events will include triggering the validation tags, updating the record, resetting the lock, logging the action (if turned on), and of course trapping any errors to report.
->deleteUsingLock = Deletes a record identified by a lock value. The record must have already been locked, and that lock ID passed to this tag. This tag, along with ->getRecordUsingLock, therefore provides full pessimistic lock control (preventing the updating of this record while it is staged to be deleted). The sequence of events will include retrieving the confirmFields data, deleting the record, logging the action (if turned on), and of course trapping any errors to report.
->deleteUsingKeyVal = Deletes a record identified by any key field/value pair. It is not necessary that the record have been previously locked. If the record has been locked, and that lock is still valid, the delete will be aborted. This is considered honoring an active lock. This tag offers the opportunity to do a hybrid of optimistic/pessimistic lock control. The sequence of events will include retrieving the confirmFields data, deleting the record, logging the action (if turned on), and of course trapping any errors to report.
->delete = Deletes a record identified by any key field/value pair. It is not necessary that the record have been previously locked. This is a "delete at will" process. If the record has been locked, and that lock is still valid, this tag will ignore that lock. This tag offers the opportunity to do no lock control at all or to use optimistic lock control if the developer includes his own code to maintain an update counter field. The sequence of events will include retrieving the confirmFields data, deleting the record, logging the action (if turned on), and of course trapping any errors to report.
->add = Inserts a record identified by the keyfield value. The sequence of events will include triggering the validation tags, inserting the record, logging the action (if turned on), retrieving confirmation data, and of course trapping any errors to report.
->duplicate = Copies a record identified by the keyfield value, and inserts a duplicate of it with a new key value. The sequence of events will include inserting the record, logging the action (if turned on), retrieving confirmation data, and of course trapping any errors to report.
->validate = This tag is automatically triggered by ->add, ->update, ->updateUsingKeyfld, and ->updateUsingLock just after an internal ->fw_validateInputs tag has processed the table mapper input validation rules. The built-in tag does nothing more than return ->'rulesAreInvalid' = false. In order to make use of this tag and write custom validation rules (outside the scope of those that could be handled through custom validation codes), the fwp_recordData type needs to be subclassed.
->sql = Accepts a completely formed SQL query. The main purpose for using this member tag instead of a standard Lasso inline:-sql tag is that this one includes error trapping behavior identical to all other member tags, and will also log the query. Additionally, it can return retrieved records as a named inline, an array of arrays, or an array of maps. It also supports several of the instance vars.
Subclassing fwp_recordData
Developers are encouraged to use fwp_recordData as first generation instances or as a parent class for customized application-specific domain models.
Subclassing the fwp_recordData ctype allows the developer to create customized validations, and to write custom methods and instance vars to represent application specific needs not covered by the built-in tags.
A simple example of a subclassed ctype would be:
define_type: 'myModel', 'fwp_recordData'; define_tag:'validate'; if: $m_expDate < date; (self->'rulesAreInvalid') = true; $fw_inputErrorMsgs->(insert:'m_expDate' = 'An expiration date must be after today\'s date.'); /if; /define_tag; define_tag:'defaultExpirationDate', -required = 'productType'; select: #productType; case: 'fruit'; return: date_add: date, -days = 5; case: 'veggie'; return: date_add: date, -days = 10; case: 'frozenveggie'; return: date_add: date, -days = 180; case; return: date_add: date, -days = 7; /select; /define_tag; /define_type;
Public Instance Variables
The object also has the following properties (some of which apply only when certain member tags are used):
->'foundCount' - (integer) : the number of found records from a SELECT (i.e. it's the 15 of "5 through 10 of 15")
->'showFirst' - (integer) - the sequence number of the first record returned in a SELECT set (i.e. it's the 5 of "5 through 10 of 15")
->'showLast' - (integer) : the sequence number of the last record returned in a SELECT set (i.e. it's the 10 of "5 through 10 of 15")
->'inlineName' (string) : the ID value of the named inline that a returned record set is stored under
->'records' - (array) : an optional record set stored as either an array of arrays or an array of maps as dictated by the -withRecordsArrays or -withRecordsMaps options in a SELECT
->'lock' - (string) : the ID value of record lock if acquired
->'error' - (boolean) : indicates whether the member tag generated an error
->'errors' - (array) : an array of pairs containing the error codes and comment strings
->'formIsValid' - (boolean) : not yet in use
->'inputsAreInvalid' - (boolean) : indicates whether the submitted fields passed the basic validation requirements specified in the tableModel_ config file
->'rulesAreInvalid' - (boolean) : indicates whether the submitted form passed the rules defined in the ->validate member tag of a subclassed custom type based on fwp_recordData
->'queryString' - (string) : the actual SQL string executed by the member tag (sometimes more than one actual query is generated, but this will be the one that is the core of the tag's purpose)
->'queryTime' - (string) : the time in milliseconds it took for all SQL queries used within the member tag to execute
->'tagTime' - (string) : the time in milliseconds it took for the entire member tag code to execute
The following is an example of the table mapper configuration file. This sample file will be used throughout the ctype code examples below.
#! dbTbl5
# filename = tblDefn_fwpuserauth.cnfg
{serverType___ mysql }
{databaseName___ fwpdemo }
{tableName___ fwpuserauth }
{keyfield___ rcrdNo }
{lockField___ rcrdLockID }
{tableModel___
#inputName fieldName dataType validation codes
#------------ ----------------- --------- -----------------------------
rcrdNo rcrdNo string
rcrdCreated rcrdCreated string
rcrdCreatedBy rcrdCreatedBy string
rcrdModified rcrdModified string
rcrdModifiedBy rcrdModifiedBy string
rcrdStatus rcrdApproved string
m_rLok rcrdLock string
rcrdLockID rcrdLockID string
rcrdLockTime rcrdLockTime string
rcrdLockOwnr rcrdLockOwnr string
m_rSessTime sessionTime string
m_rSessVars sessionVars string
m_rSessKprs sessionKeepers string
m_rSessProf sessionProfile string
m_uNameF userNameFirst string req, aspc, label=First Name
m_uNameL userNameLast string req, aspc, label=Last Name
m_uOrg userOrg string
m_uPhone userPhone string n
m_uEmail userEmail string req, email
m_uPw userPswd string
m_uHint userHint string req
m_uIns userLogins integer
m_uLastIn userLastLogin string
m_uTries userAttempts integer
m_uLokTime userLockTime string
m_uPwNew userPswdNew string
m_uPwDate userPswdCreated string
m_uPwHist userPswdHistory string
m_uHosts userHosts string
# these are inputs that are part of the model, but not part of the table
# these are usually interim form inputs used to collect pieces of what
# ultimately is inserted into a single field
i_uPhoneA - - req, n, len=3
i_uPhoneP - - req, n, len=3
i_uPhoneN - - req, n, len=3
i_uPhoneX - - n
i_up1 _ _
i_up2 _ _
} The below will generate $m_uNameF, $m_uNameL, and $m_uEmail for the record with a keyfield value of 'abcdefg'.
var:'myUser' = (fwp_recordData:'fwpuserauth'); $myUser->(select: -keyval = 'abcdefg', -select = 'userNameLast, userNameFirst, userEmail', -withMakeVars);
If a form has these inputs:
<input ..... name="m_uLastIn" ..... /> <input ..... name="m_uLastInOp" ..... /> <input ..... name="m_uNameL" ..... /> <input ..... name="m_uNameLOp" ..... /> <input ..... name="m_uIns" ..... /> <input ..... name="m_uInsOp" ..... />
and upon submission, we got the values of:
$m_uLastIn = '2005-06-15' $m_uLastInOp = 'lt' $m_uNameL = 'M' $m_uNameLOp = 'lt' $m_uLogins = '10' $m_uLoginsOp = 'gte'
and, we used the following code:
var:'userList' = (fwp_recordData:'fwpuserauth'); $userList->(select: -inputs = 'm_uNameL, m_uIns', -select = 'userNameLast, userNameFirst, userEmail, userLogins', -where = 'form', -withRecordsMaps);
then this query would automatically be constructed:
SELECT userNameLast, userNameFirst, userEmail, userLogins FROM fwpdemo.fwpuserauth WHERE userNameLast < 'M' AND m_uLogins >= 10
You'll notice that the query does not include the inputs for $m_uLastIn. Why? It was not included in the -inputs parameter. This is the safeguard against people rewriting a form to force the hand of the automated query generator.
Once our query has executed, we would have the following instance vars available too:
$userList->'foundcount' = 39 // or whatever the case may be $userList->'showFirst' = 1 $userList->'showLast' = 39 // or whatever the case may be $userList->'inlineName' = 'wh7snhjw9' // or some other ID $userList->'records' = an array of maps* $userList->'error' = false $userList->'errors' = (array) // empty array $userList->'querystring' = the above query $userList->'queryTime' = 3 // milliseconds or whatever the case may be $userList->'tagTime' = 10 // milliseconds or whatever the case may be * records are in arrays, fields are map pairs so, we'd have a 39 element array where each array member was a map with four keys of userNameLast, userNameFirst, userEmail, and userLogins
You've noticed that -inputs uses the config file inputNames, but -select uses real field names. In a perfect n-tiered world, every reference to the fields would be using the abstracted names. However, because -select allows full SQL query clauses, it would require a significant dose of processing to parse the more complex possibilities to swap out the abstract field names for the real field names. So, as it stands, I've left -select and -confirmFields to use real field names. I realize it can be a bit confusing but, I've learned to remember that -inputs means to use the form input names, otherwise, use real field names. So, in the logic code we do expose real field names (imperfect N-Tier), but in the display files it is possible to avoid real field names.
To lock a record and retrieve data for an update form:
var:'myUser' = (fwp_recordData:'fwpuserauth'); $myUser->(getRecordUsingLock: -select = 'userNameLast, userNameFirst, userEmail, userLogins', -keyval = $selectedUserID, -withMakeVars); var:'myLock' = $myUser->'lock'; // will be empty if lock attempt failed
Then to submit the update for that record:
var:'myUser' = (fwp_recordData:'fwpuserauth'); $myUser->(updateUsingLock: -lockval = $myLock, -inputs = 'm_uNameL, m_uNameF, m_uEmail'); // we're not updating userLogins, // but we fetched it to show in the form as static text
<?lassoscript
//............................................................................
//
// pageblocks: (c) 2002-2007 http://www.pageblocks.org/
//
//............................................................................
/*
{fileName= fwp_recordData.ctyp }
{rsrcType= type }
{rsrcName= fwp_recordData }
{rsrcHTTP= www.pageblocks.org/refc/fwp_recordData }
{lassoVrsnMin= 8.1.0 }
{lassoVrsnMax= 8.5.3 }
{author= Greg Willits }
{authorEmail= subscribe to pbTalk at www.pageblocks.org/talk/ }
{authorHTTP= www.pageblocks.org }
{desc= Creates a generic data type for SQL table data. }
{maintvsrn= 2.3.2 }
{maintrelease= 5.3 }
{maintdate= 2008-07-11}
{maintauthor= Nikolaj de Fine Licht }
{maintnotes= added keyword -useGet to tag validateInputs to force
tag to validate using GET params. Added the same keyword
to tag ->update and ->updateUsingLock}
{maintvsrn= 2.3.1 }
{maintrelease= 5.3 }
{maintdate= 2007-12-31}
{maintauthor= Nikolaj de Fine Licht }
{maintnotes= added tag 'addWithoutKeyval' to make add with no keyval
provided. Made approprite changes to
fwpActnAdaptor_mysql.ctyp as well. The new tag returns
LAST_INSERT_ID as a var named 'rcrdNo' which can be
retrieved right after the tag was called }
{maintvsrn= 2.3.0 }
{maintrelease= 5.3.0 }
{maintdate= 2007-08-04 }
{maintauthor= Greg Willits }
{maintnotes= added -wherePairs option to getRecordUsingLock.
added ->'validationResults'.
added ->showMsgsForInput.
added ->errorExistsForInput.
added ->fw_withRecordsMaps which creates the records
maps using the inputs names instead of fields names,
for backwards compatability -withRecordsMapsFields will
still generate the older version using field names.
Added a -quiet option to ->getRecordUsingLock.
Changed queryString from getRecordUsingLock to be the
query that gets the record (not the query that locks
the record). }
{maintvsrn= 2.2.2 }
{maintrelease= 5.2.5b }
{maintdate= 2007-07-31}
{maintauthor= Greg Willits }
{maintnotes= removed fw_ prefix from validateInputs }
{maintvsrn= 2.2.1 }
{maintrelease= 5.2.0 }
{maintdate= 2007-06-25}
{maintauthor= Greg Willits }
{maintnotes= added withoutDateStamp to ->update. This allows update to be
used to force unlock a record w/o altering modified status.
Changed some occurrences of error 5500 to 5113 }
{maintvsrn= 2.2.0 }
{maintrelease= 5.2.0 }
{maintdate= 2007-06-09}
{maintauthor= Greg Willits }
{maintnotes= updated debug and error handling systems.
Fixed bug in convertToFieldNames which was replacing
subwords and causing problems }
{maintvsrn= 2.1.0 }
{maintrelease= 5.1.7 }
{maintdate= 2007-05-25 }
{maintauthor= Greg Willits }
{maintnotes= added support for multiple locks using fw_recordLockStore }
{maintvsrn= 2.0.3 }
{maintrelease= 5.1.5 }
{maintdate= 2007-03-23 }
{maintauthor= Greg Willits }
{maintnotes= added queryParams ivar }
{maintvsrn= 2.0.2 }
{maintrelease= 5.1.5 }
{maintdate= 2007-02-18 }
{maintauthor= Greg Willits }
{maintnotes= changed occurence of error 50XX to 5505 }
{maintvsrn= 2.0.1 }
{maintrelease= 5.1.4 }
{maintdate= 2006-12-29 }
{maintauthor= Greg Willits }
{maintnotes= updated select method to move orderby, groupby, and limit
statements that remained as literal sql expressions into
the adaptor }
{maintvsrn= 2.0 }
{maintrelease= 5.1.4 }
{maintdate= 2006-11-14 }
{maintauthor= Greg Willits }
{maintnotes= Allows field names in all query clauses to be expressed
as the tableModel_ input names. }
{maintvsrn= 1.5.2 }
{maintrelease= 5.1.4 }
{maintdate= 2006-11-20 }
{maintauthor= Jolle Carlestam }
{maintnotes= added experimental support for GROUP BY handling in
SQL select queries. }
{maintvsrn= 1.5.1 }
{maintrelease= 5.1.3 }
{maintdate= 2006-11-09 }
{maintauthor= Greg Willits }
{maintnotes= fixed a bug in ->sql that referred to wrong local var
when -withRecordsMaps was used.
Added ->getFieldForInput and ->getInputForField
Changed all cases of sending a field list to makeVars
and recordsMaps to use field_names from the inline
Fixed a bug in withRecordsMaps, and cleaned out
some left over experimental code
Eliminated -fieldNames option from ->sql }
{maintvsrn= 1.5 }
{maintrelease= 5.1.0 }
{maintdate= 2006-09-27 }
{maintauthor= Greg Willits }
{maintnotes= Added -withMakeVars, -withRecordsArrays, -withRecordsMaps
to the ->sql tag. Refactored -withRecordsMaps into
a separate private tag.
Fixed bug with pageCount in ->select if perPage was 0 }
{maintvsrn= 1.4.1 }
{maintrelease= 5.1.0 }
{maintdate= 2006-09-25 }
{maintauthor= Greg Willits }
{maintnotes= fixed an issue that would not create the cookie name
using the application prefix defined in initMasters }
{maintvsrn= 1.4.0 }
{maintrelease= 5.1.0 }
{maintdate= 2006-09-12 }
{maintauthor= Greg Willits }
{maintnotes= Added pageCount and currentPage, and deprecated showFirst
and showLast in favor of firstRecord and lastRecord }
{maintvsrn= 1.3.1 }
{maintrelease= 5.1.0 }
{maintdate= 2006-08-28 }
{maintauthor= Greg Willits }
{maintnotes= Added a test for a comma in -limit so that
a '30,60' value could be submitted. Optimized
handling of found count in ->select. }
{maintvsrn= 1.3.0 }
{maintrelease= 5.1.0 }
{maintdate= 2006-08-21 }
{maintauthor= Greg Willits }
{maintnotes= added ->duplicate }
{maintvsrn= 1.2.1 }
{maintrelease= 5.1.0 }
{maintdate= 2006-06-06 }
{maintauthor= Greg Willits }
{maintnotes= changed params->find to params->contains
which is more efficient }
{maintvsrn= 1.2 }
{maintrelease= 5.1.0 }
{maintdate= 2006-05-26 }
{maintauthor= Greg Willits }
{maintnotes= converted timers to fwp_timer ctype,
added tagTrace statements,
updated some if blocks to ?,
refactored where clause to add it to update and delete }
{maintvsrn= 1.1.2 }
{maintrelease= 5.0.3 }
{maintdate= 2006-04-13 }
{maintauthor= Greg Willits }
{maintnotes= fixed a syntax bug in ->sql that works in 8.1 but will
cause problems in 8.5 }
{maintvsrn= 1.1.1 }
{maintrelease= 5.0.0 }
{maintdate= 2006-04-03 }
{maintauthor= Greg Willits }
{maintnotes= added use of fw_gUsePbUserAuth where needed }
{maintvsrn= 1.1.1 }
{maintrelease= 5.0.0 b8 }
{maintdate= 2006-03-01 }
{maintauthor= Greg Willits }
{maintnotes= added -expires to record lock cookie so that windows
users who close the browser instead of the document window
still have the cookie for a while }
{maintvsrn= 1.1 }
{maintrelease= 5.0.0 b5 }
{maintdate= 2006-02-02 }
{maintauthor= Greg Willits }
{maintnotes= added -withoutValidate option
added 'db', 'tbl', 'dbtbl' ivars
cleaned up comments
added -withoutLog options to update, delete, add tags
added -withoutValidate options to update & add tags }
{maintvsrn= 1.0 }
{maintrelease= 5.0.0 }
{maintdate= 2006-01-16 }
{maintauthor= Greg Willits }
{maintnotes= initial release }
*/
//............................................................................
define_type:'fwp_recordData', -prototype;
local:
'globalCacheVar' = 'fw_gDbTableModels',
'keytable' = string,
'fw_realTable' = string,
'fw_modelIsLoaded' = false,
'fw_qryAdaptorIsLoaded' = false,
'fw_tableModel' = null,
'fw_modelDb' = string,
'fw_modelTbl' = string,
'fw_modelConn' = string,
'fw_modelkeyFld' = string,
'fw_modelLockFld' = string,
'fw_qryAdaptor' = null,
'foundCount' = integer,
'firstRecord' = integer,
'lastRecord' = integer,
'showFirst' = integer,
'showLast' = integer,
'pageCount' = integer,
'currentPage' = integer,
'inlineName' = string,
'records' = array,
'fields' = map,
'lock' = string,
'error' = false,
'errors' = array,
'formIsValid' = false,
'inputsAreInvalid' = false,
'rulesAreInvalid' = false,
'validationResults' = map,
'queryParams' = array,
'queryString' = string,
'queryStringAlt' = string,
'queryTime' = string,
'tagTime' = string;
// didn't think we'd need these, but we do
// so, yes they're redundant, but following the privacy rules of fw_
// we need non-fw_ versions, and it's too late to eliminate the fw_ versions
local:
'db' = string,
'tbl' = string,
'dbtbl' = string;
//============================================================================
//
// ->onCreate
//
// Description:
//
// Instantiates the object`s syntax adaptor and default data set.
// This tag is automatic; the developer should not call this tag
//
//............................................................................
define_tag:'onCreate';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->onCreate');
$fw_debugTimers ? $fw_timer->(start:'sqlXtraCreate');
!(global_defined:(self->'globalCacheVar'))
? self->cacheReset;
if: !(var_defined:'fw_recordLockStore');
var:'fw_recordLockStore' = fwp_recordLockStore;
$fw_recordLockStore->init;
/if;
if: (params->contains:'-keytable');
(self->'keytable') = ((params->find:'-keytable')->last)->get:2;
else;
(self->'keytable') = params->get:1;
/if;
($fw_gTables->type == 'map')
? (self->'fw_realTable') = @($fw_gTables->find:(self->'keytable'))
| (self->'fw_realTable') = @(self->'keytable');
!(self->'fw_realTable')
? (self->'fw_realTable') = @(self->'keytable');
(self->'validationResults')->(insert:'coreCodes' = array);
(self->'validationResults')->(insert:'appCodes' = array);
(self->'validationResults')->(insert:'errorMsgs' = array);
// ................................................
// lazy load of table model
(self->'fw_modelIsLoaded') = (fwpActn_loadTableModel:(self->'fw_realTable'));
if: (self->'fw_modelIsLoaded');
(self->'fw_tableModel') = @($fw_gDbTableModels->find:(self->'fw_realTable'));
(self->'fw_modelDb') = @((self->'fw_tableModel')->find:'db');
(self->'fw_modelTbl') = @((self->'fw_tableModel')->find:'tbl');
(self->'fw_modelConn') = @((self->'fw_tableModel')->find:'conn');
(self->'fw_modelKeyFld') = @((self->'fw_tableModel')->find:'keyfld');
(self->'fw_modelLockFld') = @((self->'fw_tableModel')->find:'lockfld');
(self->'db') = @((self->'fw_tableModel')->find:'db');
(self->'tbl') = @((self->'fw_tableModel')->find:'tbl');
(self->'dbtbl') = (self->'db') + '.' + (self->'tbl');
(self->'fw_qryAdaptor') = global:($fw_gAdaptorIndex->find:(self->'fw_modelConn'));
if: (self->'fw_qryAdaptor');
(self->'fw_qryAdaptorIsLoaded') = true;
else;
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'tableModel serverType___ does not match an available query adaptor : ' + (self->'fw_modelConn'));
$fw_debug && $fw_criticalLog ? log_critical:('pbError : tableModel serverType___ does not match an available query adaptor : ' + (self->'fw_modelConn'));
$fw_error->(insert:'5201' = 'fwp_recordData');
/if;
else;
// we don't normally report or log this error because
// the likely cause is that the tableModel file was not found
// which the file loading process would have already reported
// and we don't need multiple reports of that fact
($fw_debug >= fw_kVerbose) ? $fw_error->(insert:'5201' = 'fwp_recordData');
($fw_debug >= fw_kVerbose) ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'tableModel not loaded for table ' + (self->'fw_realTable'));
($fw_debug >= fw_kVerbose) && $fw_criticalLog ? log_critical:('pbError : fwp_recordData could not load tableModel for table ' + (self->'fw_realTable'));
/if;
$fw_debugTimers ? $fw_timer->(stop:'sqlXtraCreate');
/define_tag;
//============================================================================
//
// ->cacheReset
//
// builds an error mesage based on a single error code
//
//............................................................................
define_tag:'cacheReset';
(global:(self->'globalCacheVar')) = map;
/define_tag;
//: -
//============================================================================
//
// ->fw_logAction
//
// Description:
//
// Writes an entry to the data log
//
//............................................................................
define_tag:'fw_logAction',
-required = 'usrName',
-required = 'usrRcrd',
-required = 'rcrd',
-required = 'action',
-required = 'qryTime';
($fw_debug >= fw_kChatty) ? $fw_tagTracer->(add:'fwp_recordData->logAction',-action = #action);
$fw_debugTimers ? $fw_timer->(start:'sqlXtraLog');
fwpLog_data:
-usrName = #usrName,
-usrRcrd = #usrRcrd,
-table = (self->'fw_modelTbl'),
-rcrd = #rcrd,
-action = #action,
-pageInfo = $fw_logPageInfo,
-fwpInfo = $fw_logFWPInfo,
-qryTime = #qryTime;
$fw_debugTimers ? $fw_timer->(stop:'sqlXtraLog');
/define_tag;
//============================================================================
//
// ->fw_convertToFieldNames
//
// converts all tableModel input names to field names
//
//............................................................................
define_tag:'fw_convertToFieldNames',
-required = 'qryClause', -type = 'string';
$fw_debug ? $fw_tagTracer->(add:'fw_convertToFieldNames', -qryClause=#qryClause);
local:
'fw_qryClause' = #qryClause,
'fw_qryWords' = array,
'thisQueryWord' = string,
'fieldName' = string;
#fw_qryWords = (string_findRegExp: #fw_qryClause, -find='\\w+', -ignoreCase);
iterate: #fw_qryWords, #thisQueryWord;
#fieldName = ((self->'fw_tableModel')->find:'fieldNameMap')->(find:#thisQueryWord);
#fieldName
? #fw_qryClause = (string_replaceRegExp:
#fw_qryClause,
-find = '\\b(' + #thisQueryWord + ')\\b',
-replace = #fieldName);
/iterate;
return: #fw_qryClause;
/define_tag;
//============================================================================
//
// ->fw_makeVars
//
// Description:
//
// Converts fields from a record into individual page vars.
//
//............................................................................
define_tag:'fw_makeVars',
-required = 'fieldList';
($fw_debug >= fw_kChatty) ? $fw_tagTracer->(add:'fwp_recordData->makeVars', -fieldList = #fieldList);
$fw_debugTimers ? $fw_timer->(start:'sqlXtraMakeVars');
local:
'fw_fieldNames' = array,
'fw_thisItem' = string,
'fw_indx' = string;
if: #fieldList == '*';
#fw_fieldNames = (self->'fw_tableModel')->find:'fieldNames';
/if;
(#fieldList->type == string)
? #fw_fieldNames = (fwpCnfg_splitComma: #fieldList)
| #fw_fieldNames = @#fieldList;
records: -inlinename = (self->'inlineName');
iterate: #fw_fieldNames, #fw_thisItem;
#fw_indx = (((self->'fw_tableModel')->find:'fieldNames')->findIndex:#fw_thisItem)->last;
if: #fw_indx;
select: (((self->'fw_tableModel')->find:'fieldTypes')->get:#fw_indx);
case: 'integer';
var:(((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = integer:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx));
case: 'decimal';
var:(((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = decimal:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx));
case: 'date';
var:(((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = date:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx));
case;
var:(((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = string:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx));
/select;
/if;
/iterate;
/records;
$fw_debugTimers ? $fw_timer->(stop:'sqlXtraMakeVars');
/define_tag;
//============================================================================
//
// ->fw_makeFieldsMap
//
// Description:
//
// Converts fields from a record into a map
//
//............................................................................
define_tag:'fw_makeFieldsMap',
-required = 'fieldList';
($fw_debug >= fw_kChatty) ? $fw_tagTracer->(add:'fwp_recordData->makeFieldsMap', -fieldList = #fieldList);
$fw_debugTimers ? $fw_timer->(start:'sqlXtramakeFieldsMap');
local:
'fw_fieldNames' = array,
'fw_thisItem' = string,
'fw_indx' = string;
if: #fieldList == '*';
#fw_fieldNames = (self->'fw_tableModel')->find:'fieldNames';
/if;
(#fieldList->type == 'string')
? #fw_fieldNames = (fwpCnfg_splitComma: #fieldList)
| #fw_fieldNames = @#fieldList;
records: -inlinename = (self->'inlineName');
iterate: #fw_fieldNames, #fw_thisItem;
#fw_indx = (((self->'fw_tableModel')->find:'fieldNames')->findIndex:#fw_thisItem)->last;
if: #fw_indx;
select: (((self->'fw_tableModel')->find:'fieldTypes')->get:#fw_indx);
case: 'integer';
(self->'fields')->(insert: (((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = integer:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx)));
case: 'decimal';
(self->'fields')->(insert: (((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = decimal:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx)));
case: 'date';
(self->'fields')->(insert: (((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = date:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx)));
case;
(self->'fields')->(insert: (((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx) = string:(field:(((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx)));
/select;
/if;
/iterate;
/records;
$fw_debugTimers ? $fw_timer->(stop:'sqlXtramakeFieldsMap');
/define_tag;
//============================================================================
//
// ->fw_withRecordsMaps
//
//............................................................................
define_tag:'fw_withRecordsMaps',
-required = 'records',
-required = 'fields';
local:
'_fieldNames' = #fields,
'_inputNames' = @((self->'fw_tableModel')->find:'inputNameMap'),
'_thisRcrd' = array,
'_thisField' = string,
'_tempMap' = map,
'_indxR' = 0,
'_indxF' = 0;
(#_fieldNames->type == 'string')
? #_fieldNames = fwpCnfg_splitComma: #_fields;
iterate: #records, #_thisRcrd;
#_indxR += 1;
#_tempMap = map;
#_indxF = 0;
iterate: #_thisRcrd, #_thisField;
#_indxF += 1;
#_tempMap->(insert: (#_inputNames->find:(#_fieldNames->get:#_indxF)) = #_thisField);
/iterate;
(self->'records')->(insert: #_tempMap);
/iterate;
/define_tag;
//============================================================================
//
// ->fw_withRcrdsMaps
//
// Description:
//
//
//............................................................................
define_tag:'fw_withRcrdsMaps',
-required = 'records',
-required = 'fields';
local:
'_fieldNames' = #fields,
'_thisRcrd' = array,
'_thisField' = string,
'_tempMap' = map,
'_indx' = 0,
'_indxR' = 0,
'_indxF' = 0;
(#_fieldNames->type == 'string')
? #_fieldNames = fwpCnfg_splitComma: #_fields;
iterate: #records, #_thisRcrd;
#_indxR += 1;
#_tempMap = map;
#_indxF = 0;
iterate: #_thisRcrd, #_thisField;
#_indxF += 1;
#_tempMap->(insert:(#_fieldNames->get:#_indxF) = #_thisField);
/iterate;
(self->'records')->(insert: #_tempMap);
/iterate;
/define_tag;
//============================================================================
//
// ->buildSQLWhere
//
// Description:
//
// builds a Where clause
// actnWhere has four possible sources:
// first, it might be empty, so we create a safe default
// second, if it is the literal word form, we want to create field definitions
// based on a submitted form (using a dbTbl config file)
// third, if flagged to use a library, we include the specified local module library
// fourth, it has already been defined elsewhere, so our condition tree has no effect, and
// it is used a literal SQL string
//
//............................................................................
define_tag:'fw_buildSQLWhere',
-optional = 'inputs',
-optional = 'where',
-optional = 'keyfld',
-optional = 'keyval';
($fw_debug >= fw_kVerbose) ? $fw_tagTracer->(add:'fwp_recordData->buildSQLWhere',
-inputs = local:'inputs',
-where = local:'where',
-keyfld = local:'keyfld',
-keyval = local:'keyval');
local:
'fw_actnInputs' = @local:'inputs',
'fw_actnKeyFld' = @local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnWhere' = local:'where',
'thisParam' = string,
'paramField' = string,
'paramValue' = string,
'fw_indx' = integer;
if: !#fw_actnWhere && (#fw_actnKeyVal == '%');
#fw_actnWhere = string;
// #fw_actnWhere = (self->'fw_qryAdaptor')->(selectWhereDefault:
// -keyfld = (self->'fw_modelKeyFld'));
else: !#fw_actnWhere && (#fw_actnKeyVal != '%');
#fw_actnWhere = (self->'fw_qryAdaptor')->(selectWhereKeyVal:
-keyfld=#fw_actnKeyFld,
-keyval=#fw_actnKeyVal);
else: #fw_actnWhere == 'form';
#fw_actnWhere = string;
// first let`s try to build based on form submissions
// loop through the table definition and see if a particular field was submitted by the form
iterate: ((self->'fw_tableModel')->find:'inputNames'), #thisParam;
#fw_indx += 1;
if: (var_defined:#thisParam) && (var:#thisParam) && (#fw_actnInputs >> #thisParam);
// modify statement based on search operator
// default operator if none is defined is contains
#paramField = (((self->'fw_tableModel')->find:'fieldNames')->get:#fw_indx);
#paramValue = (encode_sql:(var:((self->'fw_tableModel')->find:'inputNames')->get:#fw_indx));
select: (var: (#thisParam + 'Op'));
case: 'btw';
local:'value1' = (#paramValue->split:':::')->get:1;
local:'value2' = (#paramValue->split:':::')->get:2;
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpBTW:
-field = #paramField,
-value1 = #value1,
-value1 = #value2);
case: 'lt';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpLT:
-field = #paramField,
-value = #paramValue);
case: 'lte';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpLTE:
-field = #paramField,
-value = #paramValue);
case: 'gt';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpET:
-field = #paramField,
-value = #paramValue);
case: 'gte';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpGTE:
-field = #paramField,
-value = #paramValue);
case: 'neq';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpNEQ:
-field = #paramField,
-value = #paramValue);
case: 'eq';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpEQ:
-field = #paramField,
-value = #paramValue);
case: 'bw';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpBW:
-field = #paramField,
-value = #paramValue);
case: 'ew';
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpEW:
-field = #paramField,
-value = #paramValue);
case;
#fw_actnWhere += (self->'fw_qryAdaptor')->(selectWhereOpCN:
-field = #paramField,
-value = #paramValue);
/select;
/if;
/iterate;
#fw_actnWhere->(removeleading:' AND');
// end with a safe default just in case nothing was submitted in the form
// !#fw_actnWhere
// ? #fw_actnWhere = (self->'fw_qryAdaptor')->(selectWhereDefault:
// -mapper = (self->'fw_tableModel'),
// -keyfld = #fw_actnKeyFld);
// the actnWhere var can be defined to fetch a specific library file with
// fw_actnWhere='lib```{modPath}' which is parsed to create a file path to include
// that include must end up creating a value for #fw_actnWhere
// {modPath} is any valid LDML expression so vars & concats can be processed
else: #fw_actnWhere->(beginswith:'lib```');
library: (process:(#fw_actnWhere->(split:'```')->get:2));
/if;
return: #fw_actnWhere;
/define_tag;
//============================================================================
//
// ->getFieldForInput
//
// retrieves the fieldName for a specified inputName
//
//............................................................................
define_tag:'getFieldForInput',
-required = 'inputName', -type = 'string';
return: ((self->'fw_tableModel')->find:'fieldNameMap')->find:#inputName;
/define_tag;
//============================================================================
//
// ->getInputForField
//
// retrieves the inputName for a specified fieldName
//
//............................................................................
define_tag:'getInputForField',
-required = 'fieldName', -type = 'string';
return: ((self->'fw_tableModel')->find:'inputNameMap')->find:#fieldName;
/define_tag;
//: -
//============================================================================
//
// ->sql
//
// Description:
//
// Performs complete supplied sql query
//
//............................................................................
define_tag:'sql',
-required = 'query',
-optional = 'logname';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->sql');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagSQL');
local:
'fw_qryError' = false,
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_qryActn' = local:'query',
'fw_actnMakeVars' = false,
'fw_actnRcrdsArray' = false,
'fw_actnRcrdsMapsFields' = false,
'fw_actnRecordsMaps' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-asRecordsArrays') || (params >> '-withRecordsArrays')
? #fw_actnRcrdsArray = true;
(params >> '-asRecordsMaps') || (params >> '-withRecordsMaps')
? #fw_actnRecordsMaps = true;
(params >> '-asRecordsMapsFields') || (params >> '-withRecordsMapsFields')
? #fw_actnRcrdsMaps = true;
(self->'inlineName') = (fwpStr_randomID:16);
#fw_qryActn->trim;
if: $fw_gUsePbUserAuth
&& $fw_s
&& (((var:$fw_userVarName)->'loginValid') == 'Y');
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-sql: ' + local:'logname';
// ............................................................................
$fw_timer->(start:'sqlQrySQL');
#fw_qryActn = self->(fw_convertToFieldNames: #fw_qryActn);
inline:
-inlineName = (self->'inlineName'),
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl'),
-sql = #fw_qryActn;
$fw_timer->(stop:'sqlQrySQL');
(self->'foundCount') = found_count;
if: error_code != 0;
$fw_error->(insert:'5201' = 'fwp_recordData');
#fw_qryErrors->(insert:'5505' = ('Query failed due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Query failed due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical:('pbError 5505: Query failed due to Lasso error: ' + error_msg + ' (' + error_code + ')');
else;
if: $fw_gLogDb && (local:'logname');
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = 'unknown',
-action = 'sql',
-qryTime = $fw_timer->(eventTotal:'sqlQrySQL'));
/if;
(found_count == 1) && #fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
#fw_actnRcrdsArray
? (self->'records') = @records_array;
#fw_actnRcrdsMapsFields
? self->(fw_withRcrdsMaps:
-fields = field_names,
-records = @records_array);
#fw_actnRecordsMaps
? self->(fw_withRecordsMaps:
-fields = field_names,
-records = @records_array);
/if;
/inline;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_qryActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQrySQL');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagSQL');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagSQL');
/define_tag;
//============================================================================
//
// ->getRecordUsingLock
//
// Description:
//
// Selects a record, and locks it if available. Replaces the previously
// separate tags of ->updatePrep and ->deletePrep as they were the same.
//
//............................................................................
define_tag:'getRecordUsingLock',
-optional = 'select',
-optional = 'keyfld',
-optional = 'keyval',
-optional = 'wherePairs',
-optional = 'lockval',
-optional = 'lockname';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->getRecordUsingLock');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagGetWithLock');
local:
'fw_actnSelect' = local:'select',
'fw_actnKeyFld' = local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnWherePairs' = local:'wherePairs',
'fw_actnPrevLock' = local:'lockval',
'fw_actnLockName' = local:'lockname',
'fw_actnQuiet' = false,
'fw_actnMakeFieldsMap' = false,
'fw_actnMakeVars' = false;
(params >> '-quiet')
? #fw_actnQuiet = true;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withMakeFieldsMap')
? #fw_actnMakeFieldsMap = true;
(self->'inlineName') = (fwpStr_randomID:16);
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_actnLock' = string,
'fw_lockDelta' = string,
'fw_lockInfo' = string,
'fw_getRcrdActn' = string,
'fw_lockRcrdActn' = string;
// for backwards compatibility when lockName was not available
!#fw_actnLockName
? #fw_actnLockName = '_legacyLock_';
!#fw_actnSelect
? #fw_actnSelect = '*';
#fw_actnSelect != '*'
? #fw_actnSelect = 'rcrdNo, rcrdLockID, rcrdLockTime, rcrdLockOwnr, ' + #fw_actnSelect;
!#fw_actnKeyFld
? #fw_actnKeyFld = @((self->'fw_tableModel')->find:'keyfld');
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
else;
#fw_usrName = 'Anonymous';
/if;
if: #fw_actnPrevLock;
#fw_actnLock = #fw_actnPrevLock;
else;
#fw_actnLock = (fwpStr_randomID:9);
/if;
$fw_logFWPInfo = '-getRecordUsingLock, r=' + #fw_actnKeyVal + ', k=' + #fw_actnLock;
// ............................................................................
// make sure there`s a rcrdNo, or data gets messed up
// return only the lock fields so we can also assess the record`s lock status
if: #fw_actnKeyVal || #fw_actnWherePairs;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
if: #fw_actnKeyVal;
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnSelect,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
else;
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithWherePairs:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnSelect,
-setpairs = #fw_actnWherePairs);
/if;
$fw_timer->(start:'sqlQryGetWithLockGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryGetWithLockGet');
if: found_count != 0;
// convert field data to vars
// do this ahead of lock checking to allow the app the option
// of displaying data even if it cannot display a form
#fw_actnMakeFieldsMap
? self->(fw_makeFieldsMap: -fieldList = field_names);
#fw_actnMakeVars
? self->(fw_makeVars: -fieldList = field_names);
// is the record available / unlocked?
// if it is locked, does it happen to be the same lok ID as we started with?
// if is our ID then has the lock delay period expired?
// even though you would think we would test as though this is the first pass,
// if the field validation of the updtOK page fails, we`ll be back here
// so we have to test the lok ID and time
#fw_lockDelta=(Date_Difference:
(date),
(field:'rcrdLockTime'),
-minute);
if: (
!(field:'rcrdLockID')
|| (field:'rcrdLockID') && (#fw_lockDelta > $fw_rcrdLockDelay)
) || (
(field:'rcrdLockID')
&& ((field:'rcrdLockID') == (local:'fw_actnLock'))
&& (#fw_lockDelta < $fw_rcrdLockDelay)
);
// all is good (i.e. it is not locked, or we own the lock), so let`s lock this record for our use
$fw_recordLockStore->(insert:
-name = #fw_actnLockName,
-db = (self->'fw_modelDb'),
-tbl = (self->'fw_modelTbl'),
-conn = (self->'fw_modelConn'),
-id = #fw_actnLock);
#fw_lockRcrdActn = (self->'fw_qryAdaptor')->(setRcrdLock:
-mapper = (self->'fw_tableModel'),
-userName = #fw_usrName,
-lock = #fw_actnLock,
-keyfld = 'rcrdNo',
-keyval = field:'rcrdNo');
$fw_timer->(start:'sqlQryGetWithLockSet');
#fw_lockRcrdActn = self->(fw_convertToFieldNames:#fw_lockRcrdActn);
inline:
-sql=#fw_lockRcrdActn;
$fw_timer->(stop:'sqlQryGetWithLockSet');
if: error_code == 0;
// at this point we have a succesful lock and non-empty fw_lock
// we do nothing else
// here are all the error trapping switches
else;
#fw_actnLock = string;
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical:('pbError 5500 : (a) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5507' = ('Record could not be locked due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be locked due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical:('pbError 5507 : Record could not be locked due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline;
// if there is any error, we clear the lockID
// in order to respond with an empty reply as the custom tag output
else;
#fw_actnLock = string;
#fw_qryErrors->(insert: '5111' = (#fw_usrName + '___' + (date_add: date:(field:'rcrdLockTime'), -minute=$fw_rcrdLockDelay)));
/if;
else;
#fw_actnLock = string;
if: error_code == 0;
if: !#fw_actnQuiet && !(var:'fw_errQuiet5500');
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(b) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(b) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical:('pbError 5500: (b) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
/if;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found with query {' + #fw_getRcrdActn + '} due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('5501 Record could not be found with query {' + #fw_getRcrdActn + '} due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical:('pbError 5501 : Record could not be found with query {' + #fw_getRcrdActn + '} due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline;
/inline;
else;
#fw_actnLock = string;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'getRecordUsingLock keyval was empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'getRecordUsingLock keyval was empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : getRecordUsingLock keyval was empty');
/if;
// if fw_actnLock is not empty, the lok was good, the app can present an update form
// if fw_actnLock is empty the app must not allow updating, but can at least still
// display the requested data
self->'lock' = #fw_actnLock;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_getRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryGetWithLockGet') +
$fw_timer->(eventTotal:'sqlQryGetWithLockSet');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagGetWithLock');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagGetWithLock');
/define_tag;
//============================================================================
//
// ->updateUsingLock
//
// Description:
//
// Updates a single record using the tableModel_ defined lock field and
// supplied value as the key
//
//............................................................................
define_tag:'updateUsingLock',
-optional='lockval',
-optional='lockname',
-optional='inputs',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->updateUsingLock',
-lockval = #lockval,
-inputs = #inputs);
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagUpdtWithLock');
local:
'fw_actnLockVal' = local:'lockval',
'fw_actnInputs' = local:'inputs',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnLockName' = local:'lockname',
'fw_actnMakeVars' = false,
'fw_actnWithoutValidate' = false,
'fw_actnWithoutLog' = false,
'fw_actnUseGet' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withoutValidate')
? #fw_actnWithoutValidate = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(params >> '-useGet')
? #fw_actnUseGet = true;
// for backwards compatibility when lockName was not available
!#fw_actnLockName
? #fw_actnLockName = '_legacyLock_';
(self->'inlineName') = (fwpStr_randomID:16);
// normalize the commas, but
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
#fw_actnInputs = (fwpCnfg_splitComma: #fw_actnInputs);
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_lockDelta' = string,
'fw_lokInfo' = string,
'fw_getRcrdActn' = string,
'fw_updtRcrdActn' = string,
'fw_cnfrmFldsActn' = string,
'fw_r' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-updateUsingLock, k=' + #fw_actnLockVal;
// ............................................................................
// field-specific data validation stuff is automated via the tableModel config specs
if(!#fw_actnUseGet);
!#fw_actnWithoutValidate
? (self->validateInputs: -inputs = #fw_actnInputs);
else;
!#fw_actnWithoutValidate
? (self->validateInputs: -inputs = #fw_actnInputs, -useGet);
/if;
if: !(self->'inputsAreInvalid');
// make sure there`s a rcrdNo, or data gets messed up
// return only the lock fields so we can also assess the record`s lock status
if: #fw_actnLockVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// construct the statement
// return only the lock fields so we can also assess the record`s lock status
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = 'rcrdNo, rcrdLockID, rcrdLockTime, rcrdLockOwnr',
-keyfld = (self->'fw_modelLockFld'),
-keyval = #fw_actnLockVal);
$fw_timer->(start:'sqlQryUpdtWithLockGet');
($fw_debug >= fw_kChatty) ? $fw_tagTracer->(add:'fwp_recordData->updateUsingLock : checkLock',
-fw_getRcrdActn = #fw_getRcrdActn);
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline: -sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryUpdtWithLockGet');
if: found_count != 0;
// snag the rcrdNo for the acquisition of the confirmation fields after the update
// the update uses the lockID for all actions
// but it is erased in the update action itself
// this is a security measure -- even if a cracker knows the recordID
// a record cannot be updated without a valid lock session
// (assuming the attack runs through this code)
// we acquire the recordID only after we`re successfully find a lockID
#fw_r = (field:'rcrdNo');
// let`s verify that the record is locked (it`s supposed to be)
// and that the current session is the same one that locked the record.
// we also have to test that this update occurs before the alloted lockout time expires
// otherwise another user may have accessed the record for updating
#fw_lockDelta=(Date_Difference:
(date),
(field:'rcrdLockTime'),
-minute);
if: ((field:'rcrdLockID') == #fw_actnLockVal)
&&
(integer:#fw_lockDelta < integer:$fw_rcrdLockDelay);
// all is good, let`s go ahead and update the record, but first
// create the UPDATE statement
// starting with the standard FrameWork fields and values for an update
// then adding the fields affected by the current form
#fw_updtRcrdActn = (self->'fw_qryAdaptor')->(updateRcrdWithLock:
-mapper = (self->'fw_tableModel'),
-inputs = #fw_actnInputs,
-username = #fw_usrName,
-lock = #fw_actnLockVal);
// perform the database action
$fw_timer->(start:'sqlQryUpdtWithLockSet');
($fw_debug >= fw_kChatty) ? $fw_tagTracer->(add:'fwp_recordData->updateUsingLock : updtAction',
-fw_updtRcrdActn = #fw_updtRcrdActn,
-fw_actnInputs = #fw_actnInputs);
#fw_updtRcrdActn = self->(fw_convertToFieldNames:#fw_updtRcrdActn);
inline: -sql = #fw_updtRcrdActn;
$fw_timer->(stop:'sqlQryUpdtWithLockSet');
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = local:'fw_r',
-action = 'update',
-qryTime = $fw_timer->(eventTotal:'sqlQryUpdtWithLockSet'));
/if;
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5502' = ('Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5502 : Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')');
else;
// record lock is not deleted from the store unless there's no error
// this way if there is an error it is still possible to trap and clear the lock in a cleanup routine
$fw_recordLockStore->(delete:#fw_actnLockName);
/if;
/inline; // end fw_updtRcrdActn qry
// With MySQL, only the keyfield is available after an add or update (which we already know in fw_r)
// To display record data such as for the fw_actnCnfrmFlds data in our response form below, we have to redo the search
if: #fw_actnCnfrmFlds;
#fw_cnfrmFldsActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnCnfrmFlds,
-keyval = #fw_r);
// perform the database action
$fw_timer->(start:'sqlQryUpdtWithLockCnfrm');
#fw_cnfrmFldsActn = self->(fw_convertToFieldNames:#fw_cnfrmFldsActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_cnfrmFldsActn;
$fw_timer->(stop:'sqlQryUpdtWithLockCnfrm');
if: found_count != 0;
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
else;
// oh oh, we just updated a record but couldn`t find it
// is it because the record really isn`t there
// or did some other error occur
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a1) Record number ' + #fw_actnLockVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a1) Record number ' + #fw_actnLockVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a1) Record number ' + #fw_actnLockVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if; // end found_count test
/inline; // end fw_cnfrmFldsActn qry
/if; // end fw_actnCnfrmFlds test
else;
#fw_qryErrors->(insert: '5112' =
('Could not validate record lock with ' +
'lockID=' + (field:'rcrdLockID') +
', delta=' + #fw_lockDelta +
', delay=' + $fw_rcrdLockDelay +
'\r'));
/if; // end lock status test
else;
if: error_code == 0;
#fw_qryErrors->(insert:'5113' = ('(a2) Record number ' + #fw_actnLockVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a2) Record number ' + #fw_actnLockVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5113 : (a2) Record number ' + #fw_actnLockVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r');
/if;
/if; // end get record via lock found_count test
/inline; // end #fw_getRcrdActn qry
/inline; // end connection
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'Lock value empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Lock value empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Lock value empty');
/if; // end lock value test
else;
(self->'error') = true;
$fw_formIsNotValid = true;
/if; // end validation test
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_updtRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryUpdtWithLockGet') +
$fw_timer->(eventTotal:'sqlQryUpdtWithLockSet') +
$fw_timer->(eventTotal:'sqlQryUpdtWithLockCnfrm');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagUpdtWithLock');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagUpdtWithLock');
/define_tag;
//============================================================================
//
// ->updateUsingKeyVal
//
// Description:
//
// Updates a single record based on any key field and value. While this
// tag does not search for a record based on a lock, it will still honor
// an active lock if one exists and abandon the update.
//
//............................................................................
define_tag:'updateUsingKeyVal',
-optional='keyfld',
-optional='keyval',
-optional='inputs',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->updateUsingKeyVal');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagUpdtWithKey');
local:
'fw_actnKeyFld' = @local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnInputs' = local:'inputs',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnMakeVars' = false,
'fw_actnWithoutValidate' = false,
'fw_actnWithoutLog' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withoutValidate')
? #fw_actnWithoutValidate = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(self->'inlineName') = (fwpStr_randomID:16);
// normalize the commas, but
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
if: #fw_actnInputs && (#fw_actnInputs != '*');
#fw_actnInputs = (fwpCnfg_splitComma: #fw_actnInputs);
/if;
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_lockDelta' = string,
'fw_lokInfo' = string,
'fw_getRcrdActn' = string,
'fw_updtRcrdActn' = string,
'fw_cnfrmFldsActn' = string,
'fw_r' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-updateUsingKeyVal, kv=' + #fw_actnKeyVal;
// ............................................................................
// field-specific data validation stuff is automated via the tableModel config specs
!#fw_actnWithoutValidate
? (self->validateInputs: -inputs = #fw_actnInputs);
if: !(self->'inputsAreInvalid');
// make sure there`s a rcrdNo, or data gets messed up
// return only the lock fields so we can also assess the record`s lock status
if: #fw_actnKeyVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// construct the statement
// return only the lock fields so we can also assess the record`s lock status
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = 'rcrdNo, rcrdLockID, rcrdLockTime, rcrdLockOwnr',
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryUpdtWithKeyGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline: -sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryUpdtWithKeyGet');
if: found_count != 0;
// snag the rcrdNo for the acquisition of the confirmation fields after the update
// the update uses the lockID for all actions
// but it is erased in the update action itself
// this is a security measure -- even if a cracker knows the recordID
// a record cannot be updated without a valid lock session
// (assuming the attack runs through this code)
// we acquire the recordID only after we`re successfully find a lockID
#fw_r = (field:'rcrdNo');
// let`s verify that the record is locked (it`s supposed to be)
// and that the current session is the same one that locked the record.
// we also have to test that this update occurs before the alloted lockout time expires
// otherwise another user may have accessed the record for updating
#fw_lockDelta=(Date_Difference:
(date),
(field:'rcrdLockTime'),
-minute);
if: !(field:'rcrdLockID')
||
(
(field:'rcrdLockID') == #fw_actnKeyVal
&&
(integer:#fw_lockDelta < integer:$fw_rcrdLockDelay)
);
// all is good, let`s go ahead and update the record, but first
// create the UPDATE statement
// starting with the standard FrameWork fields and values for an update
// then adding the fields affected by the current form
#fw_updtRcrdActn = (self->'fw_qryAdaptor')->(updateRcrdWithKeyFld:
-mapper = (self->'fw_tableModel'),
-inputs = #fw_actnInputs,
-username = #fw_usrName,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
// perform the database action
$fw_timer->(start:'sqlQryUpdtWithKeySet');
#fw_updtRcrdActn = self->(fw_convertToFieldNames:#fw_updtRcrdActn);
inline: -sql = #fw_updtRcrdActn;
$fw_timer->(stop:'sqlQryUpdtWithKeySet');
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = local:'fw_r',
-action = 'update',
-qryTime = $fw_timer->(eventTotal:'sqlQryUpdtWithKeySet'));
/if;
// verify that no lasso errors occured with the inline
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5502' = ('Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5502 : Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')');
else;
// record lock is not deleted from the store unless there's no error
// this way if there is an error it is still possible to trap and clear the lock in a cleanup routine
$fw_recordLockStore->(delete:'#lockName');
/if;
/inline;
// With MySQL, only the keyfield is available after an add or update (which we already know in fw_r)
// To display record data such as for the fw_actnCnfrmFlds data in our response form below, we have to redo the search
if: #fw_actnCnfrmFlds;
#fw_cnfrmFldsActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnCnfrmFlds,
-keyval = #fw_r);
// perform the database action
$fw_timer->(start:'sqlQryUpdtWithKeyCnfrm');
#fw_cnfrmFldsActn = self->(fw_convertToFieldNames:#fw_cnfrmFldsActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_cnfrmFldsActn;
$fw_timer->(stop:'sqlQryUpdtWithKeyCnfrm');
if: found_count != 0;
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
else;
// oh oh, we just updated a record but couldn`t find it
// is it because the record really isn`t there
// or did some other error occur
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a1) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a1) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a1) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline;
/if;
else;
#fw_qryErrors->(insert: '5112' =
('Could not validate record lock with ' +
'lockID=' + (field:'rcrdLockID') +
', delta=' + #fw_lockDelta +
', delay=' + $fw_rcrdLockDelay +
'\r'));
/if;
else;
if: error_code == 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r');
/if;
/if;
/inline;
/inline;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record number empty');
/if;
else;
(self->'error') = true;
$fw_formIsNotValid = true;
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_updtRcrdActn;
self->'queryTime' = $fw_timer->(stop:'sqlQryUpdtWithKeyGet') +
$fw_timer->(stop:'sqlQryUpdtWithKeySet') +
$fw_timer->(stop:'sqlQryUpdtWithKeyCnfrm');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagUpdtWithKey');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagUpdtWithKey');
/define_tag;
//============================================================================
//
// ->update
//
// Description:
//
// Updates a single record based on any key field and value. Lock fields
// are ignored, but they are not altered.
//
//............................................................................
define_tag:'update',
-optional='keyfld',
-optional='keyval',
-optional='where',
-optional='inputs',
-optional='setpairs',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->update');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagUpdt');
local:
'fw_actnKeyFld' = local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnWhere' = local:'where',
'fw_actnInputs' = local:'inputs',
'fw_actnPairs' = local:'setpairs',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnMakeVars' = false,
'fw_actnWithoutValidate' = false,
'fw_actnWithoutDateStamp' = false,
'fw_actnWithoutLog' = false,
'fw_actnUseGet' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withoutValidate')
? #fw_actnWithoutValidate = true;
(params >> '-withoutDateStamp')
? #fw_actnWithoutDateStamp = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(params >> '-useGet')
? #fw_actnUseGet = true;
(self->'inlineName') = (fwpStr_randomID:16);
// normalize the commas, but
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
if: #fw_actnInputs && (#fw_actnInputs != '*');
#fw_actnInputs = (fwpCnfg_splitComma: #fw_actnInputs);
/if;
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_updtRcrdActn' = string,
'fw_cnfrmFldsActn' = string,
'fw_r' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-update, kv=' + #fw_actnKeyVal;
// ............................................................................
// field-specific data validation stuff is automated via the tableModel config specs
// compared to other update methods, we have to allow for no inputs in this one
// due to possibility of using -setpairs. (is possible to parse -setpairs though)
if(!#fw_actnUseGet);
!#fw_actnWithoutValidate && #fw_actnInputs
? (self->validateInputs: -inputs = #fw_actnInputs);
else;
!#fw_actnWithoutValidate && #fw_actnInputs
? (self->validateInputs: -inputs = #fw_actnInputs, -useGet);
/if;
if: !(self->'inputsAreInvalid');
// make sure there`s a rcrdNo, or data gets messed up
// return only the lock fields so we can also assess the record`s lock status
if: #fw_actnKeyVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// create the UPDATE statement
// starting with the standard FrameWork fields and values for an update
// then adding the fields affected by the current form
#fw_actnWhere = self->(fw_buildSQLWhere:
-inputs = #fw_actnInputs,
-where = #fw_actnWhere,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
#fw_updtRcrdActn = (self->'fw_qryAdaptor')->(updateRcrdWithKeyFld:
-ignorelock,
-withoutDateStamp = #fw_actnWithoutDateStamp,
-mapper = (self->'fw_tableModel'),
-inputs = #fw_actnInputs,
-setpairs = #fw_actnPairs,
-username = #fw_usrName,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal,
-where = #fw_actnWhere);
// perform the database action
$fw_timer->(start:'sqlQryUpdtSet');
#fw_updtRcrdActn = self->(fw_convertToFieldNames:#fw_updtRcrdActn);
inline: -sql = #fw_updtRcrdActn;
$fw_timer->(stop:'sqlQryUpdtSet');
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = local:'fw_r',
-action = 'update',
-qryTime = $fw_timer->(eventTotal:'sqlQryUpdtSet'));
/if;
// verify that no lasso errors occured with the inline
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5502' = ('Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5502 : Record could not be updated due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline;
// With MySQL, only the keyfield is available after an add or update (which we already know in fw_r)
// To display record data such as for the fw_actnCnfrmFlds data in our response form below, we have to redo the search
if: #fw_actnCnfrmFlds;
#fw_cnfrmFldsActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnCnfrmFlds,
-keyval = #fw_r);
// perform the database action
$fw_timer->(start:'sqlQryUpdtCnfrm');
#fw_cnfrmFldsActn = self->(fw_convertToFieldNames:#fw_cnfrmFldsActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_cnfrmFldsActn;
$fw_timer->(stop:'sqlQryUpdtCnfrm');
if: found_count != 0;
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
else;
// oh oh, we just updated a record but couldn`t find it
// is it because the record really isn`t there
// or did some other error occur
if: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a1) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a1) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a1) Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline;
/if;
/inline;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 0000 : Record number empty');
/if;
else;
(self->'error') = true;
$fw_formIsNotValid = true;
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_updtRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryUpdtSet') +
$fw_timer->(eventTotal:'sqlQryUpdtCnfrm');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagUpdt');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagUpdt');
/define_tag;
//============================================================================
//
// ->deleteUsingLock
//
// Description:
//
// Deletes a single record using the tableModel_ defined lock field and
// supplied value as the key
//
//............................................................................
define_tag:'deleteUsingLock',
-optional='lockval',
-optional='lockname',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->deleteUsingLock');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagDelWithLock');
local:
'fw_actnLockVal' = local:'lockval',
'fw_actnLockName' = local:'lockname',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnMakeVars' = false,
'fw_actnWithoutLog' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
// for backwards compatibility when lockName was not available
!#fw_actnLockName
? #fw_actnLockName = '_legacyLock_';
(self->'inlineName') = (fwpStr_randomID:16);
// normalize the commas, but
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_lockDelta' = string,
'fw_lokInfo' = string,
'fw_getSelectFields' = string,
'fw_getRcrdActn' = string,
'fw_delRcrdActn' = string,
'fw_r' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-deleteUsingLock, k=' + #fw_actnLockVal;
// ............................................................................
// field-specific data validation stuff is automated via the tableModel config specs
if: #fw_actnLockVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// construct the statement
// return only the lock fields so we can also assess the record`s lock status
#fw_getSelectFields = 'rcrdNo, rcrdLockID, rcrdLockTime, rcrdLockOwnr';
if: #fw_actnCnfrmFlds;
#fw_getSelectFields += ', ';
#fw_getSelectFields += #fw_actnCnfrmFlds;
/if;
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_getSelectFields,
-keyfld = (self->'fw_modelLockFld'),
-keyval = #fw_actnLockVal);
$fw_timer->(start:'sqlQryDelWithLockGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryDelWithLockGet');
if: found_count != 0;
// snag the record number for logging
#fw_r = (field:'rcrdNo');
// convert field data to vars to display
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
// let`s verify that the record is locked (it`s supposed to be)
// and that the current session is the same one that locked the record.
// we also have to test that this update occurs before the alloted lockout time expires
// otherwise another user may have accessed the record for updating
#fw_lockDelta=(Date_Difference:
(date),
(field:'rcrdLockTime'),
-minute);
if: ((field:'rcrdLockID') == #fw_actnLockVal)
&&
(integer:#fw_lockDelta < integer:$fw_rcrdLockDelay);
// all is good, let`s go ahead and delete the record, but first
// create the UPDATE statement
// starting with the standard FrameWork fields and values for an update
// then adding the fields affected by the current form
#fw_delRcrdActn = (self->'fw_qryAdaptor')->(deleteRcrdWithLock:
-mapper = (self->'fw_tableModel'),
-lock = #fw_actnLockVal);
// perform the database action
$fw_timer->(start:'sqlQryDelWithLockSet');
#fw_delRcrdActn = self->(fw_convertToFieldNames:#fw_delRcrdActn);
inline: -sql = #fw_delRcrdActn;
$fw_timer->(stop:'sqlQryDelWithLockSet');
if: error_code == 0;
// record lock is not deleted from the store unless there's no error
// this way if there is an error it is still possible to trap and clear the lock in a cleanup routine
$fw_recordLockStore->(delete:#fw_actnLockName);
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = local:'fw_r',
-action = 'delete',
-qryTime = $fw_timer->(eventTotal:'sqlQryDelWithLockSet'));
/if;
// verify that no lasso errors occured with the inline
else: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5504' = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5504 : Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline;
else;
#fw_qryErrors->(insert: '5112' =
('Could not validate record lock with ' +
'lockID=' + (field:'rcrdLockID') +
', delta=' + #fw_lockDelta +
', delay=' + $fw_rcrdLockDelay +
'\r'));
/if;
else;
if: error_code == 0;
#fw_qryErrors->(insert:'5113' = ('(a2) Record number ' + #fw_actnLockVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a2) Record number ' + #fw_actnLockVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5113 : (a2) Record number ' + #fw_actnLockVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r');
/if;
/if;
/inline;
/inline;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record number empty');
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_delRcrdActn;
self->'queryTime' = $fw_timer->(stop:'sqlQryDelWithLockGet') + $fw_timer->(stop:'sqlQryDelWithLockSet');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagDelWithLock');
$fw_debugTimers ? (self->'tagTime') = $fw_timer->(eventTotal:'sqlTagDelWithLock');
/define_tag;
//============================================================================
//
// ->deleteUsingKeyVal
//
// Description:
//
// Deletes a single record based on any key field and value. While this
// tag does not search for a record based on a lock, it will still honor
// an active lock if one exists and abandon the delete.
//
//............................................................................
define_tag:'deleteUsingKeyVal',
-optional='keyfld',
-optional='keyval',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->deleteUsingKeyVal');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagDelWithKey');
local:
'fw_actnKeyFld' = @local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnMakeVars' = false,
'fw_actnWithoutLog' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(self->'inlineName') = (fwpStr_randomID:16);
// normalize the commas, but
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
if: !#fw_actnKeyFld;
#fw_actnKeyFld = (self->'fw_modelKeyFld');
/if;
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_lockDelta' = string,
'fw_lokInfo' = string,
'fw_getSelectFields' = string,
'fw_getRcrdActn' = string,
'fw_delRcrdActn' = string,
'fw_r' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-deleteUsingKeyVal, kv=' + #fw_actnKeyVal;
// ............................................................................
// make sure there`s a rcrdNo, or data gets messed up
// return only the lock fields so we can also assess the record`s lock status
if: #fw_actnKeyVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// construct the statement
// return only the lock fields so we can also assess the record`s lock status
#fw_getSelectFields = 'rcrdNo, rcrdLockID, rcrdLockTime, rcrdLockOwnr';
if: #fw_actnCnfrmFlds;
#fw_getSelectFields += ', ';
#fw_getSelectFields += #fw_actnCnfrmFlds;
/if;
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_getSelectFields,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryDelWithKeyGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryDelWithKeyGet');
if: found_count != 0;
// snag the record number for logging
#fw_r = (field:'rcrdNo');
// convert field data to vars to display
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
// let`s check if the record is locked (it might be)
#fw_lockDelta=(Date_Difference:
(date),
(field:'rcrdLockTime'),
-minute);
if: !(field:'rcrdLockID')
||
(
(field:'rcrdLockID') == #fw_actnKeyVal
&&
(integer:#fw_lockDelta < integer:$fw_rcrdLockDelay)
);
// all is good (not locked or lock is expired)
// let`s go ahead and delete the record,
#fw_delRcrdActn = (self->'fw_qryAdaptor')->(deleteRcrdWithKeyFld:
-mapper = (self->'fw_tableModel'),
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
// perform the database action
$fw_timer->(start:'sqlQryDelWithKeySet');
#fw_delRcrdActn = self->(fw_convertToFieldNames:#fw_delRcrdActn);
inline: -sql = #fw_delRcrdActn;
$fw_timer->(stop:'sqlQryDelWithKeySet');
if: error_code == 0;
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = local:'fw_r',
-action = 'delete',
-qryTime = $fw_timer->(eventTotal:'sqlQryDelWithKeyGet'));
/if;
// verify that no lasso errors occured with the inline
else: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5504' = ('Record could not be deleted due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be deleted due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5504 : Record could not be deleted due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline;
else;
#fw_qryErrors->(insert: '5112' =
('Could not validate record lock with ' +
'lockID=' + (field:'rcrdLockID') +
', delta=' + #fw_lockDelta +
', delay=' + $fw_rcrdLockDelay +
'\r'));
/if;
else;
if: error_code == 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + (self->'fw_modelLockFld') + ' of table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r');
/if;
/if;
/inline;
/inline;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record number empty');
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_delRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryDelWithKeyGet') +
$fw_timer->(eventTotal:'sqlQryDelWithKeySet');
$fw_debugTimers ? $fw_timer->(start:'sqlTagDelWithKey');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagDelWithKey');
/define_tag;
//============================================================================
//
// ->delete
//
// Description:
//
// Deletes a single record based on any key field and value. Lock fields
// are ignored.
//
//............................................................................
define_tag:'delete',
-optional='keyfld',
-optional='keyval',
-optional='where',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->delete');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagDel');
local:
'fw_actnKeyFld' = @local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnWhere' = local:'where',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnMakeVars' = false,
'fw_actnWithoutLog' = false;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(self->'inlineName') = (fwpStr_randomID:16);
// normalize the commas, but
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
if: !#fw_actnKeyFld;
#fw_actnKeyFld = (self->'fw_modelKeyFld');
/if;
local:
'fw_qryErrors' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_lockDelta' = string,
'fw_lokInfo' = string,
'fw_getSelectFields' = string,
'fw_getRcrdActn' = string,
'fw_delRcrdActn' = string,
'fw_r' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = 'Anonymous';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-deleteAtWill, kv=' + #fw_actnKeyVal;
// ............................................................................
// make sure there`s a rcrdNo, or data gets messed up
// return only the lock fields so we can also assess the record`s lock status
if: #fw_actnKeyVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// construct the statement
// return only the key field so we can log it
#fw_getSelectFields = 'rcrdNo';
if: #fw_actnCnfrmFlds;
#fw_getSelectFields += ', ';
#fw_getSelectFields += #fw_actnCnfrmFlds;
/if;
#fw_actnWhere = self->(fw_buildSQLWhere:
-where = #fw_actnWhere,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_getSelectFields,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryDelGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryDelGet');
if: found_count != 0;
// snag the record number for logging
#fw_r = (field:'rcrdNo');
// convert field data to vars to display
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
#fw_delRcrdActn = (self->'fw_qryAdaptor')->(deleteRcrdWithKeyFld:
-mapper = (self->'fw_tableModel'),
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
// perform the database action
$fw_timer->(start:'sqlQryDelSet');
#fw_delRcrdActn = self->(fw_convertToFieldNames:#fw_delRcrdActn);
inline: -sql = #fw_delRcrdActn;
$fw_timer->(stop:'sqlQryDelSet');
if: error_code == 0;
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = local:'fw_r',
-action = 'delete',
-qryTime = $fw_timer->(eventTotal:'sqlQryDelSet'));
/if;
// verify that no lasso errors occured with the inline
else: !(error_code == 0);
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5504' = ('Record could not be deleted due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be deleted due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5504 : Record could not be deleted due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline;
else;
if: error_code == 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r');
/if;
/if;
/inline;
/inline;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 0000 : Record number empty');
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_delRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryDelGet') +
$fw_timer->(eventTotal:'sqlQryDelSet');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagDel');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagDel');
/define_tag;
//============================================================================
//
// ->select
//
// Description:
//
// Selects records with multiple selection automation options
//
//............................................................................
define_tag:'select',
-optional='inputs',
-optional='keyfld',
-optional='keyval',
-optional='select',
-optional='from',
-optional='where',
-optional='groupby',
-optional='orderby',
-optional='sort',
-optional='skip',
-optional='limit';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->select');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagSelect');
(self->'queryParams') = params;
local:
'fw_actnInputs' = local:'inputs',
'fw_actnKeyFld' = @local:'keyfld',
'fw_actnKeyVal' = local:'keyval',
'fw_actnSelect' = local:'select',
'fw_actnFrom' = @local:'from',
'fw_actnWhere' = local:'where',
'fw_actnGroupby' = @local:'groupby',
'fw_actnOrderby' = @local:'orderby',
'fw_actnSort' = @local:'sort',
'fw_actnSkip' = @local:'skip',
'fw_actnLimit' = local:'limit',
'fw_actnQuiet' = false,
'fw_actnFoundCount' = false,
'fw_actnMakeVars' = false,
'fw_actnMakeFieldsMap' = false,
'fw_actnRcrdsArray' = false,
'fw_actnRcrdsMapsFields' = false,
'fw_actnRecordsMaps' = false;
(params >> '-quiet')
? #fw_actnQuiet = true;
(params >> '-withFoundCount')
? #fw_actnFoundCount = true;
(params >> '-withMakeVars')
? #fw_actnMakeVars = true;
(params >> '-withMakeFieldsMap')
? #fw_actnMakeFieldsMap = true;
(params >> '-asRecordsArrays') || (params >> '-withRecordsArrays')
? #fw_actnRcrdsArray = true;
(params >> '-asRecordsMaps') || (params >> '-withRecordsMaps')
? #fw_actnRecordsMaps = true;
(params >> '-asRecordsMapsFields') || (params >> '-withRecordsMapsFields')
? #fw_actnRcrdsMapsFields = true;
(self->'inlineName') = (fwpStr_randomID:16);
// normalize comma list and split it
if: #fw_actnInputs;
#fw_actnInputs = (fwpCnfg_splitComma:#fw_actnInputs);
/if;
local:
'fw_sqlGroupBy' = string,
'fw_sqlOrderBy' = string,
'fw_sqlLimit' = string,
'fw_sqlActn' = string,
'fw_countActn' = string,
'fw_thisItem' = string,
'fw_indx' = 0,
'fw_qryErrors' = array;
$fw_logFWPInfo = '-select';
// ............................................................................
// if an FWPro list sort string was passed, parse it
// a primary sort and 2 levels of sub sorts are supported
// ::ToDo:: should rewrite this to be unlimited
local:
'fw_sortFld' = string,
'fw_sortOrdr' = string,
'fw_sortDesc' = string,
'fw_sortsub1Fld' = string,
'fw_sortsub1Ordr' = string,
'fw_sortsub1Desc' = string,
'fw_sortsub2Fld' = string,
'fw_sortsub2Ordr' = string,
'fw_sortsub2Desc' = string;
if: #fw_actnSort;
#fw_sortFld = (#fw_actnSort->split:'```')->get:1;
#fw_sortOrdr = (#fw_actnSort->split:'```')->get:2;
#fw_sortDesc = (#fw_actnSort->split:'```')->get:3;
if: (#fw_actnSort->split:'```')->size > 3;
#fw_sortsub1Fld = (#fw_actnSort->split:'```')->get:4;
#fw_sortsub1Ordr = (#fw_actnSort->split:'```')->get:5;
#fw_sortsub1Desc = (#fw_actnSort->split:'```')->get:6;
/if;
if: (#fw_actnSort->split:'```')->size > 6;
#fw_sortsub1Fld = (#fw_actnSort->split:'```')->get:7;
#fw_sortsub1Ordr = (#fw_actnSort->split:'```')->get:8;
#fw_sortsub1Desc = (#fw_actnSort->split:'```')->get:9;
/if;
// modify the default sort definition if needed
// if we`re coming back here from one of the list sort buttons
// then there will already be a #sort from that form
if: ((var:'fw_sortInvert') == 'Y') && (#fw_sortOrdr == 'asc');
#fw_sortOrdr = 'desc';
#fw_actnSort = #fw_sortFld + '```' + #fw_sortOrdr + '```' + #fw_sortDesc;
else: ((var:'fw_sortInvert') == 'Y') && (#fw_sortOrdr == 'desc');
#fw_sortOrdr = 'asc';
#fw_actnSort = #fw_sortFld + '```' + #fw_sortOrdr + '```' + #fw_sortDesc;
/if;
/if;
// ............................................................................
// set some basic defaults if certain parameters are not defined
!#fw_actnSelect
? #fw_actnSelect = '*';
!#fw_actnKeyFld
? #fw_actnKeyFld = ((self->'fw_tableModel')->find:'keyfld');
!#fw_actnKeyVal
? #fw_actnKeyVal = '%';
!#fw_actnSort
? #fw_actnSort = string;
if: #fw_actnLimit >> ',';
#fw_actnSkip = (#fw_actnLimit->(split:','))->get:1;
#fw_actnLimit = (#fw_actnLimit->(split:','))->get:2;
/if;
if: !#fw_actnLimit;
#fw_actnLimit = $fw_listRcrdsMax;
else: #fw_actnLimit == '*';
#fw_actnLimit = 0;
else;
#fw_actnLimit = integer:#fw_actnLimit;
/if;
!#fw_actnSkip
? #fw_actnSkip = 0;
// ---------------------------------------------------------------------------
// build a FROM clause
!#fw_actnFrom
? #fw_actnFrom = (self->'fw_qryAdaptor')->(dbDotTable: -mapper=(self->'fw_tableModel'));
// ---------------------------------------------------------------------------
// build a WHERE clause
#fw_actnWhere = self->(fw_buildSQLWhere:
-inputs = #fw_actnInputs,
-where = #fw_actnWhere,
-keyfld = #fw_actnKeyFld,
-keyval = #fw_actnKeyVal);
// ---------------------------------------------------------------------------
// build a GROUP BY clause
// fw_actnGroupBy means a hand coded statement was submitted
// to group result on a selected field
if: #fw_actnGroupby;
#fw_sqlGroupBy = (self->'fw_qryAdaptor')->(groupBy:
-clause = #fw_actnGroupby);
else;
#fw_sqlGroupBy = string;
/if;
// ---------------------------------------------------------------------------
// build an ORDER BY clause
// fw_actnOrderBy means a hand coded statement was submitted
// fw_actnSort means a PageBlocks list sort string was submitted
if: #fw_actnOrderby;
#fw_sqlOrderBy = (self->'fw_qryAdaptor')->(orderBy:
-clause = #fw_actnOrderby);
else: #fw_actnSort;
#fw_sqlOrderBy = (self->'fw_qryAdaptor')->(orderBy:
-sortFld = #fw_sortFld,
-sortOrdr = #fw_sortOrdr,
-sub1Fld = #fw_sortsub1Fld,
-sub1Ordr = #fw_sortsub1Ordr,
-sub2Fld = #fw_sortsub2Fld,
-sub2Ordr = #fw_sortsub2Ordr);
else;
#fw_sqlOrderBy = string;
/if;
// ---------------------------------------------------------------------------
// build a LIMIT clause
if: #fw_actnSkip || #fw_actnLimit;
#fw_sqlLimit = (self->'fw_qryAdaptor')->(limit:
-skip = #fw_actnSkip,
-limit = #fw_actnLimit);
/if;
// ---------------------------------------------------------------------------
// build the SQL statement
// note for future version: need to add error detection to ensure all required vars are defined
// right now it defaults to SQL generating an error, but it would be better to tell the developer
// a specific var is not defined
// we build a var so the entire statement is easy to print out for debugging when needed
#fw_sqlActn = (self->'fw_qryAdaptor')->(select:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnSelect,
-from = #fw_actnFrom,
-where = #fw_actnWhere,
-groupby = #fw_sqlGroupBy,
-orderby = #fw_sqlOrderBy,
-limit = #fw_sqlLimit);
// open a connection to use across both queries
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// build an alternate sql statement in order to get the total count of matching records
// we ignore errors, because they`ll just happen again in the real select statement
if: #fw_actnFoundCount;
#fw_countActn = (self->'fw_qryAdaptor')->(selectCount:
-mapper = (self->'fw_tableModel'),
-from = #fw_actnFrom,
-where = #fw_actnWhere,
-groupby = #fw_sqlGroupBy);
$fw_timer->(start:'sqlQrySelectCount');
#fw_countActn = self->(fw_convertToFieldNames:#fw_countActn);
inline:
-maxrecords = 'all',
-sql = #fw_countActn;
$fw_timer->(stop:'sqlQrySelectCount');
records;
(self->'foundCount') = field:'foundCount';
/records;
/inline;
/if;
// perform the main database select
// and store as a named inline
$fw_timer->(start:'sqlQrySelect');
#fw_sqlActn = self->(fw_convertToFieldNames:#fw_sqlActn);
inline:
-inlinename = (self->'inlineName'),
-maxrecords = 'all',
-sql = #fw_sqlActn;
$fw_timer->(stop:'sqlQrySelect');
#fw_actnRcrdsArray
? (self->'records') = @records_array;
#fw_actnRcrdsMapsFields
? self->(fw_withRcrdsMaps:
-fields = field_names,
-records = @records_array);
#fw_actnRecordsMaps
? self->(fw_withRecordsMaps:
-fields = field_names,
-records = @records_array);
if: !(self->'foundCount');
(self->'foundCount') = found_count;
/if;
if: (self->'foundCount');
(self->'firstRecord') = (integer:(local:'fw_actnSkip')) + 1;
(self->'lastRecord') = (integer:(local:'fw_actnSkip')) + found_count;
else;
(self->'firstRecord') = 0;
(self->'lastRecord') = 0;
/if;
// backwards compatibility
(self->'showFirst') = @(self->'firstRecord');
(self->'showLast') = @(self->'lastRecord');
// calc pages
if: #fw_actnFoundCount;
local:
'showFirstValues' = array,
'thisShowFirst' = integer,
'perPage' = (integer:(local:'fw_actnLimit'));
#perPage < 1
? #perPage = (self->'foundCount');
#perPage < 1
? #perPage = $fw_listRcrdsMax;
((self->'foundCount') % #perPage)
? (self->'pageCount') = (integer:((self->'foundCount') / #perPage) + 1)
| (self->'pageCount') = (integer:((self->'foundCount') / #perPage));
#thisShowFirst = 1; // first page has showFirst of 1
loop: (self->'pageCount');
#showFirstValues->(insert: #thisShowFirst);
#thisShowFirst += #perPage;
/loop;
(self->'currentPage') = (#showFirstValues->(findPosition: (self->'firstRecord'))->last);
/if;
// convert single record selects to vars
(found_count == 1) && #fw_actnMakeVars
? self->(fw_makeVars: -fieldList = field_names);
// convert single record selects to fieldsMap
(found_count == 1) && #fw_actnMakeFieldsMap
? self->(fw_makeFieldsMap: -fieldList = field_names);
// error trapping switches
if: (self->'foundcount') == 0;
if: error_code == 0;
if: !#fw_actnQuiet && !(var:'fw_errQuiet5100');
#fw_qryErrors->(insert: (pair:'5100' = 'No matching records (y)'));
/if;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5506' = ('Failed search due to Lasso error ' + error_code));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Failed search due to Lasso error ' + error_code));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5506 : Failed search due to Lasso error ' + error_code);
/if;
/if;
/inline;
/inline; // end connection
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_sqlActn;
self->'queryStringAlt' = #fw_countActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQrySelect') +
$fw_timer->(eventTotal:'sqlQrySelectCount');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagSelect');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagSelect');
/define_tag;
//============================================================================
//
// ->add
//
// Description:
//
// Adds a record with a test to ensure record ID is unique
//
//............................................................................
define_tag:'add',
-optional='inputs',
-optional='keyval',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->add');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagAdd');
local:
'fw_actnKeyVal' = local:'keyval',
'fw_actnInputs' = local:'inputs',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnWithoutValidate' = false,
'fw_actnWithoutLog' = false;
(params >> '-withoutValidate')
? #fw_actnWithoutValidate = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(self->'inlineName') = (fwpStr_randomID:16);
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
if: #fw_actnInputs && (#fw_actnInputs != '*');
#fw_actnInputs = (fwpCnfg_splitComma: #fw_actnInputs);
/if;
local:
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_qryErrors' = array,
'fw_getRcrdActn' = string,
'fw_addRcrdActn' = string,
'fw_cnfrmFldsActn' = string;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = $fw_client->'ip';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-add; r=' + #fw_actnKeyVal;
// ............................................................................
// field-specific data validation stuff is automated via the tableModel config specs
!#fw_actnWithoutValidate
? (self->validateInputs: -inputs = #fw_actnInputs);
if: !(self->'inputsAreInvalid');
// make sure there`s a rcrdNo
// also verify that there isn`t already a record with this rcrdNo to prevent duplicates
if: #fw_actnKeyVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryAddGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline:
-sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryAddGet');
// we expect to NOT find any records from the above search
if: (found_count == 0);
// all is good, let`s go ahead and add the record
#fw_addRcrdActn = (self->'fw_qryAdaptor')->(insert:
-mapper = (self->'fw_tableModel'),
-inputs = #fw_actnInputs,
-username = #fw_usrName,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryAddSet');
#fw_addRcrdActn = self->(fw_convertToFieldNames:#fw_addRcrdActn);
inline:
-sql = #fw_addRcrdActn;
$fw_timer->(stop:'sqlQryAddSet');
if: error_code == 0;
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = #fw_actnKeyVal,
-action = 'add',
-qryTime = $fw_timer->(eventTotal:'sqlQryAddSet'));
/if;
// if we want to verify the record was actually saved,
// then let`s search for it and read some confirmation fields
// to display back to the user
if: #fw_actnCnfrmFlds;
#fw_cnfrmFldsActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnCnfrmFlds,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryAddCnfrm');
#fw_cnfrmFldsActn = self->(fw_convertToFieldNames:#fw_cnfrmFldsActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_cnfrmFldsActn;
$fw_timer->(stop:'sqlQryAddCnfrm');
if: found_count != 0;
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
// oh oh, we just added a record but couldn`t find it
// is it because the record really isn`t there
// or did some other error occur
else;
if: error_code != 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = ('Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline; // fw_cnfrmFldsActn
/if;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5503' = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5503 : Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline; // fw_addRcrdActn
// our test for an existing record way above actually found one
// or we had some other database error while looking
else;
if: error_code == 0;
#fw_qryErrors->(insert:'5110' = 'Record number already exists');
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline; // getRcrdActn
/inline;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record number empty');
/if;
else;
// the field validation include should have already built up the error handling variables
// but we may as well set the main error flag to make error detection easy even for validation
(self->'error') = true;
$fw_formIsNotValid = true;
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_addRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryAddGet') +
$fw_timer->(eventTotal:'sqlQryAddSet') +
$fw_timer->(eventTotal:'sqlQryAddCnfrm');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagAdd');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagAdd');
/define_tag;
//============================================================================
//
// ->addWithoutKeyval
//
// Description:
//
// Adds a record without provided keyval using sql incrementing field
//
//............................................................................
define_tag:'addWithoutKeyval',
-optional='inputs',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->addWithoutKeyval');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagAdd');
local:
'fw_actnInputs' = local:'inputs',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnWithoutValidate' = false,
'fw_actnWithoutLog' = false;
(params >> '-withoutValidate')
? #fw_actnWithoutValidate = true;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(self->'inlineName') = (fwpStr_randomID:16);
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
if: #fw_actnInputs && (#fw_actnInputs != '*');
#fw_actnInputs = (fwpCnfg_splitComma: #fw_actnInputs);
/if;
local:
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_qryErrors' = array,
'fw_getRcrdActn' = string,
'fw_addRcrdActn' = string,
'fw_cnfrmFldsActn' = string,
'fw_actnKeyVal' = integer;
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = $fw_client->'ip';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-addWithoutKeyval';
// ............................................................................
// field-specific data validation stuff is automated via the tableModel config specs
!#fw_actnWithoutValidate
? (self->validateInputs: -inputs = #fw_actnInputs);
if: !(self->'inputsAreInvalid');
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// let`s go ahead and add the record
#fw_addRcrdActn = (self->'fw_qryAdaptor')->(insert:
-mapper = (self->'fw_tableModel'),
-inputs = #fw_actnInputs,
-username = #fw_usrName);
$fw_timer->(start:'sqlQryAddSet');
#fw_addRcrdActn = self->(fw_convertToFieldNames:#fw_addRcrdActn);
inline:
-sql = #fw_addRcrdActn;
#fw_actnKeyVal = field('fw_actnKeyVal');
$fw_timer->(stop:'sqlQryAddSet');
if: error_code == 0;
var('rcrdNo' = #fw_actnKeyVal);
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = #fw_actnKeyVal,
-action = 'add',
-qryTime = $fw_timer->(eventTotal:'sqlQryAddSet'));
/if;
// if we want to verify the record was actually saved,
// then let`s search for it and read some confirmation fields
// to display back to the user
if: #fw_actnCnfrmFlds;
#fw_cnfrmFldsActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnCnfrmFlds,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryAddCnfrm');
#fw_cnfrmFldsActn = self->(fw_convertToFieldNames:#fw_cnfrmFldsActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_cnfrmFldsActn;
$fw_timer->(stop:'sqlQryAddCnfrm');
if: found_count != 0;
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
// oh oh, we just added a record but couldn`t find it
// is it because the record really isn`t there
// or did some other error occur
else;
if: error_code != 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : Record number ' + #fw_actnKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = ('Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline; // fw_cnfrmFldsActn
/if;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5503' = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5503 : Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline; // fw_addRcrdActn
/inline;
else;
// the field validation include should have already built up the error handling variables
// but we may as well set the main error flag to make error detection easy even for validation
(self->'error') = true;
$fw_formIsNotValid = true;
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_addRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryAddGet') +
$fw_timer->(eventTotal:'sqlQryAddSet') +
$fw_timer->(eventTotal:'sqlQryAddCnfrm');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagAdd');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagAdd');
/define_tag;
//============================================================================
//
// ->duplicate
//
// Description:
//
// Duplicates a record with a test to ensure record ID is unique
//
//............................................................................
define_tag:'duplicate',
-required='keyval',
-required='newkeyval',
-optional='confirmFields';
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData->duplicate');
!(self->'fw_modelIsLoaded') || !(self->'fw_qryAdaptorIsLoaded')
? return;
$fw_debugTimers ? $fw_timer->(start:'sqlTagDuplicate');
local:
'fw_actnKeyVal' = local:'keyval',
'fw_newKeyVal' = local:'newkeyval',
'fw_actnCnfrmFlds' = local:'confirmFields',
'fw_actnWithoutLog' = false;
(params >> '-withoutLog')
? #fw_actnWithoutLog = true;
(self->'inlineName') = (fwpStr_randomID:16);
// don`t split these yet so we can use them in a SELECT
if: #fw_actnCnfrmFlds;
#fw_actnCnfrmFlds = (fwpCnfg_splitComma: #fw_actnCnfrmFlds, -nosplit=true);
/if;
local:
'fw_actnFields' = array,
'fw_thisField' = string,
'fw_actnInputs' = array,
'fw_setPairs' = array,
'fw_usrName' = string,
'fw_usrRcrd' = string,
'fw_qryErrors' = array,
'fw_getRcrdActn' = string,
'fw_checkRcrdActn' = string,
'fw_addRcrdActn' = string,
'fw_cnfrmFldsActn' = string;
#fw_actnFields = (self->'fw_tableModel')->find:'fieldNames';
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdNo'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdCreated'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdCreatedBy'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdModified'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdModifiedBy'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdStatus'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdLockID'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdLockTime'))->last);
#fw_actnFields->(remove: (#fw_actnFields->(findIndex:'rcrdLockOwnr'))->last);
#fw_actnInputs = #fw_actnFields->(join:',');
if: $fw_gUsePbUserAuth && ((var:$fw_userVarName)->'loginValid') == 'Y';
#fw_usrName = (var:$fw_userVarName)->(getProfile:'userName');
#fw_usrRcrd = (var:$fw_userVarName)->(getProfile:'userRcrdID');
else;
#fw_usrName = $fw_client->'ip';
#fw_usrRcrd = 'Anonymous';
/if;
$fw_logFWPInfo = '-duplicate; r=' + #fw_actnKeyVal + ' to ' + #fw_newKeyVal;
// ............................................................................
// make sure there`s a rcrdNo
// also verify that there isn`t already a record with this rcrdNo to prevent duplicates
if: #fw_actnKeyVal;
// open a connection for use throughout this tag
inline:
-username = $fw_gQueryUser,
-password = $fw_gQueryPswd,
-database = (self->'fw_modelDb'),
-table = (self->'fw_modelTbl');
// retrieve the source record
#fw_getRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnInputs,
-keyval = #fw_actnKeyVal);
$fw_timer->(start:'sqlQryDuplicateGet');
#fw_getRcrdActn = self->(fw_convertToFieldNames:#fw_getRcrdActn);
inline:
-sql = #fw_getRcrdActn;
$fw_timer->(stop:'sqlQryDuplicateGet');
if: (found_count == 1);
iterate: #fw_actnFields, #fw_thisField;
#fw_setPairs->(insert: (#fw_thisField) = (field:(#fw_thisField)));
/iterate;
// verify the new rcrdNo doesn't already exist
#fw_checkRcrdActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-keyval = #fw_newKeyVal);
$fw_timer->(start:'sqlQryDuplicateCheck');
#fw_checkRcrdActn = self->(fw_convertToFieldNames:#fw_checkRcrdActn);
inline:
-sql = #fw_checkRcrdActn;
$fw_timer->(stop:'sqlQryDuplicateCheck');
if: (found_count == 0);
// all is good, let`s go ahead and add the record
#fw_addRcrdActn = (self->'fw_qryAdaptor')->(insert:
-mapper = (self->'fw_tableModel'),
-setPairs = #fw_setPairs,
-username = #fw_usrName,
-keyval = #fw_newKeyVal);
$fw_timer->(start:'sqlQryDuplicateSet');
#fw_addRcrdActn = self->(fw_convertToFieldNames:#fw_addRcrdActn);
inline:
-sql = #fw_addRcrdActn;
$fw_timer->(stop:'sqlQryDuplicateSet');
if: error_code == 0;
if: $fw_gLogDb && !#fw_actnWithoutLog;
self->(fw_logAction:
-usrName = #fw_usrName,
-usrRcrd = #fw_usrRcrd,
-rcrd = #fw_newKeyVal,
-action = 'duplicate',
-qryTime = $fw_timer->(eventTotal:'sqlQryDuplicateSet'));
/if;
// if we want to verify the record was actually saved,
// then let`s search for it and read some confirmation fields
// to display back to the user
if: #fw_actnCnfrmFlds;
#fw_cnfrmFldsActn = (self->'fw_qryAdaptor')->(getRcrdWithKeyVal:
-mapper = (self->'fw_tableModel'),
-select = #fw_actnCnfrmFlds,
-keyval = #fw_newKeyVal);
$fw_timer->(start:'sqlQryDuplicateCnfrm');
#fw_cnfrmFldsActn = self->(fw_convertToFieldNames:#fw_cnfrmFldsActn);
inline:
-inlinename = (self->'inlineName'),
-sql = #fw_cnfrmFldsActn;
$fw_timer->(stop:'sqlQryDuplicateCnfrm');
if: found_count != 0;
#fw_actnMakeVars
? self->(fw_makevars: -fieldList = field_names);
// oh oh, we just added a record but couldn`t find it
// is it because the record really isn`t there
// or did some other error occur
else;
if: error_code != 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('Record number ' + #fw_newKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record number ' + #fw_newKeyVal + ' not found in table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : Record number ' + #fw_newKeyVal + ' not found in table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = ('Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record data could not be acquired due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline; // fw_cnfrmFldsActn
/if;
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5503' = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5503 : Record could not be added due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/inline; // fw_addRcrdActn
// our test for an existing record way above actually found one
// or we had some other database error while looking
else;
if: error_code == 0;
#fw_qryErrors->(insert:'5110' = 'Record number already exists');
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')');
/if;
/if;
/inline; // checkRcrdActn
// our test for an existing record way above did not find one
// or we had some other database error while looking
else;
if: error_code == 0;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5500' = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl')));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('(a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl')));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5500 : (a2) Record number ' + #fw_actnKeyVal + ' not found in field ' + #fw_actnKeyFld + ' of table ' + (self->'fw_modelTbl'));
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert: '5501' = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = ('Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r'));
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record could not be found due to Lasso error: ' + error_msg + ' (' + error_code + ')\r');
/if;
/if;
/inline; // getRcrdActn
/inline; // connection
else;
$fw_error->(insert:'5201'='fwp_recordData');
#fw_qryErrors->(insert:'5501' = 'Record number empty');
$fw_debug ? $fw_tagTracer->(add:'fwp_recordData', -ERROR = 'Record number empty');
$fw_debug && $fw_criticalLog ? log_critical: ('pbError 5501 : Record number empty');
/if;
$fw_error->(merge:#fw_qryErrors);
((#fw_qryErrors->size) > 0)
? (self->'error') = true;
self->'errors' = #fw_qryErrors;
self->'queryString' = #fw_addRcrdActn;
self->'queryTime' = $fw_timer->(eventTotal:'sqlQryDuplicateGet') +
$fw_timer->(eventTotal:'sqlQryDuplicateCheck') +
$fw_timer->(eventTotal:'sqlQryDuplicateSet') +
$fw_timer->(eventTotal:'sqlQryDuplicateCnfrm');
$fw_debugTimers ? $fw_timer->(stop:'sqlTagDuplicate');
$fw_debugTimers ? self->'tagTime' = $fw_timer->(eventTotal:'sqlTagDuplicate');
/define_tag;
//: -
//============================================================================
//
// ->validateInputs
//
// Description:
//
// Validates inputs according to tableModel_ config file settings.
// Generally the developer should not need to call this tag directly
// unless doing validation on multiple models prior to batch db storage actions.
// Use the optional -withoutValidation to turn this tag call off.
//
//............................................................................
define_tag:'validateInputs',
-required = 'inputs';
($fw_debug >= fw_kChatty) ? $fw_tagTracer->(add:'fwp_recordData->validateInputs', -inputs = #inputs);
$fw_debugTimers ? $fw_timer->(start:'sqlXtraInputs');
// added 2008-07-11 nikolaj
local('fw_actnUseGet' = false);
params >> '-useGet'
? #fw_actnUseGet = true;
if(!#fw_actnUseGet);
(self->'inputsAreInvalid') = $fw_validator->(validate:
-usingPOSTForm,
-inputs = #inputs,
-valcodes = (self->'fw_tableModel')->find:'valCodeMap');
else;
(self->'inputsAreInvalid') = $fw_validator->(validate:
-usingGETForm,
-inputs = #inputs,
-valcodes = (self->'fw_tableModel')->find:'valCodeMap');
/if;
// now execute model-specific custom validations
self->validate;
$fw_debugTimers ? $fw_timer->(stop:'sqlXtraInputs');
(self->'validationResults') = $fw_validator->getResults;
/define_tag;
//============================================================================
//
// ->validate
//
// Description:
//
// An empty method intended to be overloaded
// Needs to set value of ->'rulesAreInvalid' as boolean result
//
//............................................................................
define_tag:'validate';
// rulesAreValid is true by default
// unless this method is overloaded
($fw_debug >= fw_kVerbose)? $fw_tagTracer->(add:'fwp_recordData->validate');
(self->'rulesAreInvalid') = true;
/define_tag;
//============================================================================
//
// ->insertAppError
//
//
//............................................................................
define_tag:'insertAppError',
-required = 'input';
((self->'validationResults')->(find:'errorMsgs'))->(insert:#input);
((self->'validationResults')->(find:'appCodes'))->(insert:#input->first = 'model_error');
/define_tag;
//============================================================================
//
// ->showMsgsForInput
//
// displays all error messages for a single input name
//
//............................................................................
define_tag:'showMsgsForInput',
-required = 'input',
-optional = 'class',
-optional = 'withP',
-optional = 'withoutBR';
local:
'fw_myMsgs' = ((self->'validationResults')->(find:'errorMsgs'))->(find:#input),
'fw_thisMsg' = string,
'fw_msgStr' = string,
'fw_markupStart' = string,
'fw_markupEnd' = string,
'fw_markupClass' = string;
(params >> '-class')
? #fw_markupClass = ((params->find:'-class')->get:1)->second
| #fw_markupClass = 'inputerrmsg';
(params >> '-withP')
? #fw_markupStart = '<p class="' + #fw_markupClass + '">'
| #fw_markupStart = '<span class="' + #fw_markupClass + '">';
(params >> '-withP')
? #fw_markupEnd = '</p>'
| #fw_markupEnd = '</span>';
(params >> '-withoutBR')
? #fw_markupEnd += ''
| #fw_markupEnd += '<br />';
iterate: #fw_myMsgs, #fw_thisMsg;
#fw_msgStr += #fw_markupStart;
#fw_msgStr += #fw_thisMsg->second;
#fw_msgStr += #fw_markupEnd;
/iterate;
return: @#fw_msgStr;
/define_tag;
//============================================================================
//
// ->errorExistsForInput
//
//
//............................................................................
define_tag:'errorExistsForInput',
-required = 'input';
((self->'validationResults')->(find:'errorMsgs'))->(find:#input)
? return: true
| return: false;
/define_tag;
/define_type;
?>
© 2002-2012, pageblocks.org