EXAMPLES
For example, CUSTOMER and CUSTOMERS refer to the same form and FQL recognizes both as synonyms. Also note that unlike other computer languages, FQL allows to have spaces within names.
Do not confuse this internal key with the unique identifiers (usually called "ID", "CODE", etc.) that are natural keys but exactly because of this reason, they are form data and could potentially be subject of change by new business rules. For example, a Product ID that is unique within a certain business context, might not continue being unique after a merge with another company and may require then a Company Code or Product Type in order to continue uniquely identifying a Product.
If you consider FQL as a DSL, then Forms are the Domain on top of which FQL applies.
You can consider a Form also as a Transaction, but it is preferred to call it a Form, because it is an easier concept to grasp by the end user. Almost every internet user has sometime filled out a form, even on paper or an electronic one (generally, web-based). Transactions on the other hand, imply some other concepts that are automatically handled by an Application Base and even though useful to know them, it is not a requirement. Just choose the concept (Form or Transaction) that you feel more comfortable with but please use the word "Form" when comunicating with others.
CREATE FORM CUSTOMER (ID NUMBER NOT NULL UNIQUE,
FIRST NAME TEXT,
LAST NAME TEXT NOT NULL,
DOC TYPE TEXT NOT NULL,
DOC NUMBER TEXT NOT NULL)
UNIQUE (DOC TYPE, DOC NUMBER)
CREATE FORM ACCOUNTS (ID NUMBER NOT NULL UNIQUE,
CUSTOMER REFERENCES CUSTOMERS NOT NULL,
BALANCE NUMBER NOT NULL)
CREATE FORM TRANSACTION TYPE (TRANSACTION TYPE TEXT NOT NULL,
IS CREDIT BOOLEAN NOT NULL)
(now we define a couple of concepts, to simplify the expression of some conditions)
WHEN TRANSACTION TYPE.IS CREDIT THEN IS CREDIT TRANSACTION.
WHEN NOT CREDIT TRANSACTION THEN IS DEBIT TRANSACTION.
(note: considering that "NOT" will be a reserved word, would it make sense to allow its usage within an expression ? For example: WHEN TRANSACTION TYPE.IS NOT CREDIT THEN IS DEBIT TRANSACTION)
CREATE FORM TRANSACTIONS (ID NUMBER NOT NULL UNIQUE GENERATED,
EFFECTIVE DATE DATE,
ACCOUNT REFERENCES ACCOUNTS NOT NULL,
TRANSACTION TYPE REFERENCES TRANSACTION TYPES NOT NULL,
AMOUNT NUMBER NOT NULL)
WHEN DEBIT TRANSACTION AND AMOUNT > BALANCE IS INVALID
(note: maybe we can omit the REFERENCES clause when the data name and form name are the same. For example, EDUCATION LEVEL should be enough and the same meaning as adding the REFERENCES EDUCATION LEVEL as in the following example).
CREATE FORM CUSTOMER PROFILE (NAME TEXT NOT NULL,
EDUCATION LEVEL REFERENCES EDUCATION LEVEL,
INVESTMENT EXPERIENCE REFERENCES INVESTMENT EXPERIENCE,
PROFILE REFERENCES PROFILES)
WHEN EDUCATION LEVEL.SCORE > 5 AND INVESTMENT EXPERIENCE.SCORE > 3 THEN SET PROFILE = (GET PROFILE WITH DESCRIPTION = 'EXPERT')
Scenario Each CUSTOMER can have more than one ACCOUNT with a certain BALANCE. When the total amount of the deposits is bigger than 1.000.000, the CUSTOMER is considered a VIP CUSTOMER.
WHEN SUM(CUSTOMER.BALANCE) > 1M THEN IS A VIP CUSTOMER
Since there is only one possible path, from a CUSTOMER to a data called BALANCE then it is not necessary to specify the whole path (CUSTOMER.ACCOUNTS.BALANCE). Being a 1-to-Many relationship, the SUM functions transforms a multiple value into a single one.