Wednesday, April 16, 2014

find() and Exist() Methods.



    find()


  • find () returns a record from the table. 
  • find () must be used when a record is selected from the database by using the primary key of the table.
  • find () method must be static because find () is used to find a record among all the records of the table.
  • find () must be named find () and declared public as a best practise.
  • Find () have parameters of data type of key of the table or list of parameters if the key consists of more than one field. And the parameters in find () must follow the same order that the index follows. Because inside index the fields are listed in some order.
  • find () must have the Boolean parameter with default value False. If the Boolean parameter is true then the record is selected for update.
  • Use very effective select operation to retrieve and return the record from table. You must use a proper index and firstonly keyword.
  • Default behaviour to run is run on client and server. Never specify a single tier in the declaration, always use client server.
Example: -- 
     public  static  CustInterestJour  find (interestNote  _ interestNote,  boolean  _forupdate  = false)
     {
              select custInterestJour    
           index hint InterestIdx  
           where custInterestJour.InterestNote == interestNote;
  }





The Difference between Optimistic concurrency control(OCC) and Pessimistic concurrency control(PCC).



  1. Optimistic concurrency control (OCC) helps increase the database performance.
  2.  Optimistic concurrency control locks records only from the time the real update operation is started (i.e. during update process). So, the records are locked for a shorter duration of time and will be available for other process (for update process).
  3.  OCC makes it possible for other processes to update the record even after the record is fetched. Here the disadvantage is if another process updates the same records which are fetched, then the update fails and retry will take more time which hits the performance.
  4. In OCC fewer resources are being used to hold the locks during the update process.
  5. Property used on table is OccEnabled. Defaulted to Yes.
  • Pessimistic concurrency control locks the records immediately after they are fetched from the database for update.
  • To set concurrency model for a select statement, just replace forupdate with the optimistic or pessimistic as shown below.
For Example:-      Select optimistic CustTable
                            Select pessimistic CustTable.





Understanding and Using Args





  • Args class is used to pass arguments between objects like name, caller and parameters
  • Caller ()  will set the instance of object and will get (return) the instance of object which created the Args class object
  • To check whether the calling object (form) contains the table ‘abc' then use below code validation. So here the args will hold the record buffer of the caller(calling object). 
If (element.args().dataset == tablenum(abc)).
        

  •  To initialize the record to the table buffer 'abc' use.
Abc = element.args().record();

  • After using the above table. In continuation to get the handle of the caller data source use below code.
formDataSource = element.args().record();    or      abc.datasource();

Friday, April 4, 2014

X++ Code Layout

  • Only one statement per line.
  • Break up complex expressions that are more than one line - make it visually clear.
  • Use a single blank line to separate entities.
  • Do not use parentheses around the case constants. Warning icon
  • Do not use parentheses around where expressions.
  • Add one space between ifswitchforwhile and the expressions starting parentheses. For example:
    if (creditNote)
  • Use braces around all code blocks, except for around case clauses in a switch statement. Use braces even if there is only one statement in the block.
An indentation is equivalent to four (4) characters, which corresponds to one tab in the X++ editor. You must not start a new line in columns 2, 3 or 4. Error icon
  • Put opening and closing braces, { and }, on the same level, on separate lines, and aligned with the command creating the block. They must be at the start of a line, and in a tab column position (1, 5, 9 etc.). Error iconBraces must be on a dedicated line Error icon unless a opening brace is followed by a semicolon ( {; ) or a closing brace is followed by a while ( }while ).
  • The following reserved words should be placed at the beginning of a line: casecatchchangeCompanycontinuedefaultelseforifretryreturnswitchtryttsAbortttsBeginttsCommit,whileWarning icon
    The exceptions to this rule are:
    case: … (reserved words in a case statement)
    default: … (reserved words in a default statement)
    else if
    }while
  • If a line of code starts with any other reserved word, or with an alphabetical character, the line should start in a tab column position (1, 5, 9 etc). Warning icon The following reserved words must be placed in a tab column position: casecatchchangeCompanycontinuedefaultelseforifretryreturnswitchtryttsAbortttsBeginttsCommitwhileError icon
    The exceptions to these rules are:
    case: … (reserved words in a case statement)
    default: … (reserved words in a default statement)
    else if
    }while
  • The reserved word else must have a dedicated line unless you write else if Error icon.
  • switch-case statements: indent case and default statements by 1 level (with any code within these indented a further level) and indent break statements by two levels.
  • Indent where and other qualifiers to the select statement by one level.
  • If Booleans are used in a long expression, put them at the start of an indented new line.

Example switch-case Statement

switch (myEnum)
{
    case ABC::A:
        ...
        break;
    case ABC::B
        ...
        break;
    default:
        ...
        break;
}

Example select Statement

select myTable
    index hint myIndex
    where myTable.field1 == 1
        && myTable.field2 == 2;

Example Layout of Booleans in a Long Expression

select firstOnly utilElements
    where utilElements.recordType == recordType
        && utilElements.parentId == parentID
        && utilElements.name == elementName;
Column layout should be used where more than one line has the same structure; for example, in declarations or assignments.
Do not use column layout when there is only one row, or if consecutive rows do not have the same structure.
Column format is defined using extra blanks.

Example Column Layout

tmpABC.refRecId     = inventTable.recId;
tmpABC.itemGroupId  = inventTable.itemGroupId;
tmpABC.itemId       = inventTable.itemId;
tmpABC.amount       = amount;
tmpABC.oldValue     = this.getCategory(inventTable);
tmpABC write();
The starting parenthesis on method declarations and calls should be the character just after the method name (no space).
If there are one or two parameters, the parameters can be listed on the same line. If there are more than two parameters, move each parameter onto a new line, and indent by 4 spaces.

Example Layout for Method with One or Two Parameters

myMethod(parameter1, parameter2);

Example Layout for Method with Many Parameters

myMethod(
    parameter1,
    parameter2,
    parameter3);
Best Practise checks in AX 2012

Best Practice
Example




Place the opening and closing braces each on their own line.
if (someExpression)
{
doSomething();
}
Do not omit braces. Braces are not optional because they increase code readability and maintainability. They should be included, even for single statement blocks.
if (someExpression)
{
doSomething();
}
Omit braces for switch statements. These braces can be omitted because the case and break statements clearly indicate the beginning and ending.
case 0:
doSomething();
break;
Use a single space in the following cases:
  • On either side of the assignment operator.
Correct: cust.Name = "Jo";
Incorrect: cust.Name="Jo";
  • After the comma between parameters.
Correct:
public void doSomething(int _x, int _y)
Incorrect:
public void doSomething(int _x,int _y)
  • Between arguments.
Correct: myAddress(myStr, 0, 1)
Incorrect: myAddress(myStr,0,1)
  • Before flow control statements.
Correct: while (x == y)
Incorrect: while(x == y)
  • Before and after binary operators.
Correct: if (x == y)
Incorrect: if (x==y)
  • After the semicolon between the parts of a for statement.
Correct: for (i = 0; i < 10; i++)
Incorrect: for (i = 0;i < 10;i++)
Do not use any spaces in the following cases:
  • After the opening or before the closing parenthesis.
Correct: myAddress(myStr, 0, 1)
Incorrect: myAddress( myStr, 0, 1 )
  • Between a member name and opening parenthesis.
Correct: myAddress()
Incorrect: myAddress ()
  • Before or after the brackets.
Correct: x = dataArray[index];
Incorrect: x = dataArray[ index ];
  • Before or after unary operators.
Correct: if (!y)
Incorrect: if (! y)
Use four spaces as the standard indent. The tab key in code editor inserts four spaces. Indent in the following cases:
  • The contents of code blocks.
if (someExpression)
{
doSomething();
}
  • Case blocks even though they do not use braces.
switch (someExpression)
{
case 0:
doSomething();
break;
}
  • A wrapped line one indent from the previous line.
lastAccount = this.doSomething(
cust,
firstAccount,
startDate,
endDate);
Wrap lines that get too long to fit on a single line.
Wrap shorter lines to improve clarity.
Place each wrapped select and while select statement keyword at the beginning of a new line. The content associated with each keyword should be indented by one indent under the corresponding keyword.
select firstonly cust
where someExpression1
&& someExpression2
&& someExpression3;
select count(RecId)
from cust
where someExpression1
&& someExpression2
&& someExpression3;
while select firstonly cust
order by Name, AccountNum
where someExpression1
&& someExpression2
&& someExpression3
{
}
Do not use more or less than four spaces to force special alignment.
Right
lastAccount = this.doSomething(
cust,
firstAccount,
startDate,
endDate);
Wrong (indent is 14 spaces)
last = this.do(
cust,
firstAccount,
startDate,
endDate);
Put each indented parameter or argument on a separate line.
Use switch statements over consecutive if statements.
Do not use parenthesis around the value of the cases of a switch statement.
Do not put the closing parenthesis for a method call on a new line.


Best Practice
Example
Use Camel case naming for member variables, method names, and local variables.
serverClass;
Use Pascal case naming for Application Object Tree (AOT) elements.
AddressCountyRegion;
Prefix parameter names with an underscore (_).
myJob(Args _args)


Best Practice
Example
Do not use comments that repeat the code.
Do not use multi-line syntax /* … */ for comments. The single-line syntax // … is preferred even when a comment spans multiple lines.
public int getCount()
{
;
// This comment spans multiple
// lines because it has
// a lot to say. The use of
// multi-line syntax is
// not allowed.
}
Do not place comments at the end of a line unless the comment is very short. In most cases, comments should be placed above the code.
public class ArrayList
{
int count; // -1 indicates uninitialized array
}

Labels and Text Guidance

The following list provides best practice guidance for labels and text.
  • Use labels for text that will appear on the user interface.
  • Put labels in double quotes.
  • Do not concatenate multiple labels together.
  • Use single quotes for text that will not appear in the user interface.

X++ Coding Standards [AX 2012]


  • Declare variables as locally as possible.
  • Have only one successful return point in the code (typically, the last statement), with the exception of switch cases, or when checking for start conditions.
  • Keep the building blocks (methods) small and clear. A method should do a single, well-defined job. It should therefore be easy to name a method.
  • Put braces around every block of statements, even if there is only one statement in the block.
  • Put comments in your code, telling others what the code is supposed to do, and what the parameters are used for.
  • Do not assign values to, or manipulate, actual parameters that are "supplied" by value. You should always be able to trust that the value of such a parameter is the one initially supplied. Treat such parameters as constants.
  • Clean up your code; delete unused variables, methods and classes.
  • Never let the user experience a runtime error. Take appropriate actions to either manage the situation programmatically or throw an error informing the user in the Infolog about the problem and what actions can be taken to fix the problem.
  • Never make assignments to the "this" variable.
  • Avoid dead code. (See Dead Code Examples.)
  • Reuse code. Avoid using the same lines of code in numerous places. Consider moving them to a method instead.
  • Never use infolog.add directly. Use the indirection methods: errorwarninginfo and checkFailed.
  • Design your application to avoid deadlocks.