1.
What are different AppServer Modes? Explain them? Which mode should be used?
Which one is beneficial (context, connection) [which is most complex and which is
simplest]
a) State-aware
b) State-reset
c) State-less [should be used]
d) State-free
2. What is pessimistic Locking, What is optimistic locking?
a) Optimistic: The table is open for read/write over entire network for all users/sessions. We
can move the cursor, backward or forward dynamically.
b) Pessimistic: The table is open for read/write only for that current session. The other
session users cannot edit the same.
These are methodologies used to handle multi-user issues. How does one handle the fact that 2 people want to update the same record at the same time?
Approach 1 - 'lost update' - User 1 reads a record
- User 2 reads the same record
- User 1 updates that record
- User 2 updates the same record
User 2 has now over-written the changes that User 1 made. They are completely gone, as if they
never happened. This is called a 'lost update'.
Approach 2 - Pessimistic locking - Lock the record when it is read
- User 1 reads a record *and locks it* by putting an exclusive lock on the record (FOR UPDATE)
- User 2 attempts to read *and lock* the same record, but must now wait behind User 1
- User 1 updates the record (and, of course, commits)
- User 2 can now read the record *with the changes that User 1 made*
- User 2 updates the record complete with the changes from User 1
User 1 is locking a record that they might not ever update. User 2 cannot even read the record because they want an exclusive lock when reading as well.
This approach requires far too much exclusive locking, and the locks live far too long (often across user control - an *absolute* no-no). This approach is almost *never* implemented.
The lost update problem is solved. The problem with this approach is concurrency.
Approach 3 - Optimistic locking – doesn’t Lock the record when it is read
It does not use exclusive locks when reading. Instead, a check is made during the update to make sure that the record has not been changed since it was read. This can be done by checking every field in the table.
3. What is transaction scoping? What is transaction? How can increase the scope of the transaction? What is Transaction? How do you Minimizing and Maximizing the transaction scope? What is a transaction? What do you mean by transaction scope.
How does Progress know where to start the transaction and how much work to undo or back
out?
A transaction is a set of changes to the database, which the system either completes or discards, leaving no modification to the database. The terms physical transaction and commit unit refer to the same concept as the Progress transaction. For example, in the above scenario where you are adding customer records, each customer record you add is a transaction.
The transaction scoping means the part of the program code block in which transaction remains active. Transaction scoping depends on the size of the containing block.
The following transaction blocks start a transaction if one is not already active:
à Any block that uses the TRANSACTION keyword on the block statement (DO, FOR EACH, or REPEAT).
àA procedure block, trigger block, and each iteration of a DO ON ERROR, FOR EACH, or REPEAT block that directly updates the database or directly reads records with EXCLUSIVE-LOCK. You use EXCLUSIVE-LOCK to read records in multi-user applications.
Directly updating the database means that the block contains at least one statement that can change the database. CREATE, DELETE, and UPDATE are examples of such statements.
If a block contains FIND or FOR EACH statements that specify EXCLUSIVE-LOCK, and at least one of the FIND or FOR EACH statements is not embedded within inner transaction blocks, then the block is directly reading records with EXCLUSIVE-LOCK.
Note that DO blocks do not automatically have the transaction property. Also, if the procedure or transaction you are looking at is run by another procedure, you must check the calling procedure to determine whether it starts a transaction before the RUN statement.
Once a transaction is started, all database changes are part of that transaction, until it ends.
Each user of the database can have just one active transaction at a time.
4. Which tools do you use in query optimization? XREF
5. Have you used profiler? Yes
A performance profiler is a common and useful tool for a software developer. In brief, a profiler provides a "profile" of a particular execution. A profiler generally provides timing information and call-tree information; with that, an engineer can analyze where their program is spending most of its time and what part of the application is calling what other part of the application.
6. Do you have Appserver experience... project
7. What is handle? What are the Types of handle?
Handles are pointers to Progress objects. You generally define variables or fields to hold handle values with the HANDLE, WIDGET-HANDLE, or COM-HANDLE data type. Note that HANDLE and WIDGET-HANDLE have a weak type relationship; that is, one can be assigned directly to the other. The COM-HANDLE data type provides ActiveX support. Progress supports following types of handle, depending on the object referenced:
· Widget
· Procedure
· Query, buffer, and buffer-field
· Server
· Component
· Transaction
· System
Widget Handles
Progress assigns every static or dynamic widget a handle value once it is created. This handle serves a different purpose, depending on whether the widget is static or dynamic:
For a static widget, the handle provides a unique reference to the widget besides the widget name. The widget name, by itself, can be ambiguous if the widget is specified in more than one container widget. Progress resolves this ambiguity differently depending on the widget. However, the handle to a widget is always unambiguous.
For a dynamic widget, it provides the only means to reference and manage the widget that you create.
You generally store widget handle values in variables or fields defined with the WIDGET-HANDLE data type
Procedure Handles
Every external procedure that is in scope within an application has a handle that identifies the context of the procedure. Using a valid procedure handle, you can execute the internal procedures and procedure triggers of the specified external procedure from any other procedure in your application. This capability is especially useful with persistent procedures. Thus, you can encapsulate related functionality and make it available to your entire application.
You generally store procedure handle values in variables or fields defined with the HANDLE data type.
Query, Buffer, and Buffer-field Handles
Query, buffer, and buffer-field object handles let you manipulate static and dynamic versions of these objects.
Server Handles
A server handle references the connection that you create to a Progress AppServer using the CREATE SERVER statement. You generally store server handle values in variables or fields defined with the HANDLE data type.
Component Handles
A component handle references a COM object (ActiveX Automation object or ActiveX control). Unlike all other handles, you store component handle values in variables defined with the COM-HANDLE data type.
Transaction Handles
A transaction object handle provides access to the current transaction object.
System Handles
Progress maintains several global handles that describe the current context of an application. Some system handles reference the widget handle of a context-determined user-interface widget. Others reference data and facilities available for and about the current session. Table 16-1 lists the Progress system handles.
8. What is the difference between for first and find first?
a) FOR uses multiple indexes, FIND uses single index, so for is more efficient.
b) FOR don’t require NO-ERROR, FIND requires NO-ERROR.
c) FOR can specify the fields to be included/excluded using FIELDS phrase, FIND does not
d) FOR provides a weak block scope, where FIND is scoped in side containing procedure, block.
9. What is difference between can-find and find statement?
a) CAN-FIND is more efficient than FIND because CAN-FIND only looks at the index (usually 1 I/O operation) where FIND retrieves the entire record (minimum of 2 I/Os).
b) CAN-FIND can’t make the record available to record buffer while find statement make record
available to the record buffer.
10. What are the different types of locks used in Progress?
Lock types and then describe. What are different types of locks? Explain.
You've just seen how you can apply a lock on your own. But if you do not apply any locks, Progress performs default locking. In particular:
à Whenever it reads a record, Progress puts a SHARE-LOCK on that record. (An exception is the browse widget. This means that other users can read the record but cannot update it until the procedure releases the SHARE-LOCK. If you try to read a record with a SHARE-LOCK when another user has that record EXCLUSIVE-LOCKed, Progress displays a message that the record is in use and you must wait to access it.
à Whenever Progress updates a record; it puts an EXCLUSIVE-LOCK on that record. This means that other users cannot read or update that record until the procedure releases EXCLUSIVE-LOCK. If you try to read a record with an EXCLUSIVE-LOCK, when another user has that record SHARE-LOCKed or EXCLUSIVE-LOCKed, you receive a message that the record is in use and you must wait to access it.
NOTE: SHARE-LOCKs and EXCLUSIVE-LOCKs use up entries in the lock table. The possible number of entries in the lock table defaults to 500. You can change this with the Lock Table Entries (-L) startup parameter. Progress stops a user program if it attempts to access a record that overflows the lock table.
11. What is self-join in progress? What is the syntax for self join?
A self-join is a query in which a table is joined (compared) to itself. Self-joins are used to compare values in a column with other values in the same column in the same table.
12. What is the use of buffer-copy command?
This method copies any common fields, determined by name, data type, and extent-matching, from the source buffer to the receiving buffer. If there are fields in one buffer that do not exist in the other, they are ignored. This method is used to accommodate temp-tables of joins.
Return type: LOGICAL
Applies to: Buffer object handle
Syntax BUFFER-COPY( source-buffer-handle
[ , except-list [ , pairs-list [ , no-lobs ] ] ] )
source-buffer-handle
An expression that evaluates to the source buffer handle.
except-list
A character expression that evaluates to a comma-separated list of field names to be excluded from the copy.
pairs-list
A character expression that evaluates to a comma-separated list of field-name pairs to be copied.
You can also specify an array element as one or both of the fields. This lets you copy a field or array element from one buffer to a field or array element in the other buffer, when the two fields do not have the same name. The order within each field-name pair does not matter; each pair must contain one field name from the source and one field name from the target.
You can also copy one entire array to another by specifying its name without a subscript.
no-lobs
A logical expression indicating whether to ignore BLOB and CLOB fields in the copy. If TRUE, BLOB and CLOB fields are ignored during the copy. If FALSE, BLOB and CLOB fields are copied along with the other fields. The default value is FALSE (that is, BLOB and CLOB fields are included in the copy).
The following example fragment copies the customer table to the buffer, bh, except that customer.sales-rep is copied to a field called cust-sales-rep in the buffer:
bh:BUFFER-COPY(buffer customer:handle,?,"cust-sales-rep,sales-rep").
13. What is lookup function?
Returns an integer giving the position of an expression in a list.
Returns a 0 if the expression is not in the list.
Syntax
LOOKUP (expression, list [, character])
14. Use of field-lists in progress.
The field-list specifies a list of fields to include or exclude when you open the query. This is the syntax for field-list:
FIELDS [ ( [ field ... ] ) ]| EXCEPT [ ( [ field ... ] ) ]
15. What are different types of blocks in Progress?
16. What is Record-Bleeding?
A record may be found without acquiring any lock simply by adding the no-lock option to any statement that retrieves a record (e.g., find, for each, get, open query, etc.). In theory, it is impossible to change a record that has been found with no-lock status. In practice, there
are times when, in the presence of multiple buffers for the same record, an assignment can be made. This phenomenon is known as a bleeding lock (see Knowledge Base # 13881 for more information). An existing record can always be found with a no-lock, even if someone
else has the same record with a share- or exclusive-lock.
17. How do you read and load the 1000 records from a flat file into the database?
How can you control the size of transaction?
INPUT FROM datafile. /* Example of Reducing Transactions */
REPEAT TRANSACTION:
REPEAT vCounter = 1 TO 1000:
CREATE Customer.
IMPORT Customer.
END.
END.
18. How do you find out, which index your query are using? XREF
19. What kind of coding did you do in projects involving the AppServer? Did you do both client
and server-side programming?
20. Was any specific development methodology (SDLC) followed in projects worked on?
Waterfall model
21. Dynamic queries along with the syntax. Advantages and disadvantages of dynamic queries.
DEFINE VARIABLE qh AS WIDGET-HANDLE.
DEFINE VARIABLE numvar AS INTEGER INITIAL 10.
CREATE QUERY qh.
qh:SET-BUFFERS(BUFFER customer:HANDLE).
qh:QUERY-PREPARE("FOR EACH customer WHERE cust-num < " + string(numvar)).
qh:QUERY-OPEN.
REPEAT WITH FRAME y:
qh:GET-NEXT().
IF qh:QUERY-OFF-END THEN LEAVE.
DISPLAY cust-num
name FORMAT "x(30)"
city FORMAT "X(20)"
END.
qh:QUERY-CLOSE()
DELETE OBJECT qh.
22. Have you done Appserver configuration? Mention some of the settings that we maintain when
configuring the Appserver.
23. What according to you are the three most important considerations that a developer should
make while writing the code?
24. Have you worked on developing reports using Progress 4GL? Have you ever used any reporting tools?
25. How do you debug your code? Do you use debugging tools? Are you familiar with Pro*spy?
1) HELP Button: -debugalert or session:debug-alert = yes.
2) Enable 4GL debugging:
proenv>prodebugenable
Usage: proDebugEnable { -disable-all | -enable-all }
-disable-all : disable environment for debugging
-enable-all : enable environment for debugging
proenv>prodebugenable -enable-all
OpenEdge Release 10.1A as of Wed Dec 21 03:20:56 EST 2005
Debugging is enabled for the Progress 4GL installed in
3) Debug using Compiler Directives [pre-processors]
26. How can we optimize a query?
27. How can we know where a transaction is being started in our program?
Using LISTING option with compile.
28. What all Version control tools you have used? CVS, PVCS
29. How can we know which index(s) will be used for a query in our code? Answer is XREF option.
30. If progress is not able to find any specific index(s) for a query and will perform a sequential
search over the entire table, then how can we know this from XREF option?
Answer is that WHOLE-INDEX will appear in the file generated by XREF.
31. How will you make Unit test cases? How does Unit Testing fit into the Software Development Life Cycle?
How can you coordinate with QA and testers? Idea of Test Proofs.
This is the first and the most important level of testing. As soon as the programmer develops a unit of code the unit is tested for various scenarios. As the application is built it is much more economical to find and eliminate the bugs early on. Hence Unit Testing is the most important of all the testing levels. As the software project progresses ahead it becomes more and more costly to find and fix the bugs.
In most cases it is the developer’s responsibility to deliver Unit Tested Code.
Unit Testing Tasks and Steps:
Step 1: Create a Test Plan
Step 2: Create Test Cases and Test Data
Step 3: If applicable create scripts to run test cases
Step 4: Once the code is ready execute the test cases
Step 5: Fix the bugs if any and re test the code
Step 6: Repeat the test cycle until the “unit” is free of all bugs
What is a Unit Test Plan? This document describes the Test Plan in other words how the tests will be carried out.
This will typically include the list of things to be Tested, Roles and Responsibilities, prerequisites to begin Testing, Test Environment, Assumptions, what to do after a test is successfully carried out, what to do if test fails, Glossary and so on
What is a Test Case? Simply put, a Test Case describes exactly how the test should be carried out.
For example the test case may describe a test as follows:
Step 1: Type 10 characters in the Name Field
Step 2: Click on Submit
Test Cases clubbed together form a Test Suite
Test Case Sample Test Case ID
Test Case Description
Input Data
Expected Result
Actual Result
Pass/Fail
Remarks
Additionally the following information may also be captured:
a) Unit Name and Version Being tested
b) Tested By
c) Date
d) Test Iteration (One or more iterations of unit testing may be performed)
Steps to Effective Unit Testing:
1) Documentation: Early on document all the Test Cases needed to test your code. A lot of times this task is not given due importance. Document the Test Cases, actual Results when executing the Test Cases, Response Time of the code for each test case. There are several important advantages if the test cases and the actual execution of test cases are well documented.
a. Documenting Test Cases prevents oversight.
b. Documentation clearly indicates the quality of test cases
c. If the code needs to be retested we can be sure that we did not miss anything
d. It provides a level of transparency of what was really tested during unit testing. This is one of the most important aspects.
e. It helps in knowledge transfer in case of employee attrition
f. Sometimes Unit Test Cases can be used to develop test cases for other levels of testing
2) What should be tested when Unit Testing: A lot depends on the type of program or unit that is being created. It could be a screen or a component or a web service. Broadly the following aspects should be considered:
a. For a UI screen include test cases to verify all the screen elements that need to appear on the screens
b. For a UI screen include Test cases to verify the spelling/font/size of all the “labels” or text that appears on the screen
c. Create Test Cases such that every line of code in the unit is tested at least once in a test cycle
d. Create Test Cases such that every condition in case of “conditional statements” is tested once
e. Create Test Cases to test the minimum/maximum range of data that can be entered. For example what is the maximum “amount” that can be entered or the max length of string that can be entered or passed in as a parameter
f. Create Test Cases to verify how various errors are handled
g. Create Test Cases to verify if all the validations are being performed
3) Automate where Necessary: Time pressures/Pressure to get the job done may result in developers cutting corners in unit testing. Sometimes it helps to write scripts, which automate a part of unit testing. This may help ensure that the necessary tests were done and may result in saving time required to perform the tests.
Summary:
“Unit Testing” is the first level of testing and the most important one. Detecting and fixing bugs early on in the Software Lifecycle helps reduce costly fixes later on. An Effective Unit Testing Process can and should be developed to increase the Software Reliability and credibility of the developer. The Above article explains how Unit Testing should be done and the important points that should be considered when doing Unit Testing.
Many new developers take the unit testing tasks lightly and realize the importance of Unit Testing further down the road if they are still part of the project. This article serves as a starting point for laying out an effective (Unit) Testing Strategy.
32. Have used VSTs(Virtual System Tables) for performance tuning? What do you know about VST and promon utility?
Virtual System Tables (VST's) were added in V8.2. VST's provide access to data that was previously only accessible through the promon utility.
For example, following information could be accessed using PROMON/VSTs:
1. User Control
2. Locking and Waiting Statistics
3. Block Access
4. Record Locking Table
5. Activity
6. Shared Resources
7. Database Status
8. Shut Down Database
The Progress documentation gives a basic description of each Virtual System Table (VST) but is generally inadequate for anyone attempting to do so serious work with VST's.
Virtual system tables give 4GL and SQL-92 applications access to the same database information that you collect with the PROMON (Progress monitor) utility. Virtual system tables (VSTs) enable an application to examine the status of a database and monitor its performance. With the database server running, 4GL and SQL-92 applications can call a VST and retrieve the specified information as run-time data.
Update Access to Virtual System Tables
Progress provides the empty, demo, and sports2000 databases with the virtual system table schemas already loaded. As new virtual system tables are made available, you can update the schemas in a database. To update the schemas, run the following PROUTIL command before you start the database server:
proutil db-name -C updatevst db-name
Specifies the database you are using.
33. What is the disadvantage of having smaller transactions size? Performance overhead
34. What is the efficient ways of coding to handle record locking, duration for which locks are
retained?
35. What is deadly embrace/deadlock?
Transaction is unit of work done. So a database management system will have number of transactions. There may be situations when two or more transactions are put into wait state simultaneously .In this position each would be waiting for the other transaction to get released.
Suppose we have two transactions one and two both executing simultaneously. In transaction numbered one we update student table and then update course table. We have transaction two in which we update course table and then update student table.
We know that when a table is updated it is locked and prevented from access from other transactions from updating. So in transaction one student table is updated it is locked and in transaction two course table is updated and it is locked.
We have given already that both transactions gets executed simultaneously. So both student table and course table gets locked so each one waits for the other to get released. This is the concept of deadlock in DBMS.
36. What is the default behavior for the following conditions –
ERROR (specially inside a trigger block)
ENDKEY
END-ERROR
STOP
QUIT
37. Which utilities can you use in order to determine the following:-
Transaction ------- LISTING
Index Usage ------- XREF
Record Scope ------ LISTING
38. OERA architecture
Answer: Reference architecture is a more general term than application architecture. It can be described as a master plan that application architects consult for the development of any number of applications (whereas, an application architecture usually refers to a description of a single application).
In the OpenEdge context, the OpenEdge Reference Architecture (RA) does not define specific software components, but defines the general functional categories of components that comprise an application. It can be used as a high-level blueprint for developing OpenEdge service-oriented business applications.
Benefits of OpenEdge RA: The OpenEdge RA is particularly useful because it:
àDivides the application into functional layers that separate data access logic, business
logic, and user interface logic. This facilitates customization, the development of new or improved features, and code reuse.
In addition, the layered approach supports the deployment of multiple user interfaces. Logic can be exposed to other applications for integration purposes in any of a number of ways, including the use of cross-platform technologies like Web Services, which are supported in the OpenEdge platform
àIs not only a model for new application development, but serves as a model for
transforming existing applications to a modern application architecture.
Using the OpenEdge RA as a model for analyzing a legacy application, you can categorize
the functionality of your application into business entity, data access, user interface, and
integration components.
After you define the relationships between the application’s components, you have, in
effect, created the functional design for your application that can be used as a guide for
further implementation and development.
à Is supported by OpenEdge tools and technologies.
à Is a guide to best practices for using OpenEdge tools and technologies.
à Allows for technology independence.
If, for example, you have a requirement to create user interface logic with JavaScript, you
can use business logic that was implemented with the Progress® 4GL.
Logic can be exposed to other applications for integration purposes in any of a number of
ways, including the use of cross-platform technologies like Web Services, which are
supported in the OpenEdge platform.
39. Locks types and then describe and Record scoping, weak scoped and strong scoped
records/blocks? Which blocks can start Transaction?
What is record scoping? How many types of records scoping blocks are there in Progress?
How is record scoping relating to transactions / duration for which locks are retained?
Transactions ===========
A transaction is a set of changes to the database, which should be done completely or not at all. A transaction can be as small as updating or adding a single order with the debits and credits or as large as
increasing the prices of all items in an inventory by 10%. What is common between these two examples is that if not finished completely there could be a loss of data integrity.
With PROGRESS if an error occurs while processing a transaction, the transaction is backed out. This means that every record that was changed during the transaction is restored to the value it contained
before the transaction started. In PROGRESS a transaction is one iteration of the outermost FOR EACH,
REPEAT, or procedure block that contains direct updates to the database.
The following will start a transaction:
à Any block using the TRANSACTION keyword on the block statement (DO, FOR EACH, or REPEAT).
à A procedure and each iteration of a DO ON ERROR, FOR EACH, or REPEAT block that directly
updates the database or directly reads records with an EXCLUSIVE-LOCK.
Note:
i) Directly updating the database means that the block contains at least one statement that can change the database, CREATE DELETE, and UPDATE are examples.
ii) DO blocks do not by default have transaction properties.
iii) An important thing to remember when determining the size of a transaction is that if a transaction is active when a procedure (a program started with the run statement) is called, the scope of the transaction is defined by the calling program.
iv) Transactions can start by default or they can be explicitly with the TRANSACTION keyword.
v) By using the TRANSACTION keyword it is possible to control the size of a transaction, to make it smaller or bigger to meet the demands of the application.
Record Scope ============
When a FIND or a FOR EACH statement reads a record, it places that record in an area of memory called the record buffer. The record is available in the buffer during the scope of the record, which is the
duration of that block.
By default, the scope of a record is the outermost FOR EACH, REPEAT, Or procedure block that references the record. Use the COMPILE statement with the LISTING option to see where your record buffers are scoped.
PROGRESS automatically scopes records to REPEAT, FOR EACH, or procedure blocks. You can scope a record explicitly to REPEAT, and DO blocks using the FOR keyword.
Record scope affects several things:
à At the end of a record's scope, if it has been modified it is written out to the database.
à At the end of the record scope PROGRESS releases the record and any locks that were placed on it,
so long as it is not involved in an active transaction.
à At the end of the record scope validation is performed against unique indexes and mandatory fields.
Record Locking ==============
By default whenever PROGRESS reads a record it is read with a SHARE-LOCK. This means that other users may read the record but may not update it until the SHARE-LOCK is released. If you try to update a
record that is SHARE-LOCKed you receive a message that it is in use.
By default when a record is updated PROGRESS puts an EXCLUSIVE-LOCK on the record. Other users cannot read or update the record until the EXCLUSIVE-LOCK is removed. When you try to EXCLUSIVE-LOCK a record that currently has a SHARE-LOCK or an EXCLUSIVE-LOCK you will get a message that the record is in use.
You may override the default record locking by specifying NO-LOCK or EXCLUSIVE-LOCK when reading the record.
The duration of a lock depends on the type of lock and when it was acquired.
A SHARE-LOCK acquired during a transaction is held until the end of the transaction or the record release whichever happens later. A SHARE-LOCK acquired outside a transaction is held until the record
release. A SHARE-LOCK acquired outside a transaction but held into a transaction is held until the later of the end of the transaction or the record release.
An EXCLUSIVE-LOCK is only acquired during a transaction, and is held until the end of the transaction. It is then converted to a SHARE-LOCK if the record scope is larger than the transaction and the record is
still active in a buffer.
Notice that when an EXCLUSIVE-LOCK is downgraded it is to a SHARE-LOCK even if the record was first read with a NO-LOCK. This is because when the NO-LOCK is upgraded to a EXCLUSIVE-LOCK it must be reread from the database before the lock is applied. If you want to override the SHARE-LOCK in the case where the transaction has ended but the record scope has not, use the RELEASE statement to release the record from the record buffer.
Record release occurs at the end of the record scope, or when a RELEASE statement is executed.
PROGRESS uses a lock table in shared memory to manage record locks. In version 5 of PROGRESS whenever a record is read, an entry is made in the lock table. This includes records read EXCLUSIVE-LOCK, SHARE-LOCK, and NO-LOCK. In PROGRESS version 6 no entries are made for records read NO-LOCK. The size of the lock table defaults to 500 entries and can be adjusted by using the -L parameter when starting the server.
40. Database design rules like how will you add a table in a db.
41. Indexes and their effect.
The Progress RDBMS uses indexes to rapidly locate a specific row or a group of rows in a table. When a query is executed, one or more indexes will be selected to be used to retrieve the requested data.
Understanding index selection is very important in the design of a database system. Improper use of indexes may cause a significant bottleneck in the performance of a system. It could lead to
performance degradation for the process using the improper index, and can also affect the performance of the entire system.
Advantages/Purpose:
à Fast access and retrieval of a specific row or set of rows.
à To retrieve rows in specific order.
à To enforce uniqueness of column values.
à To allow fast location of rows that contains a specific word or phrase.
Diadvantages/Cost of Adding an Index:
Although indexes usually provide performance gains in the retrieval of a specific row or set of rows, there is a cost in adding indexes to a
table:
à Slower create and delete operations on rows. This is because index entries will be added or deleted when rows are added or deleted. The more indexes you have, the more index entries will have to be added or deleted.
à Slower updates of index columns. This is because the index entries must be updated whenever a column that is a component of an index is updated with a new value.
à Additional storage space. This is because the index entries will occupy additional disk space.
à Additional administration and maintenance. This is because the increase in number of indexes will increase the time to rebuild indexes. In addition, the increase in size of the database will result in more time to manage the functions such as backup and restore.
Design Considerations:
As there are advantages and costs involved in adding indexes, therefore it is very important to understand the need for indexes and avoid unnecessary or redundant indexes.
It is also a good idea to review the components of each index during design time along with the type of queries that will be performed on the table.
This can help in reducing the number of indexes needed by organizing them to take advantage of multiple index selection. The following should be considered when evaluating the need for an index:
a) How many rows are in the table?
b) How often the rows will accessed using this index?
c) How many rows will be accessed using this index?
d) Are there existing indexes, which could be used instead?
e) Is the row access required during on-line transaction processing or is it required for nightly batch runs?
f) If it required for nightly batch runs, is the index really required?
Maintenance Considerations:
à Use PROUTIL's IDXANALYS qualifier to get information about index blocks and utilization.
à To execute the IDXANALYS qualifier, enter the following command:
proutil db-name -C idxanalys
The IDXANALYS qualifier provides:
-- The number of fields and levels in each index.
-- The size of each index, in blocks and in bytes.
-- The percent utilization within the index (that is, the degree of disk space efficiency).
-- A factor value that indicates whether to rebuild each index.
-- A summary of indexes for the current database and the percentage of total index space used by
each index.
NOTE: You can run PROUTIL with the IDXANALYS qualifier while the database is in use; however, Progress generates only approximate information.
The most important field in the IXANALYS display is the % Util field. This field shows the degree of consolidation of each index. If an index is several hundred blocks, and your application most frequently retrieves data, an index utilization of 85 percent or higher is optimal.
There are two ways to increase an index's utilization rate:
-- Compress the index with the database online or offline with the PROUTIL IDXCOMPACT utility.
-- Rebuild and compress the index offline with the PROUTIL IDXBUILD utility.
The Levels field shows the number of reads Progress performs in each index per entry. The Blocks and Bytes fields show you the size of each index.
The Factor field is based on the utilization and size of the index; it is an indicator of when you should rebuild indexes. Table 12-3 provides a description of the different ranges of values for the Factor field.
When you use the factor field to decide whether to rebuild an index, consider the context of how the particular index is used. For example, if an index is highly active, with continuous insertions and deletions, its utilization rate varies greatly, and a rebuild is inadvisable. However, a static index with a high factor value benefits from a rebuild..
42. What all Version control tools you have used? CVS, PVCS
43. How can we know which index(s) will be used for a query in our code? Answer is XREF option.
44. If progress is not able to find any specific index(s) for a query and will perform a sequential
search over the entire table, then how can we know this from XREF option?
Answer is that WHOLE-INDEX will appear in the file generated by XREF.
45. SDLC?
The HIDDEN and VISIBLE attributes are not simple opposites of each other.
You will want to set the HIDDEN attribute to selectively show different aspects of your interface. In some cases, you may want to hide some fields from some users. In other cases you may want to
hide a screen while you programmatically manipulate its contents.
The reason that HIDDEN should be used is that VISIBLE has side effects. VISIBLE was added to the PROGRESS 4GL in Version 7 to parallel the behavior of the keyword VIEW.
Both VIEW and VISIBLE, when applied to an object, implicitly make other objects visible. If you view a button, the frame that contains it and the window that contains the frame are also made visible. The following code sample shows this behavior when run from the Procedure Editor.
DEFINE BUTTON b LABEL "Hello, World".
DEFINE FRAME f
b AT ROW 1 COLUMN 1 WITH NO-LABELS.
ASSIGN b:VISIBLE = YES.
Running the above program will make the "Hello, World" button visible. But because the button won't actually be seen until the parent frame is made visible, PROGRESS will do that too. Compare this to the following program. If you run this program you should not be able to see either the frame or the button.
DEFINE BUTTON b LABEL "Hello, World".
DEFINE FRAME f
b AT ROW 1 COLUMN 1 WITH NO-LABELS.
ASSIGN b:HIDDEN = NO.
Even though the button is not HIDDEN, the user never sees it because its container has not been explicitly viewed.
When you are setting up the contents of a frame, you want to control the timing of when that frame is made visible to your users. You do not want the frame to appear before it is ready to be seen. If you
use the VISIBLE attribute on objects in the frame, there is a chance that the frame will appear before all your setup code has executed.
Because of these reasons, it is always safer to set the HIDDEN attribute.
47. Persistent procedures, how and when are they used?
Persistent procedures, how and why are they used? How to get the handle to a persistent
proc when it is or isn't running already. What is persistent procedure?
Is it mandatory to keep the persistent procedures alive thorough out the progress session?
Advantages of persistent procedures. What is the difference between persistent and
non-persistent procedures.
A non-persistent procedure creates and maintains its context only until it returns from execution.
The context of a non-persistent procedure remains in scope only until the RUN statement that
executes it completes.
A persistent procedure creates its context when it executes and then maintains that context after it returns until the end of the Progress session, or until it is explicitly deleted. The context of a persistent procedure remains in scope after the RUN statement that executes it completes until you remove it. As long as its context is in scope, the triggers and internal procedures of a persistent procedure remain available for execution by your application.
NOTE: If you run an application that creates persistent procedures from an ADE tool, that tool (for
example, the Procedure Editor or User Interface Builder) removes all instances of persistent
procedures, still created when the application terminates.
Advantages of Persistent Procedures:
a) Persistent procedures promote modular application design and development by more easily allowing you to distribute functionality among several procedures.
For example,
à You might build a persistent procedure that provides access to a database through a set of local buffers that it otherwise hides from the rest of the application or
à Your persistent procedure might create and manage its own windows while allowing independent access (non-modal access) to other windows in your application.
b) The additional modularity also helps to avoid hitting r-code segment limits. Thus, creating a persistent procedure whose context you access through internal procedures provides the most effective means to achieve encapsulation in Progress.
c) You can also use a persistent procedure to create multiple versions of the same context. Each time you call a persistent procedure, it creates a separate instance of its context. Your application (and
user) can access and manage each context independently from the others.
Scan the session’s PERSISTENT procedures for "ProgramName.w". If "ProgramName.w" is running, run its "InternalProcedureName". Otherwise run "ProgramName.w" PERSISTENT and then run its
"InternalProcedureName":
DEFINE VARIABLE hProcedureHandle AS HANDLE NO-UNDO.
DEFINE VARIABLE cProgramName AS CHARACTER NO-UNDO.
ASSIGN
cProgramName = "ProgramName.w"
hProcedureHandle = SESSION:FIRST-PROCEDURE.
DO WHILE VALID-HANDLE(hProcedureHandle):
IF hProcedureHandle:FILE-NAME = cProgramName THEN LEAVE.
hProcedureHandle = hProcedureHandle:NEXT-SIBLING.
END.
IF VALID-HANDLE(hProcedureHandle) THEN
RUN InternalProcedureName IN hProcedureHandle.
ELSE DO:
RUN VALUE(cProgramName) PERSISTENT SET hProcedureHandle.
RUN InternalProcedureName IN hProcedureHandle.
END.
48. Diff b/w what is the difference between &global-define and &scope-define?
Every preprocessor name that is defined has a specific scope. The scope, of a preprocessor name, is the area within its compilation unit where it can be accessed, or referenced, the by the preprocessor &name.
The scope of a preprocessor name is determined by:
a) Whether it is defined within the compilation unit and
b) Whether it is defined with the &GLOBAL-DEFINE or &SCOPED-DEFINE directive.
The syntax of the &GLOBAL-DEFINE and &SCOPED-DEFINE directives are identical but these directives
are used differently:
&GLOBAL-DEFINE preprocessor-name definition
&SCOPE-DEFINE preprocessor-name definition
A preprocessor name defined with the &GLOBAL-DEFINE directive is globally defined; a preprocessor
name defined with the &SCOPED-DEFINE directive is non-globally defined.
49. What is new in OE 10 over progress 9.x?
a. New Data types - BLOB, DATETIME, DATETIME-TZ, CLOB
b. The "Generated by WebSpeed" comment has been moved to the end of the web page because it creates problems using standards compliance with IE web-browser. Internet Explorer ignores the DOCTYPE tag if it's not the first in the page, such where the "Generated by Webspeed" comment used to be. Problems may arise if there are programs relying on the comment being the first line. The following can be undertaken to revert the output to the same as in the past.
• Specify something else than "text/html" for content-type to not avoid the generated comment in the end of the output.
• Manually add the comment back-in as first line of the output.
c. ProDataSets and direct related XML support
d. Open Client [.NET, Java] support
e. Auditing feature
f. OpenEdge® Replication [Fathom]
50. Client side transaction/Server Side Transaction.
51. Have u used complier directives to debug application?
52. What would be your plan of action when you are stuck with a problem?
UNDERSTANDING THE PROBLEM
à What are you trying to find or do?
à What are the unknowns?
à What information do you obtain from the problem?
à What information, if any, is missing or not needed?
DEVISING A PLAN
The following list of strategies, although not exhaustive, is very useful.
à Look for a pattern.
à Examine related problems, and determine if the same technique can be applied.
à Examine a simpler or special case of the problem to gain insight into the solution of the
original problem.
à Make a table.
à Make a diagram.
à Write an equation.
à Use guess and check.
CARRYING OUT THE PLAN
à Implement the strategy or strategies in step 2, and perform any necessary actions or
computations.
à Check each step of the plan as you proceed. This may be intuitive checking or a formal proof
of each step.
à Keep an accurate record of your work.
COMPARE
à Compare the results with the original problem.
53. What kind of editors you use to write the progress Application code?
54. What would you do to optimize the code in terms of time, memory and effort?
55. Which transaction you will prefer, batch transaction or one record at a time?
56. A program abc.p is called by many files. How could you find out what other files are calling this program?
57. Include files; what are the uses of these?
58. Publish and Subscribe.
PUBLISH Statement Causes a Progress named event to occur.
NOTE: Progress named events are completely different from the key function, mouse, widget, and direct manipulation events described in the "Events Reference" chapter of this manual.
SYNTAX:
PUBLISH event-name
[ FROM publisher-handle ]
[ ( parameter [ , parameter ] ... ) ]
event-name : A quoted character string or character expression representing the name of a named
event. If you use a quoted character string, Progress adds event-name to the PUBLISHED-EVENTS
attribute's list of events.
FROM publisher-handle: A procedure or widget handle representing the procedure or widget to which
Progress attributes the named event. The FROM option lets a procedure publish an event on behalf of
Another procedure or widget.
For example, if you want procedure A to publish a named event on behalf of procedure B, set publisher-
handle to the procedure handle of B.
If the FROM option does not appear, Progress attributes the event to THIS-PROCEDURE, the procedure
that contains the PUBLISH statement.
NOTE: If the FROM option does not appear and the PUBLISH statement occurs in a non-persistent procedure that does not publicize its handle, potential subscribers have no way of knowing the handle's value, and can subscribe to the event only by using the SUBSCRIBE statement's ANYWHERE option.
( parameter [ , parameter ] ... ) The parameters, if any, of the named event. As in the RUN statement,
you must supply a value for each INPUT and INPUT-OUTPUT parameter and a variable for each
OUTPUT parameter.
Also, if a named event has one or more parameters, the PUBLISH statement and each subscriber's local internal procedure (which the SUBSCRIBE statement names and which Progress runs when the named event occurs) must specify identical signatures-where signature means the number of parameters and the data type and mode (INPUT, etc.) for each.
NOTE: When the named event occurs and Progress runs each subscriber's local internal procedure, if the signature of a local internal procedure does not match the signature in the PUBLISH statement; Progress reports a run time error. Since the PUBLISH statement runs with an implicit NO-ERROR, errors are stored in the ERROR-STATUS handle.
The parameter syntax is identical to that of the RUN statement. For its specification, see the RUN
Statement reference entry.
EXAMPLE
The following example consists of four procedure files: a driver, a publisher, and two subscribers. The
driver, r-nedrvr.p, runs the publisher and the two subscribers persistently, then subscribes to the event
NewCustomer on behalf of the second subscriber.
r-nedrivr.p
/* r-nedrvr.p */
DEFINE VARIABLE hPub AS HANDLE.
DEFINE VARIABLE hSub1 AS HANDLE.
DEFINE VARIABLE hSub2 AS HANDLE.
DEFINE BUTTON bNewCust LABEL "New Customer".
DEFINE BUTTON bQuit LABEL "Quit".
RUN r-nepub.p PERSISTENT set hPub.
RUN r-nesub1.p PERSISTENT set hSub1 (hPub).
RUN r-nesub2.p PERSISTENT set hSub2.
/* Subscribe to event NewCustomer on behalf of subscriber 2 */
SUBSCRIBE PROCEDURE hSub2 TO "NewCustomer" IN hPub.
FORM bNewCust bQuit WITH FRAME x.
ENABLE ALL WITH FRAME x.
ON CHOOSE OF bNewCust RUN NewCust in hPub.
WAIT-FOR CHOOSE OF bQuit OR WINDOW-CLOSE OF CURRENT-WINDOW.
The publisher, r-nepub.p, publishes the event NewCustomer.
r-nepub.p
/* r-nepub.p */
PROCEDURE NewCust:
DEFINE VARIABLE name AS CHARACTER INITIAL "Sam".
/* Let subscriber know new customer */
PUBLISH "NewCustomer" (INPUT name).
END PROCEDURE.
The first subscriber, nesub1.p, subscribes to the event NewCustomer.
r-nesub1.p
/* r-nesub1.p */
DEFINE INPUT PARAMETER hPub AS HANDLE.
SUBSCRIBE TO "NewCustomer" IN hPub.
PROCEDURE NewCustomer:
DEFINE INPUT PARAMETER name AS CHAR.
MESSAGE "Subscriber 1 received event NewCustomer concerning" name
VIEW-AS ALERT-BOX.
END.
The second subscriber, nesub2.p, already subscribed to the event NewCustomer, cancels all
subscriptions.
r-nesub2.p
/* r-nesub2.p */
PROCEDURE NewCustomer:
DEFINE INPUT PARAMETER name AS CHAR.
MESSAGE "Subscriber 2 received event NewCustomer concerning" name
VIEW-AS ALERT-BOX.
/* This subscriber receives the first event, then removes itself */
UNSUBSCRIBE TO ALL.
END.
To start the example, run the driver, r-nedrvr.p.
NOTES
à If a named event has multiple subscribers, the order in which Progress notifies subscribers is
undefined.
à INPUT-OUTPUT parameters can accumulate values from a set of subscribers. When a subscriber
receives an INPUT-UTPUT parameter, it has the value that the previous subscriber set it to.
When the publisher receives an INPUT-OUTPUT parameter, it has the value that the last subscriber
set it to.
à If a named event with multiple subscribers has OUTPUT parameters, each time a subscriber sets an
OUTPUT parameter, Progress overwrites the previous value. For this reason, Progress Software
Corporation recommends that you use OUTPUT parameters with named events only when there is a
single subscriber.
à If a named event has multiple subscribers and several subscribers specify a RETURN statement with a
return value, the RETURN-VALUE function evaluates to the return value set by the last subscriber.
à Progress executes the PUBLISH statement with an implicit NO-ERROR option. To find out if any errors
occurred, and if so, which ones, use the ERROR-STATUS system handle.
à If publisher-handle is a widget handle, the value of SOURCE-PROCEDURE in each of the subscribers'
internal procedures will be the handle of the procedure that created the widget.
SUBSCRIBE Statement Creates a subscription to a Progress named event. NOTE: Progress named events are completely different from the key function, mouse, widget, and direct manipulation events described in the "Events Reference" chapter in this manual.
SYNTAX
SUBSCRIBE [ PROCEDURE subscriber-handle ]
[ TO ] event-name
{ IN publisher-handle | ANYWHERE }
[ RUN-PROCEDURE local-internal-procedure ]
[ NO-ERROR ]
PROCEDURE subscriber-handle A procedure or handle representing the subscriber.
The PROCEDURE option lets one procedure create a subscription on behalf of another. For example, if
you want procedure A to create a subscription on behalf of procedure B, set subscriber-handle to the
procedure handle of B.
If the PROCEDURE option does not appear, Progress creates a subscription on behalf of THIS-
PROCEDURE, the procedure that contains the SUBSCRIBE statement.
TO event-name A quoted string or a character expression representing the name of the event.
IN publisher-handle Subscribes to the named events published by publisher-handle.
If publisher-handle is not a valid procedure or widget handle at the time the SUBSCRIBE statement
executes, Progress reports a run time error unless you specify the NO-ERROR option.
ANYWHERE Subscribes to named events published within the Progress session-regardless of the publisher.
RUN-PROCEDURE local-internal-procedure A quoted string or character expression representing the
name of an internal procedure that resides within the subscribing program. Progress runs local-internal-
procedure when the named event occurs.
If the RUN-PROCEDURE option does not appear, when the named event occurs, Progress runs an
internal procedure with the same name as the named event.
NOTE: The RUN-PROCEDURE option lets you create a subscription when the event name and the procedure name do not match, or when you must subscribe to two different events that have the same name.
When the named event occurs, Progress RUNs each subscriber's local internal procedure, passing the parameters, if any, The order in which Progress notifies subscribers is undefined. Progress always performs this RUN with an implicit NO-ERROR, and logs errors to the ERROR-STATUS system handle.
NO-ERROR Tells Progress not to report a run time error if publisher-handle or subscriber-handle is not a valid
procedure handle, or if Progress cannot evaluate an event-name expression. Errors are still generated,
however, and are stored in the ERROR-STATUS handle.
EXAMPLE
For an example, see the reference entry for the PUBLISH Statement in this manual.
NOTES
à Within the local internal procedure, you can get a handle to the publisher of the named event by using
the SOURCE-PROCEDURE system handle.
à If Progress detects a redundant SUBSCRIBE statement¾that is, a SUBSCRIBE statement with the
same event name, and either the same publisher handle or the same ANYWHERE option¾Progress
does not report an error.
à If event-name is a string containing spaces or is otherwise not a standard Progress name, use one of
the following techniques:
à Use the RUN-PROCEDURE option to assign the local internal procedure a more conventional name.
à When you define local-internal-procedure, put its name in quotes, as in the following example:
PROCEDURE "spaced event":
PUBLISH and SUBSCRIBE with ADM2
The PUBLISH / SUBSCRIBE mechanism can be used within SmartObjects too.
The Progress ADM2 implements SmartLinks using the Progress 4GL PUBLISH
& SUBSCRIBE event mechanism.
SmartLinks are based on the PUBLISH / SUBSCRIBE mechanism and are
created and maintained by each SmartObject's container. Each link is
a property in each SmartObject that supports that type of link. The
smart.p super procedure has procedures and functions for link
management. Each link is mapped to one or more events that use the
PUBLISH and SUBSCRIBE statements. These event lists are also
SmartObject properties.
It is possible to dynamically add a SmartLink to any SmartObject with
a RUN addLink statement. For example:
RUN addLink (INPUT hSmartPanel, INPUT `Navigation':U, INPUT hdCust).
It is also possible to add your customized links to SmartObjects with
addLink; for example, using the addLink procedure to add a customized
SmartLink that is not recognized as one of the object's supported
links:
RUN addLink(h1, 'newLink', h2).
The addLink procedure now executes the following statement:
SUBSCRIBE PROCEDURE h2 TO 'newlink' IN h1.
Now it is necessary to create a procedure called 'newlink' on the
subscriber. The procedure h1 can now execute the PUBLISH statement
whenever it wants to invoke the named event in h2:
PUBLISH 'newlink'.
Using the PUBLISH / SUBSCRIBE mechanism with SmartObjects is only
recommended for cases in which it is not possible to use the
SmartLinks; for example, to communicate between a SmartObject and a
non-smart object such as a fill-in.
EXAMPLE:
Example of PUBLISH and SUBSCRIBE with a SmartWindow:
In the example below, SmartWindows show how to use the PUBLISH /
SUBSCRIBE mechanism with SmartObjects, although, to reduce the code,
no other SmartObject is used in the example.
In the main window, publisher.w, there is a normal browser in one
SmartWindow and a fill-in in the SmartWindow subscriber.w. This
fill-in merely displays the cust-num field of the selected row in the
browser.
In this case it is necessary to override the super procedure
InitalizeObject on the subscriber SmartWindow with the Fill-in, and
add the subscribe command after the RUN SUPER statement.
In the publisher.w window, the named event is being published in the
VALUE-CHANGED of the browse.
****PUBLISHER.W:
&Scoped-define WINDOW-NAME wWin
CREATE WIDGET-POOL.
/* ******************** Preprocessor Definitions ************** */
&Scoped-define PROCEDURE-TYPE SmartWindow
&Scoped-define DB-AWARE no
&Scoped-define ADM-CONTAINER WINDOW
&Scoped-define ADM-SUPPORTED-LINKS
Data-Target,Data-Source,Page-Target,Update-Source,Update-Target,Filter-target,Filter-Source
&Scoped-define FRAME-NAME fMain
&Scoped-define BROWSE-NAME BROWSE-1
&Scoped-define INTERNAL-TABLES Customer
&Scoped-define FIELDS-IN-QUERY-BROWSE-1 Customer.Cust-Num
Customer.Name Customer.City
&Scoped-define ENABLED-FIELDS-IN-QUERY-BROWSE-1
&Scoped-define OPEN-QUERY-BROWSE-1 OPEN QUERY BROWSE-1 FOR EACH
Customer NO-LOCK INDEXED-REPOSITION.
&Scoped-define TABLES-IN-QUERY-BROWSE-1 Customer
&Scoped-define FIRST-TABLE-IN-QUERY-BROWSE-1 Customer
&Scoped-define OPEN-BROWSERS-IN-QUERY-fMain
~{&OPEN-QUERY-BROWSE-1}
&Scoped-Define ENABLED-OBJECTS BROWSE-1 BUTTON-1 BtnDone
DEFINE VAR wWin AS WIDGET-HANDLE NO-UNDO.
DEFINE BUTTON BtnDone DEFAULT LABEL "&Done" SIZE 15 BY 1.14 BGCOLOR 8.
DEFINE BUTTON BUTTON-1 LABEL "Subscriber Window" SIZE 25 BY 1.19.
DEFINE QUERY BROWSE-1 FOR Customer SCROLLING.
DEFINE BROWSE BROWSE-1
QUERY BROWSE-1 NO-LOCK DISPLAY
Customer.Cust-Num FORMAT ">>>>9":U
Customer.Name FORMAT "x(20)":U
Customer.City FORMAT "x(12)":U WIDTH 9
WITH NO-ROW-MARKERS SEPARATORS SIZE 44 BY 7.14 EXPANDABLE.
/.* ************************ Frame Definitions ***************** */
DEFINE FRAME fMain
BROWSE-1 AT ROW 2.19 COL 7
BUTTON-1 AT ROW 10.05 COL 4
BtnDone AT ROW 10.05 COL 39
WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D
AT COL 1 ROW 1 SIZE 59.2 BY 12.1
DEFAULT-BUTTON BtnDone.
/* ************************* Create Window ******************** */
IF SESSION:DISPLAY-TYPE = "GUI":U THEN
CREATE WINDOW wWin ASSIGN
HIDDEN = YES
TITLE = "Prinicpal>"
HEIGHT = 12.1 WIDTH = 59.2
MAX-HEIGHT = 28.81 MAX-WIDTH = 146.2
VIRTUAL-HEIGHT = 28.81 VIRTUAL-WIDTH = 146.2
RESIZE = no SCROLL-BARS = no
STATUS-AREA = no BGCOLOR = ?
FGCOLOR = ? THREE-D = yes
MESSAGE-AREA = no SENSITIVE = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
/* ************************* Included-Libraries *************** */
{src/adm2/containr.i}
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN wWin:HIDDEN = yes.
ON END-ERROR OF wWin /* <Prinicpal> */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
IF THIS-PROCEDURE:PERSISTENT THEN RETURN NO-APPLY.
END.
ON WINDOW-CLOSE OF wWin /* <Prinicpal> */
DO:
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN NO-APPLY.
END.
ON VALUE-CHANGED OF BROWSE-1 IN FRAME fMain
DO:
PUBLISH "custom" ( customer.cust-num ).
END.
ON CHOOSE OF BtnDone IN FRAME fMain /* Done */
DO:
&IF "{&PROCEDURE-TYPE}" EQ "SmartPanel" &THEN
&IF "{&ADM-VERSION}" EQ "ADM1.1" &THEN
RUN dispatch IN THIS-PROCEDURE ('exit').
&ELSE
RUN exitObject.
&ENDIF
&ELSE
APPLY "CLOSE":U TO THIS-PROCEDURE.
&ENDIF
END.
ON CHOOSE OF BUTTON-1 IN FRAME fMain /* Open Subscriber Window */
DO:
RUN subscriber.w.
END.
/* *************************** Main Block ********************** */
/* Include custom Main Block code for SmartWindows. */
{src/adm2/windowmn.i}
/* ********************** Internal Procedures ****************** */
PROCEDURE adm-create-objects :
END PROCEDURE.
PROCEDURE disable_UI :
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN DELETE WIDGET wWin.
IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.
PROCEDURE enable_UI :
ENABLE BROWSE-1 BUTTON-1 BtnDone
WITH FRAME fMain IN WINDOW wWin.
{&OPEN-BROWSERS-IN-QUERY-fMain}
VIEW wWin.
END PROCEDURE.
PROCEDURE exitObject :
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN.
END PROCEDURE.
****SUBSCRIBER.W:
&Scoped-define WINDOW-NAME wWin
CREATE WIDGET-POOL.
/* ******************** Preprocessor Definitions ************* */
&Scoped-define PROCEDURE-TYPE SmartWindow
&Scoped-define DB-AWARE no
&Scoped-define ADM-CONTAINER WINDOW
&Scoped-define ADM-SUPPORTED-LINKS
Data-Target,Data-Source,Page-Target,Update-Source,Update-Target,Filter-target,Filter-Source
&Scoped-define FRAME-NAME fMain
&Scoped-Define ENABLED-OBJECTS BtnDone cust-num
&Scoped-Define DISPLAYED-OBJECTS cust-num
DEFINE VAR wWin AS WIDGET-HANDLE NO-UNDO.
DEFINE BUTTON BtnDone DEFAULT LABEL "&Done" SIZE 15 BY 1.14 BGCOLOR 8.
DEFINE VARIABLE cust-num AS CHARACTER FORMAT "X(15)":U LABEL "Cust-num
from publisher:"
VIEW-AS FILL-IN SIZE 14 BY 1 NO-UNDO.
/* ************************ Frame Definitions ****************** */
DEFINE FRAME fMain
BtnDone AT ROW 2.67 COL 51
cust-num AT ROW 3.14 COL 28 COLON-ALIGNED
WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D
AT COL 1 ROW 1 SIZE 80 BY 8.29
DEFAULT-BUTTON BtnDone.
IF SESSION:DISPLAY-TYPE = "GUI":U THEN
CREATE WINDOW wWin ASSIGN
HIDDEN = YES
TITLE = "SMART SUBSCRIBER"
HEIGHT = 4.33 WIDTH = 66.6
MAX-HEIGHT . = 34.33 MAX-WIDTH = 204.8
VIRTUAL-HEIGHT = 34.33 VIRTUAL-WIDTH = 204.8
RESIZE = no SCROLL-BARS = no
STATUS-AREA = no BGCOLOR = ?
FGCOLOR = ? THREE-D = yes
MESSAGE-AREA = no SENSITIVE = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
/* ************************* Included-Libraries **************** */
{src/adm2/containr.i}
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN wWin:HIDDEN = yes.
ON END-ERROR OF wWin /* SMART SUBSCRIBER */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
IF THIS-PROCEDURE:PERSISTENT THEN RETURN NO-APPLY.
END.
ON WINDOW-CLOSE OF wWin /* SMART SUBSCRIBER */
DO:
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN NO-APPLY.
END.
ON CHOOSE OF BtnDone IN FRAME fMain /* Done */
DO:
&IF "{&PROCEDURE-TYPE}" EQ "SmartPanel" &THEN
&IF "{&ADM-VERSION}" EQ "ADM1.1" &THEN
RUN dispatch IN THIS-PROCEDURE ('exit').
&ELSE
RUN exitObject.
&ENDIF
&ELSE
APPLY "CLOSE":U TO THIS-PROCEDURE.
&ENDIF
END.
/* *************************** Main Block ******************** */
/* Include custom Main Block code for SmartWindows. */
{src/adm2/windowmn.i}
/* ********************** Internal Procedures *************** */
PROCEDURE adm-create-objects :
END PROCEDURE.
PROCEDURE custom :
DEF INPUT PARAMETER cust AS CHAR.
cust-num=cust.
DISPLAY cust-num WITH FRAME fmain.
END PROCEDURE.
PROCEDURE disable_UI :
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN DELETE WIDGET wWin.
IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.
PROCEDURE enable_UI :
DISPLAY cust-num
WITH FRAME fMain IN WINDOW wWin.
ENABLE BtnDone cust-num
WITH FRAME fMain IN WINDOW wWin.
{&OPEN-BROWSERS-IN-QUERY-fMain}
VIEW wWin.
END PROCEDURE.
PROCEDURE exitObject :
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN.
END PROCEDURE.
PROCEDURE initializeObject :
RUN SUPER.
SUBSCRIBE TO "custom" ANYWHERE.
END PROCEDURE.
59. Super Procedures.
ADD-SUPER-PROCEDURE( ) method Associates a super procedure file with a procedure file or with the current OpenEdge
session. When a procedure file invokes an internal procedure or a user-defined function,
Progress searches for it, among other places, in the super procedures (if any) of the procedure
file and of the current OpenEdge session. The procedure-search option determines which
procedures are searched.
Return type: LOGICAL
Applies to: SESSION system handle, THIS-PROCEDURE system handle and all procedure
handles
ADD-SUPER-PROCEDURE ( super-proc-hdl [ , proc-search ] )
Super-proc-handle
The handle of a running persistent procedure that you want to make a super procedure of the local procedure or of the current OpenEdge session.
ADD-SUPER-PROCEDURE returns FALSE if super-proc-hdl is not a valid handle, or if Progress detects that the method was not successful. Otherwise, the method returns TRUE.
proc-search
Optional expression that determines which super procedures are searched when super-proc-hdl invokes RUN SUPER or the SUPER function. Valid values are SEARCH-SELF (or 1) or SEARCH-TARGET (or 2). The default, if there is no entry, is SEARCH-SELF. The search commences in the super procedure stack of super-proc-hdl.
Consider the following:
o SEARCH-SELF starts searching in the procedure file that initiated the current internal procedure or user-defined function.
o SEARCH-TARGET starts searching the super procedures of the procedure file that originally invoked the current internal procedure or user-defined function (the procedure with the original RUN statement). If the procedure was RUN . . . IN procedure-handle, SEARCH-TARGET searches the super procedures of procedure-handle.
o A given super-proc-hdl can be added as either SEARCH-TARGET or SEARCH-SELF, but cannot be added as both. If proc-search is set for a super-proc-hdl, then any attempt to change its value generates a run-time warning, but the ADD-SUPER-PROCEDURE( ) method succeeds. The warning message “Changing proc-search-string for procedure <.p-name> from <string> to <string>” is presented to indicate that the application is using an instance of a given super procedure in an inconsistent manner. This warning message can be suppressed by using the SESSION:SUPPRESS-WARNINGS attribute. In addition, the warning message can be avoided by creating two instances of super-proc-hdl, one identified as SEARCH-TARGET and the other identified as SEARCH-SELF.
Associating a super procedure with a procedure The following example associates a super procedure with the current procedure:
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(my-super-proc-hdl, SEARCH-SELF).
The following example:
local-proc-hdl:ADD-SUPER-PROCEDURE(my-super-proc-hdl, SEARCH-TARGET).
The procedure to which you add a super procedure is called the local procedure of the super procedure.
Associating a super procedure with the current OpenEdgesession The following example associates a super procedure with the current OpenEdge session:
SESSION:ADD-SUPER-PROCEDURE(my-super-proc-hdl).
When you do this, Progress automatically associates the super procedure with all the session’s
procedures—persistent and nonpersistent—without your having to change their code in any way.
This technique lets you replace occurrences of the following:
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(super-proc-hdl).
in individual procedures with a single occurrence of the following:
SESSION:ADD-SUPER-PROCEDURE(super-proc-hdl).
Super procedure stacking
You can associate multiple super procedures with a single local procedure or with the current
OpenEdge session. When you do this, Progress stores (and later on, searches) the
corresponding procedure handles in last in first out (LIFO) order—the handle of the most recently
added super procedure first, the handle of the next most recently added super procedure second,
etc.
A collection of super procedure handles associated with a local procedure or with the current
OpenEdge session is called a super procedure stack. The handle of the most recently added
super procedure occupies the top of the stack.
If you add a super procedure that is already in the stack, Progress removes the previous
occurrence of the super procedure handle from the stack and adds the new occurrence to the top
of the stack—all without reporting an error.
Super procedure chaining You can add a super procedure to a super procedure. For example, imagine the following
scenario:
1. A, B, and C are procedure files running persistently.
2. B is a super procedure of A.
3. C is a super procedure of B.
B is a super procedure (of A) and has a super procedure (C).
When you add a super procedure to a super procedure, the result is a super procedure chain,
each link of which consists of two elements: a local procedure and its super procedure. When
Progress searches a super procedure chain, it does not proceed to the next link unless the
current link’s super procedure element explicitly invokes its super version (by using the
RUN SUPER statement or the SUPER function).
For example, imagine the following scenario:
1. A, B, and C, and X are procedure files running persistently.
2. add-record is an internal procedure different versions of which reside in A, B, and C.
3. B is a super procedure of A.
4. C is a super procedure of B.
5. X says RUN add-record IN A.
The following events occur:
1. Progress searches A for add-record and runs it if found.
2. If and only if A’s add-record exists and says RUN SUPER, Progress searches B for add-record and runs it if found.
Note: If A does not contain add-record, the following events occur: If B contains add-record, Progress runs it. If B does not contain add-record, Progress does not search for add-record in C.
3. If and only if B’s add-record exists and says RUN SUPER, Progress searches C for add-record and runs it if found.
In this way, Progress avoids excessive and possibly circular searching.
Search rules Progress searches for internal procedures and user-defined functions depending on how the
internal procedure or user-defined function is invoked. The search rules illustrated in the first
three cases assume that all the super procedures were added with no proc-search value or with a
proc-search value of SEARCH-SELF. The fourth case illustrates the search process when a
super procedure is added with a proc-search value of SEARCH-TARGET:
Case 1: When Progress encounters a statement like the following:
RUN add-record(’customer’).
Progress searches for add-record as follows:
1. As an internal procedure in the local procedure.
2. As an internal procedure in a super procedure of the local procedure.
3. As an internal procedure in a super procedure of the OpenEdge session.
4. As an external procedure file add-record.p or add-record.r.
Case 2: When Progress encounters a statement like the following:
RUN add-record(’customer’) IN my-proc-hdl.
Progress searches for add-record as follows:
1. As an internal procedure in my-proc-hdl.
2. As an internal procedure in a super procedure of my-proc-hdl.
3. As an internal procedure in a super procedure of the OpenEdge session.
Case 3: When Progress encounters a statement like the following:
add-record(’customer’).
Progress searches for add-record as follows:
1. As a user-defined function in the local procedure.
2. As a user-defined function in a super procedure of the local procedure.
3. As a user-defined function in a super procedure of the OpenEdge session.
Note: The rules of Case 3 apply whether or not the user-defined function’s declaration (function prototype) includes the IN proc-hdl option. In Case 3, proc-hdl represents the local procedure.
Search rules for SEARCH-TARGET Case 4: A procedure, main.p, has added three super procedures, S1, S2, and S3 (in that order). Each of these super procedures has added its own super procedures, S1A, S1B, S2A, S2B, S3A, S3B. The procedure, add-record, exists in three places: in S1, in S2 where it contains a RUN SUPER statement, and in S2A.
When Progress encounters a statement like "RUN add-record(’customer’).", it searches
for the add-record procedure:
1. As an internal procedure in the local procedure, main.p.
2. Then as an internal procedure in S3, and then in S2 where it is found.
If add-record was added with no proc-search value or with a proc-search value of
SEARCH-SELF, when RUN SUPER is executed within add-record in S2, Progress starts
searching in S2A, which is next in the search stack of the super procedure S2.
If add-record was added with a proc-search value of SEARCH-TARGET, when RUN
SUPER is executed within add-record in S2, Progress will start searching in S1 which is
next in the search stack of the local procedure, main.p.
Note: The search commences with the super procedure following super-proc-hdl in the local procedure’s chain.
60. SDLC phases and your involvement in each phases in your projects.
61. Difference between state-less and state-free (new in OE).
62. Difference b/w strong and week scope. Give examples.
63. Dynamic temp-table, dynamic buffers. Give examples.
CREATE TEMP-TABLE statement Creates a temp-table dynamically at run time. The temp-table that is created is empty and
must be defined using ADD/CREATE methods.
Syntax CREATE TEMP-TABLE widget-handle
[ IN WIDGET-POOL widget-pool-name ]
widget-handle
A variable of type WIDGET-HANDLE that represents the handle of the temp-table object.
IN WIDGET-POOL widget-pool-name
An expression of type CHARACTER that evaluates, at run time, to the name of the widget pool that contains the dynamic temp-table.
Note: Widget pool names are not case-sensitive.
Example The following example creates a temp-table like the order table and populates it from the order
table. In addition, the corresponding sales-rep name is added from the salesrep table.
r-cretmpt.p
DEFINE VARIABLE tth AS HANDLE.
DEFINE VARIABLE bh AS HANDLE.
DEFINE VARIABLE qh AS HANDLE.
DEFINE VARIABLE buf-ord-hndl AS HANDLE.
DEFINE VARIABLE buf-rep-hndl AS HANDLE.
DEFINE VARIABLE fld1 AS HANDLE.
DEFINE VARIABLE fld2 AS HANDLE.
/* get database table handles */
buf-ord-hndl = BUFFER order:HANDLE.
buf-rep-hndl = BUFFER salesrep:HANDLE.
/* create an empty undefined temp-table */
CREATE TEMP-TABLE tth.
/* give it order table’s fields & indexes */
tth:CREATE-LIKE(buf-ord-hndl).
/* add field like Salesrep.Rep-Name */
tth:ADD-LIKE-FIELD("RepName","Salesrep.Rep-Name").
/* no more fields will be added */
tth:TEMP-TABLE-PREPARE("ordx").
/* get the buffer handle for the temp-table */
bh = tth:DEFAULT-BUFFER-HANDLE.
/* populate the temp-table from order */
FOR EACH order:
bh:BUFFER-CREATE.
bh:BUFFER-COPY(buf-ord-hndl).
/* add the corresponding salesrep name */
FIND salesrep WHERE salesrep.sales-rep = order.sales-rep NO-ERROR.
IF AVAILABLE salesrep THEN
bh:BUFFER-COPY(buf-rep-hndl,?,"RepName,rep-name").
END.
/* run a query to access the temp-table */
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE("for each ordx where order-num < 50 BY RepName").
qh:QUERY-OPEN().
fld1 = bh:BUFFER-FIELD("order-num").
fld2 = bh:BUFFER-FIELD("RepName").
/* display the order-number and the salesrep name */
REPEAT:
qh:GET-NEXT().
IF qh:QUERY-OFF-END THEN LEAVE.
DISPLAY fld1:BUFFER-VALUE() FORMAT "X(10)".
DISPLAY fld2:BUFFER-VALUE() FORMAT "X(20)".
END.
qh:QUERY-CLOSE().
bh:BUFFER-RELEASE().
DELETE OBJECT tth.
DELETE OBJECT qh.
Notes Ø Once the temp-table fields and indexes are defined using the ADD/CREATE methods, the definition must be terminated by using the TEMP-TABLE-PREPARE method before the temp-table can be used.
Ø Once the temp-table is prepared, it can be manipulated by using its buffer object handle which is retrieved using the DEFAULT-BUFFER-HANDLE attribute. All the BUFFER methods are available to the dynamic temp-table.
Ø The dynamic temp-table object is scoped like the buffer object. It is created in a widget pool and ends when the widget pool ends or when it is deleted with the DELETE OBJECT statement. You may not delete the default buffer object belonging to a dynamic temp-table.
Ø Errors for dynamic temp-tables do not automatically raise the ERROR condition since they occur inside a widget expression. All the methods that can have errors return FALSE if an error occurs, so they must be tested. If NO-ERROR is in effect in the statement containing the widget reference, no messages display, but they can be retrieved from the ERROR-STATUS system handle.
Dynamic Buffers:
CREATE BUFFER statement Creates a dynamic buffer.
Syntax
CREATE BUFFER handle FOR TABLE table-exp | table-handle-exp
[ BUFFER-NAME buffer-expression ]
[ IN WIDGET-POOL widget-pool-name ]
handle
A variable of type HANDLE that represents the handle of the buffer object.
FOR TABLE table-exp | table-handle-exp
A character expression that evaluates to a unique database table name or temp-table name or to the handle of a database table or a temp-table.
Note: If the table name is ambiguous, you must qualify it with a database name.
BUFFER-NAME buffer-expression
An expression of type CHARACTER that evaluates, at run time, to the name of the dynamic buffer you are creating. This option lets a dynamic query have multiple buffers for the same table.
IN WIDGET-POOL widget-pool-name
An expression of type CHARACTER that evaluates, at run time, to the name of the widget pool that contains the dynamic buffer.
Note: Widget pool names are not case-sensitive.
Example The following example runs the query “for each customer” dynamically against the Sports
database using a purely dynamic buffer with no compile time references at all:
r-crtbuf.p
/* r-crtbuf.p */
/* requires a connection to the Sports database */
DEFINE VARIABLE i AS INTEGER.
DEFINE VARIABLE qh AS WIDGET-HANDLE.
DEFINE VARIABLE bh AS WIDGET-HANDLE.
DEFINE VARIABLE fh AS WIDGET-HANDLE EXTENT 10.
CREATE BUFFER bh FOR TABLE "customer".
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE("for each customer").
qh:QUERY-OPEN.
qh:GET-FIRST.
DISPLAY bh:NAME.
REPEAT i = 1 TO 10.
fh[i] = bh:BUFFER-FIELD(i).
DISPLAY fh[i]:NAME STRING(fh[i]:BUFFER-VALUE).
END.
DELETE WIDGET bh.
Which one is beneficial (context, connection) [which is most complex and which is
simplest]
a) State-aware
b) State-reset
c) State-less [should be used]
d) State-free
2. What is pessimistic Locking, What is optimistic locking?
a) Optimistic: The table is open for read/write over entire network for all users/sessions. We
can move the cursor, backward or forward dynamically.
b) Pessimistic: The table is open for read/write only for that current session. The other
session users cannot edit the same.
These are methodologies used to handle multi-user issues. How does one handle the fact that 2 people want to update the same record at the same time?
Approach 1 - 'lost update' - User 1 reads a record
- User 2 reads the same record
- User 1 updates that record
- User 2 updates the same record
User 2 has now over-written the changes that User 1 made. They are completely gone, as if they
never happened. This is called a 'lost update'.
Approach 2 - Pessimistic locking - Lock the record when it is read
- User 1 reads a record *and locks it* by putting an exclusive lock on the record (FOR UPDATE)
- User 2 attempts to read *and lock* the same record, but must now wait behind User 1
- User 1 updates the record (and, of course, commits)
- User 2 can now read the record *with the changes that User 1 made*
- User 2 updates the record complete with the changes from User 1
User 1 is locking a record that they might not ever update. User 2 cannot even read the record because they want an exclusive lock when reading as well.
This approach requires far too much exclusive locking, and the locks live far too long (often across user control - an *absolute* no-no). This approach is almost *never* implemented.
The lost update problem is solved. The problem with this approach is concurrency.
Approach 3 - Optimistic locking – doesn’t Lock the record when it is read
It does not use exclusive locks when reading. Instead, a check is made during the update to make sure that the record has not been changed since it was read. This can be done by checking every field in the table.
3. What is transaction scoping? What is transaction? How can increase the scope of the transaction? What is Transaction? How do you Minimizing and Maximizing the transaction scope? What is a transaction? What do you mean by transaction scope.
How does Progress know where to start the transaction and how much work to undo or back
out?
A transaction is a set of changes to the database, which the system either completes or discards, leaving no modification to the database. The terms physical transaction and commit unit refer to the same concept as the Progress transaction. For example, in the above scenario where you are adding customer records, each customer record you add is a transaction.
The transaction scoping means the part of the program code block in which transaction remains active. Transaction scoping depends on the size of the containing block.
The following transaction blocks start a transaction if one is not already active:
à Any block that uses the TRANSACTION keyword on the block statement (DO, FOR EACH, or REPEAT).
àA procedure block, trigger block, and each iteration of a DO ON ERROR, FOR EACH, or REPEAT block that directly updates the database or directly reads records with EXCLUSIVE-LOCK. You use EXCLUSIVE-LOCK to read records in multi-user applications.
Directly updating the database means that the block contains at least one statement that can change the database. CREATE, DELETE, and UPDATE are examples of such statements.
If a block contains FIND or FOR EACH statements that specify EXCLUSIVE-LOCK, and at least one of the FIND or FOR EACH statements is not embedded within inner transaction blocks, then the block is directly reading records with EXCLUSIVE-LOCK.
Note that DO blocks do not automatically have the transaction property. Also, if the procedure or transaction you are looking at is run by another procedure, you must check the calling procedure to determine whether it starts a transaction before the RUN statement.
Once a transaction is started, all database changes are part of that transaction, until it ends.
Each user of the database can have just one active transaction at a time.
4. Which tools do you use in query optimization? XREF
5. Have you used profiler? Yes
A performance profiler is a common and useful tool for a software developer. In brief, a profiler provides a "profile" of a particular execution. A profiler generally provides timing information and call-tree information; with that, an engineer can analyze where their program is spending most of its time and what part of the application is calling what other part of the application.
6. Do you have Appserver experience... project
7. What is handle? What are the Types of handle?
Handles are pointers to Progress objects. You generally define variables or fields to hold handle values with the HANDLE, WIDGET-HANDLE, or COM-HANDLE data type. Note that HANDLE and WIDGET-HANDLE have a weak type relationship; that is, one can be assigned directly to the other. The COM-HANDLE data type provides ActiveX support. Progress supports following types of handle, depending on the object referenced:
· Widget
· Procedure
· Query, buffer, and buffer-field
· Server
· Component
· Transaction
· System
Widget Handles
Progress assigns every static or dynamic widget a handle value once it is created. This handle serves a different purpose, depending on whether the widget is static or dynamic:
For a static widget, the handle provides a unique reference to the widget besides the widget name. The widget name, by itself, can be ambiguous if the widget is specified in more than one container widget. Progress resolves this ambiguity differently depending on the widget. However, the handle to a widget is always unambiguous.
For a dynamic widget, it provides the only means to reference and manage the widget that you create.
You generally store widget handle values in variables or fields defined with the WIDGET-HANDLE data type
Procedure Handles
Every external procedure that is in scope within an application has a handle that identifies the context of the procedure. Using a valid procedure handle, you can execute the internal procedures and procedure triggers of the specified external procedure from any other procedure in your application. This capability is especially useful with persistent procedures. Thus, you can encapsulate related functionality and make it available to your entire application.
You generally store procedure handle values in variables or fields defined with the HANDLE data type.
Query, Buffer, and Buffer-field Handles
Query, buffer, and buffer-field object handles let you manipulate static and dynamic versions of these objects.
Server Handles
A server handle references the connection that you create to a Progress AppServer using the CREATE SERVER statement. You generally store server handle values in variables or fields defined with the HANDLE data type.
Component Handles
A component handle references a COM object (ActiveX Automation object or ActiveX control). Unlike all other handles, you store component handle values in variables defined with the COM-HANDLE data type.
Transaction Handles
A transaction object handle provides access to the current transaction object.
System Handles
Progress maintains several global handles that describe the current context of an application. Some system handles reference the widget handle of a context-determined user-interface widget. Others reference data and facilities available for and about the current session. Table 16-1 lists the Progress system handles.
8. What is the difference between for first and find first?
a) FOR uses multiple indexes, FIND uses single index, so for is more efficient.
b) FOR don’t require NO-ERROR, FIND requires NO-ERROR.
c) FOR can specify the fields to be included/excluded using FIELDS phrase, FIND does not
d) FOR provides a weak block scope, where FIND is scoped in side containing procedure, block.
9. What is difference between can-find and find statement?
a) CAN-FIND is more efficient than FIND because CAN-FIND only looks at the index (usually 1 I/O operation) where FIND retrieves the entire record (minimum of 2 I/Os).
b) CAN-FIND can’t make the record available to record buffer while find statement make record
available to the record buffer.
10. What are the different types of locks used in Progress?
Lock types and then describe. What are different types of locks? Explain.
You've just seen how you can apply a lock on your own. But if you do not apply any locks, Progress performs default locking. In particular:
à Whenever it reads a record, Progress puts a SHARE-LOCK on that record. (An exception is the browse widget. This means that other users can read the record but cannot update it until the procedure releases the SHARE-LOCK. If you try to read a record with a SHARE-LOCK when another user has that record EXCLUSIVE-LOCKed, Progress displays a message that the record is in use and you must wait to access it.
à Whenever Progress updates a record; it puts an EXCLUSIVE-LOCK on that record. This means that other users cannot read or update that record until the procedure releases EXCLUSIVE-LOCK. If you try to read a record with an EXCLUSIVE-LOCK, when another user has that record SHARE-LOCKed or EXCLUSIVE-LOCKed, you receive a message that the record is in use and you must wait to access it.
NOTE: SHARE-LOCKs and EXCLUSIVE-LOCKs use up entries in the lock table. The possible number of entries in the lock table defaults to 500. You can change this with the Lock Table Entries (-L) startup parameter. Progress stops a user program if it attempts to access a record that overflows the lock table.
11. What is self-join in progress? What is the syntax for self join?
A self-join is a query in which a table is joined (compared) to itself. Self-joins are used to compare values in a column with other values in the same column in the same table.
12. What is the use of buffer-copy command?
This method copies any common fields, determined by name, data type, and extent-matching, from the source buffer to the receiving buffer. If there are fields in one buffer that do not exist in the other, they are ignored. This method is used to accommodate temp-tables of joins.
Return type: LOGICAL
Applies to: Buffer object handle
Syntax BUFFER-COPY( source-buffer-handle
[ , except-list [ , pairs-list [ , no-lobs ] ] ] )
source-buffer-handle
An expression that evaluates to the source buffer handle.
except-list
A character expression that evaluates to a comma-separated list of field names to be excluded from the copy.
pairs-list
A character expression that evaluates to a comma-separated list of field-name pairs to be copied.
You can also specify an array element as one or both of the fields. This lets you copy a field or array element from one buffer to a field or array element in the other buffer, when the two fields do not have the same name. The order within each field-name pair does not matter; each pair must contain one field name from the source and one field name from the target.
You can also copy one entire array to another by specifying its name without a subscript.
no-lobs
A logical expression indicating whether to ignore BLOB and CLOB fields in the copy. If TRUE, BLOB and CLOB fields are ignored during the copy. If FALSE, BLOB and CLOB fields are copied along with the other fields. The default value is FALSE (that is, BLOB and CLOB fields are included in the copy).
The following example fragment copies the customer table to the buffer, bh, except that customer.sales-rep is copied to a field called cust-sales-rep in the buffer:
bh:BUFFER-COPY(buffer customer:handle,?,"cust-sales-rep,sales-rep").
13. What is lookup function?
Returns an integer giving the position of an expression in a list.
Returns a 0 if the expression is not in the list.
Syntax
LOOKUP (expression, list [, character])
14. Use of field-lists in progress.
The field-list specifies a list of fields to include or exclude when you open the query. This is the syntax for field-list:
FIELDS [ ( [ field ... ] ) ]| EXCEPT [ ( [ field ... ] ) ]
15. What are different types of blocks in Progress?
16. What is Record-Bleeding?
A record may be found without acquiring any lock simply by adding the no-lock option to any statement that retrieves a record (e.g., find, for each, get, open query, etc.). In theory, it is impossible to change a record that has been found with no-lock status. In practice, there
are times when, in the presence of multiple buffers for the same record, an assignment can be made. This phenomenon is known as a bleeding lock (see Knowledge Base # 13881 for more information). An existing record can always be found with a no-lock, even if someone
else has the same record with a share- or exclusive-lock.
17. How do you read and load the 1000 records from a flat file into the database?
How can you control the size of transaction?
INPUT FROM datafile. /* Example of Reducing Transactions */
REPEAT TRANSACTION:
REPEAT vCounter = 1 TO 1000:
CREATE Customer.
IMPORT Customer.
END.
END.
18. How do you find out, which index your query are using? XREF
19. What kind of coding did you do in projects involving the AppServer? Did you do both client
and server-side programming?
20. Was any specific development methodology (SDLC) followed in projects worked on?
Waterfall model
21. Dynamic queries along with the syntax. Advantages and disadvantages of dynamic queries.
DEFINE VARIABLE qh AS WIDGET-HANDLE.
DEFINE VARIABLE numvar AS INTEGER INITIAL 10.
CREATE QUERY qh.
qh:SET-BUFFERS(BUFFER customer:HANDLE).
qh:QUERY-PREPARE("FOR EACH customer WHERE cust-num < " + string(numvar)).
qh:QUERY-OPEN.
REPEAT WITH FRAME y:
qh:GET-NEXT().
IF qh:QUERY-OFF-END THEN LEAVE.
DISPLAY cust-num
name FORMAT "x(30)"
city FORMAT "X(20)"
END.
qh:QUERY-CLOSE()
DELETE OBJECT qh.
22. Have you done Appserver configuration? Mention some of the settings that we maintain when
configuring the Appserver.
23. What according to you are the three most important considerations that a developer should
make while writing the code?
24. Have you worked on developing reports using Progress 4GL? Have you ever used any reporting tools?
25. How do you debug your code? Do you use debugging tools? Are you familiar with Pro*spy?
1) HELP Button: -debugalert or session:debug-alert = yes.
2) Enable 4GL debugging:
proenv>prodebugenable
Usage: proDebugEnable { -disable-all | -enable-all }
-disable-all : disable environment for debugging
-enable-all : enable environment for debugging
proenv>prodebugenable -enable-all
OpenEdge Release 10.1A as of Wed Dec 21 03:20:56 EST 2005
Debugging is enabled for the Progress 4GL installed in
3) Debug using Compiler Directives [pre-processors]
26. How can we optimize a query?
27. How can we know where a transaction is being started in our program?
Using LISTING option with compile.
28. What all Version control tools you have used? CVS, PVCS
29. How can we know which index(s) will be used for a query in our code? Answer is XREF option.
30. If progress is not able to find any specific index(s) for a query and will perform a sequential
search over the entire table, then how can we know this from XREF option?
Answer is that WHOLE-INDEX will appear in the file generated by XREF.
31. How will you make Unit test cases? How does Unit Testing fit into the Software Development Life Cycle?
How can you coordinate with QA and testers? Idea of Test Proofs.
This is the first and the most important level of testing. As soon as the programmer develops a unit of code the unit is tested for various scenarios. As the application is built it is much more economical to find and eliminate the bugs early on. Hence Unit Testing is the most important of all the testing levels. As the software project progresses ahead it becomes more and more costly to find and fix the bugs.
In most cases it is the developer’s responsibility to deliver Unit Tested Code.
Unit Testing Tasks and Steps:
Step 1: Create a Test Plan
Step 2: Create Test Cases and Test Data
Step 3: If applicable create scripts to run test cases
Step 4: Once the code is ready execute the test cases
Step 5: Fix the bugs if any and re test the code
Step 6: Repeat the test cycle until the “unit” is free of all bugs
What is a Unit Test Plan? This document describes the Test Plan in other words how the tests will be carried out.
This will typically include the list of things to be Tested, Roles and Responsibilities, prerequisites to begin Testing, Test Environment, Assumptions, what to do after a test is successfully carried out, what to do if test fails, Glossary and so on
What is a Test Case? Simply put, a Test Case describes exactly how the test should be carried out.
For example the test case may describe a test as follows:
Step 1: Type 10 characters in the Name Field
Step 2: Click on Submit
Test Cases clubbed together form a Test Suite
Test Case Sample Test Case ID
Test Case Description
Input Data
Expected Result
Actual Result
Pass/Fail
Remarks
Additionally the following information may also be captured:
a) Unit Name and Version Being tested
b) Tested By
c) Date
d) Test Iteration (One or more iterations of unit testing may be performed)
Steps to Effective Unit Testing:
1) Documentation: Early on document all the Test Cases needed to test your code. A lot of times this task is not given due importance. Document the Test Cases, actual Results when executing the Test Cases, Response Time of the code for each test case. There are several important advantages if the test cases and the actual execution of test cases are well documented.
a. Documenting Test Cases prevents oversight.
b. Documentation clearly indicates the quality of test cases
c. If the code needs to be retested we can be sure that we did not miss anything
d. It provides a level of transparency of what was really tested during unit testing. This is one of the most important aspects.
e. It helps in knowledge transfer in case of employee attrition
f. Sometimes Unit Test Cases can be used to develop test cases for other levels of testing
2) What should be tested when Unit Testing: A lot depends on the type of program or unit that is being created. It could be a screen or a component or a web service. Broadly the following aspects should be considered:
a. For a UI screen include test cases to verify all the screen elements that need to appear on the screens
b. For a UI screen include Test cases to verify the spelling/font/size of all the “labels” or text that appears on the screen
c. Create Test Cases such that every line of code in the unit is tested at least once in a test cycle
d. Create Test Cases such that every condition in case of “conditional statements” is tested once
e. Create Test Cases to test the minimum/maximum range of data that can be entered. For example what is the maximum “amount” that can be entered or the max length of string that can be entered or passed in as a parameter
f. Create Test Cases to verify how various errors are handled
g. Create Test Cases to verify if all the validations are being performed
3) Automate where Necessary: Time pressures/Pressure to get the job done may result in developers cutting corners in unit testing. Sometimes it helps to write scripts, which automate a part of unit testing. This may help ensure that the necessary tests were done and may result in saving time required to perform the tests.
Summary:
“Unit Testing” is the first level of testing and the most important one. Detecting and fixing bugs early on in the Software Lifecycle helps reduce costly fixes later on. An Effective Unit Testing Process can and should be developed to increase the Software Reliability and credibility of the developer. The Above article explains how Unit Testing should be done and the important points that should be considered when doing Unit Testing.
Many new developers take the unit testing tasks lightly and realize the importance of Unit Testing further down the road if they are still part of the project. This article serves as a starting point for laying out an effective (Unit) Testing Strategy.
32. Have used VSTs(Virtual System Tables) for performance tuning? What do you know about VST and promon utility?
Virtual System Tables (VST's) were added in V8.2. VST's provide access to data that was previously only accessible through the promon utility.
For example, following information could be accessed using PROMON/VSTs:
1. User Control
2. Locking and Waiting Statistics
3. Block Access
4. Record Locking Table
5. Activity
6. Shared Resources
7. Database Status
8. Shut Down Database
The Progress documentation gives a basic description of each Virtual System Table (VST) but is generally inadequate for anyone attempting to do so serious work with VST's.
Virtual system tables give 4GL and SQL-92 applications access to the same database information that you collect with the PROMON (Progress monitor) utility. Virtual system tables (VSTs) enable an application to examine the status of a database and monitor its performance. With the database server running, 4GL and SQL-92 applications can call a VST and retrieve the specified information as run-time data.
Update Access to Virtual System Tables
Progress provides the empty, demo, and sports2000 databases with the virtual system table schemas already loaded. As new virtual system tables are made available, you can update the schemas in a database. To update the schemas, run the following PROUTIL command before you start the database server:
proutil db-name -C updatevst db-name
Specifies the database you are using.
33. What is the disadvantage of having smaller transactions size? Performance overhead
34. What is the efficient ways of coding to handle record locking, duration for which locks are
retained?
35. What is deadly embrace/deadlock?
Transaction is unit of work done. So a database management system will have number of transactions. There may be situations when two or more transactions are put into wait state simultaneously .In this position each would be waiting for the other transaction to get released.
Suppose we have two transactions one and two both executing simultaneously. In transaction numbered one we update student table and then update course table. We have transaction two in which we update course table and then update student table.
We know that when a table is updated it is locked and prevented from access from other transactions from updating. So in transaction one student table is updated it is locked and in transaction two course table is updated and it is locked.
We have given already that both transactions gets executed simultaneously. So both student table and course table gets locked so each one waits for the other to get released. This is the concept of deadlock in DBMS.
36. What is the default behavior for the following conditions –
ERROR (specially inside a trigger block)
ENDKEY
END-ERROR
STOP
QUIT
37. Which utilities can you use in order to determine the following:-
Transaction ------- LISTING
Index Usage ------- XREF
Record Scope ------ LISTING
38. OERA architecture
Answer: Reference architecture is a more general term than application architecture. It can be described as a master plan that application architects consult for the development of any number of applications (whereas, an application architecture usually refers to a description of a single application).
In the OpenEdge context, the OpenEdge Reference Architecture (RA) does not define specific software components, but defines the general functional categories of components that comprise an application. It can be used as a high-level blueprint for developing OpenEdge service-oriented business applications.
Benefits of OpenEdge RA: The OpenEdge RA is particularly useful because it:
àDivides the application into functional layers that separate data access logic, business
logic, and user interface logic. This facilitates customization, the development of new or improved features, and code reuse.
In addition, the layered approach supports the deployment of multiple user interfaces. Logic can be exposed to other applications for integration purposes in any of a number of ways, including the use of cross-platform technologies like Web Services, which are supported in the OpenEdge platform
àIs not only a model for new application development, but serves as a model for
transforming existing applications to a modern application architecture.
Using the OpenEdge RA as a model for analyzing a legacy application, you can categorize
the functionality of your application into business entity, data access, user interface, and
integration components.
After you define the relationships between the application’s components, you have, in
effect, created the functional design for your application that can be used as a guide for
further implementation and development.
à Is supported by OpenEdge tools and technologies.
à Is a guide to best practices for using OpenEdge tools and technologies.
à Allows for technology independence.
If, for example, you have a requirement to create user interface logic with JavaScript, you
can use business logic that was implemented with the Progress® 4GL.
Logic can be exposed to other applications for integration purposes in any of a number of
ways, including the use of cross-platform technologies like Web Services, which are
supported in the OpenEdge platform.
39. Locks types and then describe and Record scoping, weak scoped and strong scoped
records/blocks? Which blocks can start Transaction?
What is record scoping? How many types of records scoping blocks are there in Progress?
How is record scoping relating to transactions / duration for which locks are retained?
Transactions ===========
A transaction is a set of changes to the database, which should be done completely or not at all. A transaction can be as small as updating or adding a single order with the debits and credits or as large as
increasing the prices of all items in an inventory by 10%. What is common between these two examples is that if not finished completely there could be a loss of data integrity.
With PROGRESS if an error occurs while processing a transaction, the transaction is backed out. This means that every record that was changed during the transaction is restored to the value it contained
before the transaction started. In PROGRESS a transaction is one iteration of the outermost FOR EACH,
REPEAT, or procedure block that contains direct updates to the database.
The following will start a transaction:
à Any block using the TRANSACTION keyword on the block statement (DO, FOR EACH, or REPEAT).
à A procedure and each iteration of a DO ON ERROR, FOR EACH, or REPEAT block that directly
updates the database or directly reads records with an EXCLUSIVE-LOCK.
Note:
i) Directly updating the database means that the block contains at least one statement that can change the database, CREATE DELETE, and UPDATE are examples.
ii) DO blocks do not by default have transaction properties.
iii) An important thing to remember when determining the size of a transaction is that if a transaction is active when a procedure (a program started with the run statement) is called, the scope of the transaction is defined by the calling program.
iv) Transactions can start by default or they can be explicitly with the TRANSACTION keyword.
v) By using the TRANSACTION keyword it is possible to control the size of a transaction, to make it smaller or bigger to meet the demands of the application.
Record Scope ============
When a FIND or a FOR EACH statement reads a record, it places that record in an area of memory called the record buffer. The record is available in the buffer during the scope of the record, which is the
duration of that block.
By default, the scope of a record is the outermost FOR EACH, REPEAT, Or procedure block that references the record. Use the COMPILE statement with the LISTING option to see where your record buffers are scoped.
PROGRESS automatically scopes records to REPEAT, FOR EACH, or procedure blocks. You can scope a record explicitly to REPEAT, and DO blocks using the FOR keyword.
Record scope affects several things:
à At the end of a record's scope, if it has been modified it is written out to the database.
à At the end of the record scope PROGRESS releases the record and any locks that were placed on it,
so long as it is not involved in an active transaction.
à At the end of the record scope validation is performed against unique indexes and mandatory fields.
Record Locking ==============
By default whenever PROGRESS reads a record it is read with a SHARE-LOCK. This means that other users may read the record but may not update it until the SHARE-LOCK is released. If you try to update a
record that is SHARE-LOCKed you receive a message that it is in use.
By default when a record is updated PROGRESS puts an EXCLUSIVE-LOCK on the record. Other users cannot read or update the record until the EXCLUSIVE-LOCK is removed. When you try to EXCLUSIVE-LOCK a record that currently has a SHARE-LOCK or an EXCLUSIVE-LOCK you will get a message that the record is in use.
You may override the default record locking by specifying NO-LOCK or EXCLUSIVE-LOCK when reading the record.
The duration of a lock depends on the type of lock and when it was acquired.
A SHARE-LOCK acquired during a transaction is held until the end of the transaction or the record release whichever happens later. A SHARE-LOCK acquired outside a transaction is held until the record
release. A SHARE-LOCK acquired outside a transaction but held into a transaction is held until the later of the end of the transaction or the record release.
An EXCLUSIVE-LOCK is only acquired during a transaction, and is held until the end of the transaction. It is then converted to a SHARE-LOCK if the record scope is larger than the transaction and the record is
still active in a buffer.
Notice that when an EXCLUSIVE-LOCK is downgraded it is to a SHARE-LOCK even if the record was first read with a NO-LOCK. This is because when the NO-LOCK is upgraded to a EXCLUSIVE-LOCK it must be reread from the database before the lock is applied. If you want to override the SHARE-LOCK in the case where the transaction has ended but the record scope has not, use the RELEASE statement to release the record from the record buffer.
Record release occurs at the end of the record scope, or when a RELEASE statement is executed.
PROGRESS uses a lock table in shared memory to manage record locks. In version 5 of PROGRESS whenever a record is read, an entry is made in the lock table. This includes records read EXCLUSIVE-LOCK, SHARE-LOCK, and NO-LOCK. In PROGRESS version 6 no entries are made for records read NO-LOCK. The size of the lock table defaults to 500 entries and can be adjusted by using the -L parameter when starting the server.
40. Database design rules like how will you add a table in a db.
41. Indexes and their effect.
The Progress RDBMS uses indexes to rapidly locate a specific row or a group of rows in a table. When a query is executed, one or more indexes will be selected to be used to retrieve the requested data.
Understanding index selection is very important in the design of a database system. Improper use of indexes may cause a significant bottleneck in the performance of a system. It could lead to
performance degradation for the process using the improper index, and can also affect the performance of the entire system.
Advantages/Purpose:
à Fast access and retrieval of a specific row or set of rows.
à To retrieve rows in specific order.
à To enforce uniqueness of column values.
à To allow fast location of rows that contains a specific word or phrase.
Diadvantages/Cost of Adding an Index:
Although indexes usually provide performance gains in the retrieval of a specific row or set of rows, there is a cost in adding indexes to a
table:
à Slower create and delete operations on rows. This is because index entries will be added or deleted when rows are added or deleted. The more indexes you have, the more index entries will have to be added or deleted.
à Slower updates of index columns. This is because the index entries must be updated whenever a column that is a component of an index is updated with a new value.
à Additional storage space. This is because the index entries will occupy additional disk space.
à Additional administration and maintenance. This is because the increase in number of indexes will increase the time to rebuild indexes. In addition, the increase in size of the database will result in more time to manage the functions such as backup and restore.
Design Considerations:
As there are advantages and costs involved in adding indexes, therefore it is very important to understand the need for indexes and avoid unnecessary or redundant indexes.
It is also a good idea to review the components of each index during design time along with the type of queries that will be performed on the table.
This can help in reducing the number of indexes needed by organizing them to take advantage of multiple index selection. The following should be considered when evaluating the need for an index:
a) How many rows are in the table?
b) How often the rows will accessed using this index?
c) How many rows will be accessed using this index?
d) Are there existing indexes, which could be used instead?
e) Is the row access required during on-line transaction processing or is it required for nightly batch runs?
f) If it required for nightly batch runs, is the index really required?
Maintenance Considerations:
à Use PROUTIL's IDXANALYS qualifier to get information about index blocks and utilization.
à To execute the IDXANALYS qualifier, enter the following command:
proutil db-name -C idxanalys
The IDXANALYS qualifier provides:
-- The number of fields and levels in each index.
-- The size of each index, in blocks and in bytes.
-- The percent utilization within the index (that is, the degree of disk space efficiency).
-- A factor value that indicates whether to rebuild each index.
-- A summary of indexes for the current database and the percentage of total index space used by
each index.
NOTE: You can run PROUTIL with the IDXANALYS qualifier while the database is in use; however, Progress generates only approximate information.
The most important field in the IXANALYS display is the % Util field. This field shows the degree of consolidation of each index. If an index is several hundred blocks, and your application most frequently retrieves data, an index utilization of 85 percent or higher is optimal.
There are two ways to increase an index's utilization rate:
-- Compress the index with the database online or offline with the PROUTIL IDXCOMPACT utility.
-- Rebuild and compress the index offline with the PROUTIL IDXBUILD utility.
The Levels field shows the number of reads Progress performs in each index per entry. The Blocks and Bytes fields show you the size of each index.
The Factor field is based on the utilization and size of the index; it is an indicator of when you should rebuild indexes. Table 12-3 provides a description of the different ranges of values for the Factor field.
When you use the factor field to decide whether to rebuild an index, consider the context of how the particular index is used. For example, if an index is highly active, with continuous insertions and deletions, its utilization rate varies greatly, and a rebuild is inadvisable. However, a static index with a high factor value benefits from a rebuild..
42. What all Version control tools you have used? CVS, PVCS
43. How can we know which index(s) will be used for a query in our code? Answer is XREF option.
44. If progress is not able to find any specific index(s) for a query and will perform a sequential
search over the entire table, then how can we know this from XREF option?
Answer is that WHOLE-INDEX will appear in the file generated by XREF.
45. SDLC?
- Planning – establishing the plans for creating an information system by
- Defining the system to be developed – based on the systems prioritized according to the organization’s critical success factor (CSF), a system must be identified and chosen
- Defining the project scope – a high level of system requirements must be defined and put into a project scope document
- Developing the project plan - – all details from tasks to be completed, who completed them and when they were completed must be formalized
- Managing and monitoring the project plan – this allows the organization to stay on track, creating project milestones and feature creeps which allow you to add to the initial plan
- Analysis – the users and IT specialists collaborate to collect, comprehend, and logistically formalize business requirements by
- Gathering the business requirements – IT specialists and knowledge workers collaborate in a joint application design (JAD) and discuss which tasks to undertake to make the system most successful
- Analyzing the requirements – business requirements are prioritized and put in a requirements definition document where the knowledge worker will approve and place their signatures
- Design – this is where the technical blueprint of the system is created by
- Designing the technical architecture – choosing amongst the architectural designs of telecommunications, hardware and software that will best suit the organization’s system and future needs
- Designing the systems model – graphically creating a model from graphical user interface (GUI), GUI screen design, and databases, to placement of objects on screen
- Write the test conditions - Work with the end users to develop the test scripts according to the system requirements
- Development – executing the design into a physical system by
- Building the technical architecture – purchasing the material needed to build the system
- Building the database and programs – the IT specialists write programs which will be used on the system
- Testing – testing the developed system
- Test the system using the established test scripts – test conditions are conducted by comparing expected outcomes to actual outcomes. If these differ, a bug is generated and a backtrack to the development stage must occur.
- Deployment – the systems are placed and used in the actual workforce and
- The user guide is created
- Training is provided to the users of the system - usually through workshops or online
- Maintenance – keeping the system up to date with the changes in the organization and ensuring it meets the goals of the organization by
- Building a help desk to support the system users – having a team available to aid technical difficulties and answer questions
- Implementing changes to the system when necessary.
The HIDDEN and VISIBLE attributes are not simple opposites of each other.
You will want to set the HIDDEN attribute to selectively show different aspects of your interface. In some cases, you may want to hide some fields from some users. In other cases you may want to
hide a screen while you programmatically manipulate its contents.
The reason that HIDDEN should be used is that VISIBLE has side effects. VISIBLE was added to the PROGRESS 4GL in Version 7 to parallel the behavior of the keyword VIEW.
Both VIEW and VISIBLE, when applied to an object, implicitly make other objects visible. If you view a button, the frame that contains it and the window that contains the frame are also made visible. The following code sample shows this behavior when run from the Procedure Editor.
DEFINE BUTTON b LABEL "Hello, World".
DEFINE FRAME f
b AT ROW 1 COLUMN 1 WITH NO-LABELS.
ASSIGN b:VISIBLE = YES.
Running the above program will make the "Hello, World" button visible. But because the button won't actually be seen until the parent frame is made visible, PROGRESS will do that too. Compare this to the following program. If you run this program you should not be able to see either the frame or the button.
DEFINE BUTTON b LABEL "Hello, World".
DEFINE FRAME f
b AT ROW 1 COLUMN 1 WITH NO-LABELS.
ASSIGN b:HIDDEN = NO.
Even though the button is not HIDDEN, the user never sees it because its container has not been explicitly viewed.
When you are setting up the contents of a frame, you want to control the timing of when that frame is made visible to your users. You do not want the frame to appear before it is ready to be seen. If you
use the VISIBLE attribute on objects in the frame, there is a chance that the frame will appear before all your setup code has executed.
Because of these reasons, it is always safer to set the HIDDEN attribute.
47. Persistent procedures, how and when are they used?
Persistent procedures, how and why are they used? How to get the handle to a persistent
proc when it is or isn't running already. What is persistent procedure?
Is it mandatory to keep the persistent procedures alive thorough out the progress session?
Advantages of persistent procedures. What is the difference between persistent and
non-persistent procedures.
A non-persistent procedure creates and maintains its context only until it returns from execution.
The context of a non-persistent procedure remains in scope only until the RUN statement that
executes it completes.
A persistent procedure creates its context when it executes and then maintains that context after it returns until the end of the Progress session, or until it is explicitly deleted. The context of a persistent procedure remains in scope after the RUN statement that executes it completes until you remove it. As long as its context is in scope, the triggers and internal procedures of a persistent procedure remain available for execution by your application.
NOTE: If you run an application that creates persistent procedures from an ADE tool, that tool (for
example, the Procedure Editor or User Interface Builder) removes all instances of persistent
procedures, still created when the application terminates.
Advantages of Persistent Procedures:
a) Persistent procedures promote modular application design and development by more easily allowing you to distribute functionality among several procedures.
For example,
à You might build a persistent procedure that provides access to a database through a set of local buffers that it otherwise hides from the rest of the application or
à Your persistent procedure might create and manage its own windows while allowing independent access (non-modal access) to other windows in your application.
b) The additional modularity also helps to avoid hitting r-code segment limits. Thus, creating a persistent procedure whose context you access through internal procedures provides the most effective means to achieve encapsulation in Progress.
c) You can also use a persistent procedure to create multiple versions of the same context. Each time you call a persistent procedure, it creates a separate instance of its context. Your application (and
user) can access and manage each context independently from the others.
Scan the session’s PERSISTENT procedures for "ProgramName.w". If "ProgramName.w" is running, run its "InternalProcedureName". Otherwise run "ProgramName.w" PERSISTENT and then run its
"InternalProcedureName":
DEFINE VARIABLE hProcedureHandle AS HANDLE NO-UNDO.
DEFINE VARIABLE cProgramName AS CHARACTER NO-UNDO.
ASSIGN
cProgramName = "ProgramName.w"
hProcedureHandle = SESSION:FIRST-PROCEDURE.
DO WHILE VALID-HANDLE(hProcedureHandle):
IF hProcedureHandle:FILE-NAME = cProgramName THEN LEAVE.
hProcedureHandle = hProcedureHandle:NEXT-SIBLING.
END.
IF VALID-HANDLE(hProcedureHandle) THEN
RUN InternalProcedureName IN hProcedureHandle.
ELSE DO:
RUN VALUE(cProgramName) PERSISTENT SET hProcedureHandle.
RUN InternalProcedureName IN hProcedureHandle.
END.
48. Diff b/w what is the difference between &global-define and &scope-define?
Every preprocessor name that is defined has a specific scope. The scope, of a preprocessor name, is the area within its compilation unit where it can be accessed, or referenced, the by the preprocessor &name.
The scope of a preprocessor name is determined by:
a) Whether it is defined within the compilation unit and
b) Whether it is defined with the &GLOBAL-DEFINE or &SCOPED-DEFINE directive.
The syntax of the &GLOBAL-DEFINE and &SCOPED-DEFINE directives are identical but these directives
are used differently:
&GLOBAL-DEFINE preprocessor-name definition
&SCOPE-DEFINE preprocessor-name definition
A preprocessor name defined with the &GLOBAL-DEFINE directive is globally defined; a preprocessor
name defined with the &SCOPED-DEFINE directive is non-globally defined.
49. What is new in OE 10 over progress 9.x?
a. New Data types - BLOB, DATETIME, DATETIME-TZ, CLOB
b. The "Generated by WebSpeed" comment has been moved to the end of the web page because it creates problems using standards compliance with IE web-browser. Internet Explorer ignores the DOCTYPE tag if it's not the first in the page, such where the "Generated by Webspeed" comment used to be. Problems may arise if there are programs relying on the comment being the first line. The following can be undertaken to revert the output to the same as in the past.
• Specify something else than "text/html" for content-type to not avoid the generated comment in the end of the output.
• Manually add the comment back-in as first line of the output.
c. ProDataSets and direct related XML support
d. Open Client [.NET, Java] support
e. Auditing feature
f. OpenEdge® Replication [Fathom]
50. Client side transaction/Server Side Transaction.
51. Have u used complier directives to debug application?
52. What would be your plan of action when you are stuck with a problem?
UNDERSTANDING THE PROBLEM
à What are you trying to find or do?
à What are the unknowns?
à What information do you obtain from the problem?
à What information, if any, is missing or not needed?
DEVISING A PLAN
The following list of strategies, although not exhaustive, is very useful.
à Look for a pattern.
à Examine related problems, and determine if the same technique can be applied.
à Examine a simpler or special case of the problem to gain insight into the solution of the
original problem.
à Make a table.
à Make a diagram.
à Write an equation.
à Use guess and check.
CARRYING OUT THE PLAN
à Implement the strategy or strategies in step 2, and perform any necessary actions or
computations.
à Check each step of the plan as you proceed. This may be intuitive checking or a formal proof
of each step.
à Keep an accurate record of your work.
COMPARE
à Compare the results with the original problem.
53. What kind of editors you use to write the progress Application code?
54. What would you do to optimize the code in terms of time, memory and effort?
55. Which transaction you will prefer, batch transaction or one record at a time?
56. A program abc.p is called by many files. How could you find out what other files are calling this program?
57. Include files; what are the uses of these?
58. Publish and Subscribe.
PUBLISH Statement Causes a Progress named event to occur.
NOTE: Progress named events are completely different from the key function, mouse, widget, and direct manipulation events described in the "Events Reference" chapter of this manual.
SYNTAX:
PUBLISH event-name
[ FROM publisher-handle ]
[ ( parameter [ , parameter ] ... ) ]
event-name : A quoted character string or character expression representing the name of a named
event. If you use a quoted character string, Progress adds event-name to the PUBLISHED-EVENTS
attribute's list of events.
FROM publisher-handle: A procedure or widget handle representing the procedure or widget to which
Progress attributes the named event. The FROM option lets a procedure publish an event on behalf of
Another procedure or widget.
For example, if you want procedure A to publish a named event on behalf of procedure B, set publisher-
handle to the procedure handle of B.
If the FROM option does not appear, Progress attributes the event to THIS-PROCEDURE, the procedure
that contains the PUBLISH statement.
NOTE: If the FROM option does not appear and the PUBLISH statement occurs in a non-persistent procedure that does not publicize its handle, potential subscribers have no way of knowing the handle's value, and can subscribe to the event only by using the SUBSCRIBE statement's ANYWHERE option.
( parameter [ , parameter ] ... ) The parameters, if any, of the named event. As in the RUN statement,
you must supply a value for each INPUT and INPUT-OUTPUT parameter and a variable for each
OUTPUT parameter.
Also, if a named event has one or more parameters, the PUBLISH statement and each subscriber's local internal procedure (which the SUBSCRIBE statement names and which Progress runs when the named event occurs) must specify identical signatures-where signature means the number of parameters and the data type and mode (INPUT, etc.) for each.
NOTE: When the named event occurs and Progress runs each subscriber's local internal procedure, if the signature of a local internal procedure does not match the signature in the PUBLISH statement; Progress reports a run time error. Since the PUBLISH statement runs with an implicit NO-ERROR, errors are stored in the ERROR-STATUS handle.
The parameter syntax is identical to that of the RUN statement. For its specification, see the RUN
Statement reference entry.
EXAMPLE
The following example consists of four procedure files: a driver, a publisher, and two subscribers. The
driver, r-nedrvr.p, runs the publisher and the two subscribers persistently, then subscribes to the event
NewCustomer on behalf of the second subscriber.
r-nedrivr.p
/* r-nedrvr.p */
DEFINE VARIABLE hPub AS HANDLE.
DEFINE VARIABLE hSub1 AS HANDLE.
DEFINE VARIABLE hSub2 AS HANDLE.
DEFINE BUTTON bNewCust LABEL "New Customer".
DEFINE BUTTON bQuit LABEL "Quit".
RUN r-nepub.p PERSISTENT set hPub.
RUN r-nesub1.p PERSISTENT set hSub1 (hPub).
RUN r-nesub2.p PERSISTENT set hSub2.
/* Subscribe to event NewCustomer on behalf of subscriber 2 */
SUBSCRIBE PROCEDURE hSub2 TO "NewCustomer" IN hPub.
FORM bNewCust bQuit WITH FRAME x.
ENABLE ALL WITH FRAME x.
ON CHOOSE OF bNewCust RUN NewCust in hPub.
WAIT-FOR CHOOSE OF bQuit OR WINDOW-CLOSE OF CURRENT-WINDOW.
The publisher, r-nepub.p, publishes the event NewCustomer.
r-nepub.p
/* r-nepub.p */
PROCEDURE NewCust:
DEFINE VARIABLE name AS CHARACTER INITIAL "Sam".
/* Let subscriber know new customer */
PUBLISH "NewCustomer" (INPUT name).
END PROCEDURE.
The first subscriber, nesub1.p, subscribes to the event NewCustomer.
r-nesub1.p
/* r-nesub1.p */
DEFINE INPUT PARAMETER hPub AS HANDLE.
SUBSCRIBE TO "NewCustomer" IN hPub.
PROCEDURE NewCustomer:
DEFINE INPUT PARAMETER name AS CHAR.
MESSAGE "Subscriber 1 received event NewCustomer concerning" name
VIEW-AS ALERT-BOX.
END.
The second subscriber, nesub2.p, already subscribed to the event NewCustomer, cancels all
subscriptions.
r-nesub2.p
/* r-nesub2.p */
PROCEDURE NewCustomer:
DEFINE INPUT PARAMETER name AS CHAR.
MESSAGE "Subscriber 2 received event NewCustomer concerning" name
VIEW-AS ALERT-BOX.
/* This subscriber receives the first event, then removes itself */
UNSUBSCRIBE TO ALL.
END.
To start the example, run the driver, r-nedrvr.p.
NOTES
à If a named event has multiple subscribers, the order in which Progress notifies subscribers is
undefined.
à INPUT-OUTPUT parameters can accumulate values from a set of subscribers. When a subscriber
receives an INPUT-UTPUT parameter, it has the value that the previous subscriber set it to.
When the publisher receives an INPUT-OUTPUT parameter, it has the value that the last subscriber
set it to.
à If a named event with multiple subscribers has OUTPUT parameters, each time a subscriber sets an
OUTPUT parameter, Progress overwrites the previous value. For this reason, Progress Software
Corporation recommends that you use OUTPUT parameters with named events only when there is a
single subscriber.
à If a named event has multiple subscribers and several subscribers specify a RETURN statement with a
return value, the RETURN-VALUE function evaluates to the return value set by the last subscriber.
à Progress executes the PUBLISH statement with an implicit NO-ERROR option. To find out if any errors
occurred, and if so, which ones, use the ERROR-STATUS system handle.
à If publisher-handle is a widget handle, the value of SOURCE-PROCEDURE in each of the subscribers'
internal procedures will be the handle of the procedure that created the widget.
SUBSCRIBE Statement Creates a subscription to a Progress named event. NOTE: Progress named events are completely different from the key function, mouse, widget, and direct manipulation events described in the "Events Reference" chapter in this manual.
SYNTAX
SUBSCRIBE [ PROCEDURE subscriber-handle ]
[ TO ] event-name
{ IN publisher-handle | ANYWHERE }
[ RUN-PROCEDURE local-internal-procedure ]
[ NO-ERROR ]
PROCEDURE subscriber-handle A procedure or handle representing the subscriber.
The PROCEDURE option lets one procedure create a subscription on behalf of another. For example, if
you want procedure A to create a subscription on behalf of procedure B, set subscriber-handle to the
procedure handle of B.
If the PROCEDURE option does not appear, Progress creates a subscription on behalf of THIS-
PROCEDURE, the procedure that contains the SUBSCRIBE statement.
TO event-name A quoted string or a character expression representing the name of the event.
IN publisher-handle Subscribes to the named events published by publisher-handle.
If publisher-handle is not a valid procedure or widget handle at the time the SUBSCRIBE statement
executes, Progress reports a run time error unless you specify the NO-ERROR option.
ANYWHERE Subscribes to named events published within the Progress session-regardless of the publisher.
RUN-PROCEDURE local-internal-procedure A quoted string or character expression representing the
name of an internal procedure that resides within the subscribing program. Progress runs local-internal-
procedure when the named event occurs.
If the RUN-PROCEDURE option does not appear, when the named event occurs, Progress runs an
internal procedure with the same name as the named event.
NOTE: The RUN-PROCEDURE option lets you create a subscription when the event name and the procedure name do not match, or when you must subscribe to two different events that have the same name.
When the named event occurs, Progress RUNs each subscriber's local internal procedure, passing the parameters, if any, The order in which Progress notifies subscribers is undefined. Progress always performs this RUN with an implicit NO-ERROR, and logs errors to the ERROR-STATUS system handle.
NO-ERROR Tells Progress not to report a run time error if publisher-handle or subscriber-handle is not a valid
procedure handle, or if Progress cannot evaluate an event-name expression. Errors are still generated,
however, and are stored in the ERROR-STATUS handle.
EXAMPLE
For an example, see the reference entry for the PUBLISH Statement in this manual.
NOTES
à Within the local internal procedure, you can get a handle to the publisher of the named event by using
the SOURCE-PROCEDURE system handle.
à If Progress detects a redundant SUBSCRIBE statement¾that is, a SUBSCRIBE statement with the
same event name, and either the same publisher handle or the same ANYWHERE option¾Progress
does not report an error.
à If event-name is a string containing spaces or is otherwise not a standard Progress name, use one of
the following techniques:
à Use the RUN-PROCEDURE option to assign the local internal procedure a more conventional name.
à When you define local-internal-procedure, put its name in quotes, as in the following example:
PROCEDURE "spaced event":
PUBLISH and SUBSCRIBE with ADM2
The PUBLISH / SUBSCRIBE mechanism can be used within SmartObjects too.
The Progress ADM2 implements SmartLinks using the Progress 4GL PUBLISH
& SUBSCRIBE event mechanism.
SmartLinks are based on the PUBLISH / SUBSCRIBE mechanism and are
created and maintained by each SmartObject's container. Each link is
a property in each SmartObject that supports that type of link. The
smart.p super procedure has procedures and functions for link
management. Each link is mapped to one or more events that use the
PUBLISH and SUBSCRIBE statements. These event lists are also
SmartObject properties.
It is possible to dynamically add a SmartLink to any SmartObject with
a RUN addLink statement. For example:
RUN addLink (INPUT hSmartPanel, INPUT `Navigation':U, INPUT hdCust).
It is also possible to add your customized links to SmartObjects with
addLink; for example, using the addLink procedure to add a customized
SmartLink that is not recognized as one of the object's supported
links:
RUN addLink(h1, 'newLink', h2).
The addLink procedure now executes the following statement:
SUBSCRIBE PROCEDURE h2 TO 'newlink' IN h1.
Now it is necessary to create a procedure called 'newlink' on the
subscriber. The procedure h1 can now execute the PUBLISH statement
whenever it wants to invoke the named event in h2:
PUBLISH 'newlink'.
Using the PUBLISH / SUBSCRIBE mechanism with SmartObjects is only
recommended for cases in which it is not possible to use the
SmartLinks; for example, to communicate between a SmartObject and a
non-smart object such as a fill-in.
EXAMPLE:
Example of PUBLISH and SUBSCRIBE with a SmartWindow:
In the example below, SmartWindows show how to use the PUBLISH /
SUBSCRIBE mechanism with SmartObjects, although, to reduce the code,
no other SmartObject is used in the example.
In the main window, publisher.w, there is a normal browser in one
SmartWindow and a fill-in in the SmartWindow subscriber.w. This
fill-in merely displays the cust-num field of the selected row in the
browser.
In this case it is necessary to override the super procedure
InitalizeObject on the subscriber SmartWindow with the Fill-in, and
add the subscribe command after the RUN SUPER statement.
In the publisher.w window, the named event is being published in the
VALUE-CHANGED of the browse.
****PUBLISHER.W:
&Scoped-define WINDOW-NAME wWin
CREATE WIDGET-POOL.
/* ******************** Preprocessor Definitions ************** */
&Scoped-define PROCEDURE-TYPE SmartWindow
&Scoped-define DB-AWARE no
&Scoped-define ADM-CONTAINER WINDOW
&Scoped-define ADM-SUPPORTED-LINKS
Data-Target,Data-Source,Page-Target,Update-Source,Update-Target,Filter-target,Filter-Source
&Scoped-define FRAME-NAME fMain
&Scoped-define BROWSE-NAME BROWSE-1
&Scoped-define INTERNAL-TABLES Customer
&Scoped-define FIELDS-IN-QUERY-BROWSE-1 Customer.Cust-Num
Customer.Name Customer.City
&Scoped-define ENABLED-FIELDS-IN-QUERY-BROWSE-1
&Scoped-define OPEN-QUERY-BROWSE-1 OPEN QUERY BROWSE-1 FOR EACH
Customer NO-LOCK INDEXED-REPOSITION.
&Scoped-define TABLES-IN-QUERY-BROWSE-1 Customer
&Scoped-define FIRST-TABLE-IN-QUERY-BROWSE-1 Customer
&Scoped-define OPEN-BROWSERS-IN-QUERY-fMain
~{&OPEN-QUERY-BROWSE-1}
&Scoped-Define ENABLED-OBJECTS BROWSE-1 BUTTON-1 BtnDone
DEFINE VAR wWin AS WIDGET-HANDLE NO-UNDO.
DEFINE BUTTON BtnDone DEFAULT LABEL "&Done" SIZE 15 BY 1.14 BGCOLOR 8.
DEFINE BUTTON BUTTON-1 LABEL "Subscriber Window" SIZE 25 BY 1.19.
DEFINE QUERY BROWSE-1 FOR Customer SCROLLING.
DEFINE BROWSE BROWSE-1
QUERY BROWSE-1 NO-LOCK DISPLAY
Customer.Cust-Num FORMAT ">>>>9":U
Customer.Name FORMAT "x(20)":U
Customer.City FORMAT "x(12)":U WIDTH 9
WITH NO-ROW-MARKERS SEPARATORS SIZE 44 BY 7.14 EXPANDABLE.
/.* ************************ Frame Definitions ***************** */
DEFINE FRAME fMain
BROWSE-1 AT ROW 2.19 COL 7
BUTTON-1 AT ROW 10.05 COL 4
BtnDone AT ROW 10.05 COL 39
WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D
AT COL 1 ROW 1 SIZE 59.2 BY 12.1
DEFAULT-BUTTON BtnDone.
/* ************************* Create Window ******************** */
IF SESSION:DISPLAY-TYPE = "GUI":U THEN
CREATE WINDOW wWin ASSIGN
HIDDEN = YES
TITLE = "Prinicpal>"
HEIGHT = 12.1 WIDTH = 59.2
MAX-HEIGHT = 28.81 MAX-WIDTH = 146.2
VIRTUAL-HEIGHT = 28.81 VIRTUAL-WIDTH = 146.2
RESIZE = no SCROLL-BARS = no
STATUS-AREA = no BGCOLOR = ?
FGCOLOR = ? THREE-D = yes
MESSAGE-AREA = no SENSITIVE = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
/* ************************* Included-Libraries *************** */
{src/adm2/containr.i}
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN wWin:HIDDEN = yes.
ON END-ERROR OF wWin /* <Prinicpal> */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
IF THIS-PROCEDURE:PERSISTENT THEN RETURN NO-APPLY.
END.
ON WINDOW-CLOSE OF wWin /* <Prinicpal> */
DO:
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN NO-APPLY.
END.
ON VALUE-CHANGED OF BROWSE-1 IN FRAME fMain
DO:
PUBLISH "custom" ( customer.cust-num ).
END.
ON CHOOSE OF BtnDone IN FRAME fMain /* Done */
DO:
&IF "{&PROCEDURE-TYPE}" EQ "SmartPanel" &THEN
&IF "{&ADM-VERSION}" EQ "ADM1.1" &THEN
RUN dispatch IN THIS-PROCEDURE ('exit').
&ELSE
RUN exitObject.
&ENDIF
&ELSE
APPLY "CLOSE":U TO THIS-PROCEDURE.
&ENDIF
END.
ON CHOOSE OF BUTTON-1 IN FRAME fMain /* Open Subscriber Window */
DO:
RUN subscriber.w.
END.
/* *************************** Main Block ********************** */
/* Include custom Main Block code for SmartWindows. */
{src/adm2/windowmn.i}
/* ********************** Internal Procedures ****************** */
PROCEDURE adm-create-objects :
END PROCEDURE.
PROCEDURE disable_UI :
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN DELETE WIDGET wWin.
IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.
PROCEDURE enable_UI :
ENABLE BROWSE-1 BUTTON-1 BtnDone
WITH FRAME fMain IN WINDOW wWin.
{&OPEN-BROWSERS-IN-QUERY-fMain}
VIEW wWin.
END PROCEDURE.
PROCEDURE exitObject :
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN.
END PROCEDURE.
****SUBSCRIBER.W:
&Scoped-define WINDOW-NAME wWin
CREATE WIDGET-POOL.
/* ******************** Preprocessor Definitions ************* */
&Scoped-define PROCEDURE-TYPE SmartWindow
&Scoped-define DB-AWARE no
&Scoped-define ADM-CONTAINER WINDOW
&Scoped-define ADM-SUPPORTED-LINKS
Data-Target,Data-Source,Page-Target,Update-Source,Update-Target,Filter-target,Filter-Source
&Scoped-define FRAME-NAME fMain
&Scoped-Define ENABLED-OBJECTS BtnDone cust-num
&Scoped-Define DISPLAYED-OBJECTS cust-num
DEFINE VAR wWin AS WIDGET-HANDLE NO-UNDO.
DEFINE BUTTON BtnDone DEFAULT LABEL "&Done" SIZE 15 BY 1.14 BGCOLOR 8.
DEFINE VARIABLE cust-num AS CHARACTER FORMAT "X(15)":U LABEL "Cust-num
from publisher:"
VIEW-AS FILL-IN SIZE 14 BY 1 NO-UNDO.
/* ************************ Frame Definitions ****************** */
DEFINE FRAME fMain
BtnDone AT ROW 2.67 COL 51
cust-num AT ROW 3.14 COL 28 COLON-ALIGNED
WITH 1 DOWN NO-BOX KEEP-TAB-ORDER OVERLAY
SIDE-LABELS NO-UNDERLINE THREE-D
AT COL 1 ROW 1 SIZE 80 BY 8.29
DEFAULT-BUTTON BtnDone.
IF SESSION:DISPLAY-TYPE = "GUI":U THEN
CREATE WINDOW wWin ASSIGN
HIDDEN = YES
TITLE = "SMART SUBSCRIBER"
HEIGHT = 4.33 WIDTH = 66.6
MAX-HEIGHT . = 34.33 MAX-WIDTH = 204.8
VIRTUAL-HEIGHT = 34.33 VIRTUAL-WIDTH = 204.8
RESIZE = no SCROLL-BARS = no
STATUS-AREA = no BGCOLOR = ?
FGCOLOR = ? THREE-D = yes
MESSAGE-AREA = no SENSITIVE = yes.
ELSE {&WINDOW-NAME} = CURRENT-WINDOW.
/* ************************* Included-Libraries **************** */
{src/adm2/containr.i}
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN wWin:HIDDEN = yes.
ON END-ERROR OF wWin /* SMART SUBSCRIBER */
OR ENDKEY OF {&WINDOW-NAME} ANYWHERE DO:
IF THIS-PROCEDURE:PERSISTENT THEN RETURN NO-APPLY.
END.
ON WINDOW-CLOSE OF wWin /* SMART SUBSCRIBER */
DO:
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN NO-APPLY.
END.
ON CHOOSE OF BtnDone IN FRAME fMain /* Done */
DO:
&IF "{&PROCEDURE-TYPE}" EQ "SmartPanel" &THEN
&IF "{&ADM-VERSION}" EQ "ADM1.1" &THEN
RUN dispatch IN THIS-PROCEDURE ('exit').
&ELSE
RUN exitObject.
&ENDIF
&ELSE
APPLY "CLOSE":U TO THIS-PROCEDURE.
&ENDIF
END.
/* *************************** Main Block ******************** */
/* Include custom Main Block code for SmartWindows. */
{src/adm2/windowmn.i}
/* ********************** Internal Procedures *************** */
PROCEDURE adm-create-objects :
END PROCEDURE.
PROCEDURE custom :
DEF INPUT PARAMETER cust AS CHAR.
cust-num=cust.
DISPLAY cust-num WITH FRAME fmain.
END PROCEDURE.
PROCEDURE disable_UI :
IF SESSION:DISPLAY-TYPE = "GUI":U AND VALID-HANDLE(wWin)
THEN DELETE WIDGET wWin.
IF THIS-PROCEDURE:PERSISTENT THEN DELETE PROCEDURE THIS-PROCEDURE.
END PROCEDURE.
PROCEDURE enable_UI :
DISPLAY cust-num
WITH FRAME fMain IN WINDOW wWin.
ENABLE BtnDone cust-num
WITH FRAME fMain IN WINDOW wWin.
{&OPEN-BROWSERS-IN-QUERY-fMain}
VIEW wWin.
END PROCEDURE.
PROCEDURE exitObject :
APPLY "CLOSE":U TO THIS-PROCEDURE.
RETURN.
END PROCEDURE.
PROCEDURE initializeObject :
RUN SUPER.
SUBSCRIBE TO "custom" ANYWHERE.
END PROCEDURE.
59. Super Procedures.
ADD-SUPER-PROCEDURE( ) method Associates a super procedure file with a procedure file or with the current OpenEdge
session. When a procedure file invokes an internal procedure or a user-defined function,
Progress searches for it, among other places, in the super procedures (if any) of the procedure
file and of the current OpenEdge session. The procedure-search option determines which
procedures are searched.
Return type: LOGICAL
Applies to: SESSION system handle, THIS-PROCEDURE system handle and all procedure
handles
ADD-SUPER-PROCEDURE ( super-proc-hdl [ , proc-search ] )
Super-proc-handle
The handle of a running persistent procedure that you want to make a super procedure of the local procedure or of the current OpenEdge session.
ADD-SUPER-PROCEDURE returns FALSE if super-proc-hdl is not a valid handle, or if Progress detects that the method was not successful. Otherwise, the method returns TRUE.
proc-search
Optional expression that determines which super procedures are searched when super-proc-hdl invokes RUN SUPER or the SUPER function. Valid values are SEARCH-SELF (or 1) or SEARCH-TARGET (or 2). The default, if there is no entry, is SEARCH-SELF. The search commences in the super procedure stack of super-proc-hdl.
Consider the following:
o SEARCH-SELF starts searching in the procedure file that initiated the current internal procedure or user-defined function.
o SEARCH-TARGET starts searching the super procedures of the procedure file that originally invoked the current internal procedure or user-defined function (the procedure with the original RUN statement). If the procedure was RUN . . . IN procedure-handle, SEARCH-TARGET searches the super procedures of procedure-handle.
o A given super-proc-hdl can be added as either SEARCH-TARGET or SEARCH-SELF, but cannot be added as both. If proc-search is set for a super-proc-hdl, then any attempt to change its value generates a run-time warning, but the ADD-SUPER-PROCEDURE( ) method succeeds. The warning message “Changing proc-search-string for procedure <.p-name> from <string> to <string>” is presented to indicate that the application is using an instance of a given super procedure in an inconsistent manner. This warning message can be suppressed by using the SESSION:SUPPRESS-WARNINGS attribute. In addition, the warning message can be avoided by creating two instances of super-proc-hdl, one identified as SEARCH-TARGET and the other identified as SEARCH-SELF.
Associating a super procedure with a procedure The following example associates a super procedure with the current procedure:
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(my-super-proc-hdl, SEARCH-SELF).
The following example:
- Associates a super procedure with a procedure that the current procedure is working for.
- Requests that the super procedure stack associated with local-proc-hdl be searched rather than the stack associated with my-super-proc-hdl when RUN SUPER is invoked in super-proc-hdl.
local-proc-hdl:ADD-SUPER-PROCEDURE(my-super-proc-hdl, SEARCH-TARGET).
The procedure to which you add a super procedure is called the local procedure of the super procedure.
Associating a super procedure with the current OpenEdgesession The following example associates a super procedure with the current OpenEdge session:
SESSION:ADD-SUPER-PROCEDURE(my-super-proc-hdl).
When you do this, Progress automatically associates the super procedure with all the session’s
procedures—persistent and nonpersistent—without your having to change their code in any way.
This technique lets you replace occurrences of the following:
THIS-PROCEDURE:ADD-SUPER-PROCEDURE(super-proc-hdl).
in individual procedures with a single occurrence of the following:
SESSION:ADD-SUPER-PROCEDURE(super-proc-hdl).
Super procedure stacking
You can associate multiple super procedures with a single local procedure or with the current
OpenEdge session. When you do this, Progress stores (and later on, searches) the
corresponding procedure handles in last in first out (LIFO) order—the handle of the most recently
added super procedure first, the handle of the next most recently added super procedure second,
etc.
A collection of super procedure handles associated with a local procedure or with the current
OpenEdge session is called a super procedure stack. The handle of the most recently added
super procedure occupies the top of the stack.
If you add a super procedure that is already in the stack, Progress removes the previous
occurrence of the super procedure handle from the stack and adds the new occurrence to the top
of the stack—all without reporting an error.
Super procedure chaining You can add a super procedure to a super procedure. For example, imagine the following
scenario:
1. A, B, and C are procedure files running persistently.
2. B is a super procedure of A.
3. C is a super procedure of B.
B is a super procedure (of A) and has a super procedure (C).
When you add a super procedure to a super procedure, the result is a super procedure chain,
each link of which consists of two elements: a local procedure and its super procedure. When
Progress searches a super procedure chain, it does not proceed to the next link unless the
current link’s super procedure element explicitly invokes its super version (by using the
RUN SUPER statement or the SUPER function).
For example, imagine the following scenario:
1. A, B, and C, and X are procedure files running persistently.
2. add-record is an internal procedure different versions of which reside in A, B, and C.
3. B is a super procedure of A.
4. C is a super procedure of B.
5. X says RUN add-record IN A.
The following events occur:
1. Progress searches A for add-record and runs it if found.
2. If and only if A’s add-record exists and says RUN SUPER, Progress searches B for add-record and runs it if found.
Note: If A does not contain add-record, the following events occur: If B contains add-record, Progress runs it. If B does not contain add-record, Progress does not search for add-record in C.
3. If and only if B’s add-record exists and says RUN SUPER, Progress searches C for add-record and runs it if found.
In this way, Progress avoids excessive and possibly circular searching.
Search rules Progress searches for internal procedures and user-defined functions depending on how the
internal procedure or user-defined function is invoked. The search rules illustrated in the first
three cases assume that all the super procedures were added with no proc-search value or with a
proc-search value of SEARCH-SELF. The fourth case illustrates the search process when a
super procedure is added with a proc-search value of SEARCH-TARGET:
Case 1: When Progress encounters a statement like the following:
RUN add-record(’customer’).
Progress searches for add-record as follows:
1. As an internal procedure in the local procedure.
2. As an internal procedure in a super procedure of the local procedure.
3. As an internal procedure in a super procedure of the OpenEdge session.
4. As an external procedure file add-record.p or add-record.r.
Case 2: When Progress encounters a statement like the following:
RUN add-record(’customer’) IN my-proc-hdl.
Progress searches for add-record as follows:
1. As an internal procedure in my-proc-hdl.
2. As an internal procedure in a super procedure of my-proc-hdl.
3. As an internal procedure in a super procedure of the OpenEdge session.
Case 3: When Progress encounters a statement like the following:
add-record(’customer’).
Progress searches for add-record as follows:
1. As a user-defined function in the local procedure.
2. As a user-defined function in a super procedure of the local procedure.
3. As a user-defined function in a super procedure of the OpenEdge session.
Note: The rules of Case 3 apply whether or not the user-defined function’s declaration (function prototype) includes the IN proc-hdl option. In Case 3, proc-hdl represents the local procedure.
Search rules for SEARCH-TARGET Case 4: A procedure, main.p, has added three super procedures, S1, S2, and S3 (in that order). Each of these super procedures has added its own super procedures, S1A, S1B, S2A, S2B, S3A, S3B. The procedure, add-record, exists in three places: in S1, in S2 where it contains a RUN SUPER statement, and in S2A.
When Progress encounters a statement like "RUN add-record(’customer’).", it searches
for the add-record procedure:
1. As an internal procedure in the local procedure, main.p.
2. Then as an internal procedure in S3, and then in S2 where it is found.
If add-record was added with no proc-search value or with a proc-search value of
SEARCH-SELF, when RUN SUPER is executed within add-record in S2, Progress starts
searching in S2A, which is next in the search stack of the super procedure S2.
If add-record was added with a proc-search value of SEARCH-TARGET, when RUN
SUPER is executed within add-record in S2, Progress will start searching in S1 which is
next in the search stack of the local procedure, main.p.
Note: The search commences with the super procedure following super-proc-hdl in the local procedure’s chain.
60. SDLC phases and your involvement in each phases in your projects.
61. Difference between state-less and state-free (new in OE).
62. Difference b/w strong and week scope. Give examples.
63. Dynamic temp-table, dynamic buffers. Give examples.
CREATE TEMP-TABLE statement Creates a temp-table dynamically at run time. The temp-table that is created is empty and
must be defined using ADD/CREATE methods.
Syntax CREATE TEMP-TABLE widget-handle
[ IN WIDGET-POOL widget-pool-name ]
widget-handle
A variable of type WIDGET-HANDLE that represents the handle of the temp-table object.
IN WIDGET-POOL widget-pool-name
An expression of type CHARACTER that evaluates, at run time, to the name of the widget pool that contains the dynamic temp-table.
Note: Widget pool names are not case-sensitive.
Example The following example creates a temp-table like the order table and populates it from the order
table. In addition, the corresponding sales-rep name is added from the salesrep table.
r-cretmpt.p
DEFINE VARIABLE tth AS HANDLE.
DEFINE VARIABLE bh AS HANDLE.
DEFINE VARIABLE qh AS HANDLE.
DEFINE VARIABLE buf-ord-hndl AS HANDLE.
DEFINE VARIABLE buf-rep-hndl AS HANDLE.
DEFINE VARIABLE fld1 AS HANDLE.
DEFINE VARIABLE fld2 AS HANDLE.
/* get database table handles */
buf-ord-hndl = BUFFER order:HANDLE.
buf-rep-hndl = BUFFER salesrep:HANDLE.
/* create an empty undefined temp-table */
CREATE TEMP-TABLE tth.
/* give it order table’s fields & indexes */
tth:CREATE-LIKE(buf-ord-hndl).
/* add field like Salesrep.Rep-Name */
tth:ADD-LIKE-FIELD("RepName","Salesrep.Rep-Name").
/* no more fields will be added */
tth:TEMP-TABLE-PREPARE("ordx").
/* get the buffer handle for the temp-table */
bh = tth:DEFAULT-BUFFER-HANDLE.
/* populate the temp-table from order */
FOR EACH order:
bh:BUFFER-CREATE.
bh:BUFFER-COPY(buf-ord-hndl).
/* add the corresponding salesrep name */
FIND salesrep WHERE salesrep.sales-rep = order.sales-rep NO-ERROR.
IF AVAILABLE salesrep THEN
bh:BUFFER-COPY(buf-rep-hndl,?,"RepName,rep-name").
END.
/* run a query to access the temp-table */
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE("for each ordx where order-num < 50 BY RepName").
qh:QUERY-OPEN().
fld1 = bh:BUFFER-FIELD("order-num").
fld2 = bh:BUFFER-FIELD("RepName").
/* display the order-number and the salesrep name */
REPEAT:
qh:GET-NEXT().
IF qh:QUERY-OFF-END THEN LEAVE.
DISPLAY fld1:BUFFER-VALUE() FORMAT "X(10)".
DISPLAY fld2:BUFFER-VALUE() FORMAT "X(20)".
END.
qh:QUERY-CLOSE().
bh:BUFFER-RELEASE().
DELETE OBJECT tth.
DELETE OBJECT qh.
Notes Ø Once the temp-table fields and indexes are defined using the ADD/CREATE methods, the definition must be terminated by using the TEMP-TABLE-PREPARE method before the temp-table can be used.
Ø Once the temp-table is prepared, it can be manipulated by using its buffer object handle which is retrieved using the DEFAULT-BUFFER-HANDLE attribute. All the BUFFER methods are available to the dynamic temp-table.
Ø The dynamic temp-table object is scoped like the buffer object. It is created in a widget pool and ends when the widget pool ends or when it is deleted with the DELETE OBJECT statement. You may not delete the default buffer object belonging to a dynamic temp-table.
Ø Errors for dynamic temp-tables do not automatically raise the ERROR condition since they occur inside a widget expression. All the methods that can have errors return FALSE if an error occurs, so they must be tested. If NO-ERROR is in effect in the statement containing the widget reference, no messages display, but they can be retrieved from the ERROR-STATUS system handle.
Dynamic Buffers:
CREATE BUFFER statement Creates a dynamic buffer.
Syntax
CREATE BUFFER handle FOR TABLE table-exp | table-handle-exp
[ BUFFER-NAME buffer-expression ]
[ IN WIDGET-POOL widget-pool-name ]
handle
A variable of type HANDLE that represents the handle of the buffer object.
FOR TABLE table-exp | table-handle-exp
A character expression that evaluates to a unique database table name or temp-table name or to the handle of a database table or a temp-table.
Note: If the table name is ambiguous, you must qualify it with a database name.
BUFFER-NAME buffer-expression
An expression of type CHARACTER that evaluates, at run time, to the name of the dynamic buffer you are creating. This option lets a dynamic query have multiple buffers for the same table.
IN WIDGET-POOL widget-pool-name
An expression of type CHARACTER that evaluates, at run time, to the name of the widget pool that contains the dynamic buffer.
Note: Widget pool names are not case-sensitive.
Example The following example runs the query “for each customer” dynamically against the Sports
database using a purely dynamic buffer with no compile time references at all:
r-crtbuf.p
/* r-crtbuf.p */
/* requires a connection to the Sports database */
DEFINE VARIABLE i AS INTEGER.
DEFINE VARIABLE qh AS WIDGET-HANDLE.
DEFINE VARIABLE bh AS WIDGET-HANDLE.
DEFINE VARIABLE fh AS WIDGET-HANDLE EXTENT 10.
CREATE BUFFER bh FOR TABLE "customer".
CREATE QUERY qh.
qh:SET-BUFFERS(bh).
qh:QUERY-PREPARE("for each customer").
qh:QUERY-OPEN.
qh:GET-FIRST.
DISPLAY bh:NAME.
REPEAT i = 1 TO 10.
fh[i] = bh:BUFFER-FIELD(i).
DISPLAY fh[i]:NAME STRING(fh[i]:BUFFER-VALUE).
END.
DELETE WIDGET bh.