A History of Progress

Acronymic Legacy: The Origin of DLC
The R-Code Limit
Version 1
First Business
Early Employees
Application Partners
Business Moves
Modern Progress
Future Shock
Going Public
Progress Goes GUI
Object Orientation
What Does The Future Hold?

Planning

The Keys To A Successful Application
System Management
Database Responsibility
Project Responsibility
Process Management

Practical Systems Analysis

Why do Systems Analysis?
Purpose of the Application
Object Flow
Information and Documentation Flow
Data Generation and Accuracy
Create a Design Document


Systems Design

Toward a New Design Model
Business Rules
Sequencing Business Rules
Tools
Infrastructure
Concurrency & Transaction Management
Hardware
Database Design
Indexing
Application Design
Distributed Application Component
GUI-TTY-Web
User-Based Application Design
Multi-Site Issues
Development Software
Programming Paradigm
Event-Based Design
Just In Time Computing
Object-Oriented Design
Disaster Recovery
Deployment
Documentation
Designing the Development Environment
Administration
Testing
Database Design
Replication
Adopting New Methodologies


Database Design

Principles of Database Design
What a Database is For
Establishing the Data Stores
Rodney's Rule of Repeating Names
Daphne's Dictum
Marjorie's Mantra
Rebecca's Rules
Determining the Accuracy of Data
Anixter's Axiom
"Smart" Fields
Normalizing Your Data
John's Theory of Database Normalization
The Hippenhop Theory of Normalization
Murphy's Corollary to the Hippenhop theory
Steinbrenner's Observation on Murphy's Corollary:
Yosh's Cost Benefit Analysis of Normalization:
Seven Simple Steps to Normalization
First Normal Form
Second Normal Form
Third Normal Form
Fourth Normal Form
Fifth Normal Form
Structuring the Database for Joins
Structuring the Database for Rapid Data Access
Table Size and Access Speed
Field Lists
Validation and Referential Integrity
Trigger Overview
Preventing Orphanages
Analyze the Database for Inefficiencies or Redundancies
Redundant Indexes
Field Redundancies
Looking For Inefficiencies
Sizing Your Database
Multiple Databases vs. Single Databases

Installing and Configuring Progress

System Configuration
Host-based
Client-Server
The Application Server
Internet and Intranet
Operating Systems
Hardware
Multi-volume
RAID
Configuring Memory
Configuring the Operating System
Configuring Progress
Progress Databases
Installing and Tuning Progress
Identifying Application Components
Starting and Shutting Down Progress
Single vs. Multi-user

The Work Environment

Configuration of the Development Environment
Database Control
Configuration Management Versus Code Control

Project Management

Budget
Programming Resources
The Calendar Factor
Tools
Development Environment
Training
Specifications
Standards
Documentation
Support
Testing
Milestones
Deployment

Progress Internals

Data Movement
The Server/Broker
Client Memory
Variables
Query Cache
The Client-Server Model
The Client
The Server
The BI File
Self-Service vs. Remote Clients
Application Server
Internet/Intranet Capabilities
Summary

The Progress Database

Background
Purpose of the Progress Database
Classes of Progress
Components
Database Component Overview
The Progress DB File
The BI File
Shared Memory
The LK File
The AI File
Multi-volume
Database Internals
DB Composition
Blocks and Chains
Progress Datatypes
Data Formats
Indexes
Index Structure
Index Cursors
Index Structure
Clear talk about bracketing
The Private Life of the BI File
BI Internals
To Truncate or Not to Truncate
Checkpointing
APWs, BIWs, and Checkpointing
The Local Before-Image File
Volumes
Schema Cache
The Template Record

The Metaschema

Metaschema Map
Compile Time Role of the Schema
Validation and Help
Triggers
Index Selection and Record Reading
Default Values: The Template Record
Data Integrity
Time Stamp and CRC
Converting a DB from one Version to another
Fast Schema Change

The Progress Compiler

The 63-K Code Limit
Segmented R-Code Structure
Background
How the Compiler Works
The Metaschema and the Compiler
Screen Formatting
Validation
Triggers
Preprocessor and Includes
SQL and GL

The Progress Language

4GL Programming
Identifying the Programming Styles
Block Structure
Event Programming
Object-Orientation
Tools

Client-server

Broker, Server, Client
Configuring A Client-server Environment
Client-Server Performance
The Roots of all Client-Server Evil
Reduce Network Traffic
Reduce Record Reads
Bracketing
Move Functionality to the Server
Don't Re-read Records
Local Databases
Local Code
Local Flat Files
Local Temp Files
Schema Cache
Reduce Data Transfer
Field Lists
Results List Entries
Reduce Program Calls
Components
Program Library Storage (-pls)
Summary

Blocks

Implicit vs. Explicit Properties
Kinds of Blocks
Block Properties
Exception Handling
Transaction Control
Data Context
Block Types

Scope

Definition
Purpose
Duration of Scope
Instantiation, Context, and Scope
Levels of Context
Kinds of Scope
Data Structures and Scope
Triggers, Procedures and Scope
Visualizing Scope
Scope and Progress Commands
Borrowing Frame Scope
Record Scoping
Record Scope and Block Scoping "Strength"
Transaction Scope
Screen Objects and Scope

Error Management

Error Handling and Blocks
How Blocks Work
Block Actions
Specified Block Control
Suppressing Run-time Errors
Inter-program Error Control
Errors and Triggers

Transactions

Transaction Problems
Optimistic vs. Pessimistic Locking
Judgmental Concurrency
Defaults
Transaction Scope
Sub-Transactions
Transaction Scope and Record Locks
How and Why to Change Transaction Scope
Suggestions for Structuring Transactions
Exceptions
Distinct Transactions on Application Servers

Validation and Integrity

Screen Independent Validation
Virtual vs. Static Lookup Tables

Reusable Code

Building Good Reusable Modules
The Reusability Process
Kinds of Reusability
Identifying Reusable Code
Reusability Tools
Conditional Parameter Passing
Vertical Reusability
Establishing Persistence
Local and Remote Effect
Message and Information Broadcast
Linking
Building a Simple ActiveX Application
VBX Example
User-defined Functions
Recursive Reusability: Multi-Level Operations
The Preprocessor
Separating Interface from Function
Debugging the Preprocessor
Generating Progress Code from a Program
Late Binding
Creating a Dynamic Query
Custom Screen Objects
Triggers and Reusability
AppServer Modules
Object-orientation and Reusability

Frames

What is a Frame?
Categories of Frames
Components of Frames
How Progress Lays Out Frames
Frames and Blocks
Default Frame
Frame Type and Block Type
Difference Between Default Frame and Scoped Frame
The Default Frame and the Unnamed Frame
Naming Frames
Frame Functions
Determining Screen Buffer Value
Sharing Frames
Character and GUI Frames

Interface Components

Widgets, Objects or Controls?
Progress and the GUI Environment
What is a widget?
Character and GUI Widgets
Types of Widgets
Classification of Widgets
Containers
Manipulation Widgets
Data Representation
Fill-in
Radio Set
Toggle Box
Slider
Editor
Lists
Browser
Selection List
Combo Box
Decorative Widgets
Pseudo-Widgets
GUI Vocabulary
The View-as Statement
Attributes
Methods
Events
Enable
Wait-For
Handles
Pseudo-widgets
Programming With Widgets
Creating Widgets
The Value of A Widget's Data
Using Attributes
Readable vs. Writable Attributes
Toggling an Attribute
Common Attributes
Attributes for the Browser
Max-Data-Guess
Attributes for an Editor
An Editor Undo Function
Attributes for a Selection List
Sliders
Toggle Box
The Window Widget
Window State
Fill-in
Frame
Radio set
System Handles
Error-Status
Focus and Self
Session
Immediate-display
This-Procedure
Attributes vs. Properties
Using Methods
Methods for a Selection List
Working with VBXs
VBX Properties
Editor Methods
Browser Methods
The Radio Set
Image and Buttons
Procedure Methods
Methods vs. Events
Walking the Widget Tree
Dynamic Widgets
Character Mode vs. GUI Widgets
Conclusion

Event-driven Programming

A New Paradigm
"Events" In a Procedural Context
Global Events in Procedural Programs
Local Events
Expanded Events
Contrasting a Global and Local Events
Expanded Event Set
How Event Programming Works
Classes of Events
Keyboard events
Ways to Leave a Field
Mouse Events
High-Level Events
Direct Manipulation Events
Which Events Exist for a Widget
Using Events in Your Code
Events and Triggers
Categories of Triggers
Structuring an Event Driven Program
Converting Editing Blocks to Triggers
Tricks and Tips
Disabling Events
Applying Events Through Code
Client-centric Approach Revisited:
The Difference Between Interface & Schema Triggers
When to Use Event Triggers, Assign Triggers, or Validation
Conclusion

Separating Function from Interface

A Brief History of How We Code
GL Legacy
Business Structure Sometimes Embedded Within the Code
Business Rules Embedded in the Interface
Relational Legacy-Business Structure within the DB
GL Legacy
Making the Separation Real
Object-Orientation and its Potential
User Interaction Independent of Interface
Further Separating Interface and Function
Separating the Database Functionality from the Interface
Using Triggers to Isolate Functionality
Using the Application Server
Business Structure Independent of Functionality
Reusability
Unit Function Level
Business Process Objects
Modular Objects-Working for Maximum Flexibility
Business Objects
Starting With GUI
How Do I Get from Here to There?

Object Methodology

Moving Your Progress Application Toward Object-Oriented Principles
What is Object Methodology?
Application Flexibility
Modular Data Functions
From Applications to Objects
Some Simple Rules
Building Code Objects
Conceiving and Building the Application:
Evaluate High-level Application Functionality
Getting Started
Visualizing the Screen Objects
Steps in Building the Application
Building the Screen
Abstracting the Code
Interaction Between Objects
Editing The Data
Editing
Edit Actions
Messaging
Object Independence
Separating the Objects
Overview
Concepts
Creating New Windows
Relating Programs
Tight Coupling vs. Loose Coupling
Linking the Browser and Viewer
Internal Functionality of an Object
Review
Adding more Functionality
Encapsulation
Adding the Control Panel
Message Dispatching
Simple Inheritance
Methods
Building Methods
Modifying Methods
Making Methods into Method Libraries
Method Overriding
De-coupling Programs
Communicating Values From one Object to Another
Conclusion

Smart Objects

Evolution Of Smart Objects
Anatomy of a Smart Object
Smart Object Functionality
Relationships Between Smart Objects
Links and the Broker
Messages
Methods, Attributes, Events and States
States
Incorrect Messaging
Public, Private and Local Data
Global Data
Attributes and Smart Objects

Importing Data Into Progress

Formatting Data for Progress Input
Getting the Vocabulary Straight
Method : No Pre-formatting
Method : Quote Contained
Mixed "Containers"
Fixed Length Input
Quoter
Merging and Separating Data
Splitting Data Into Multiple Records
Multiple Input Files
Repetitive Data in Input Files
Skipping Fields in the Input
"Padding" Input with Blank Fields
Detecting Errors
Validating Data
Application Code Validation
Using Quoter

Writing Reports

Inner and Outer Joins
Left Outer Joins
Unique Inner Joins
Unique Inner Joins: A Reprise
Recursion
Buffers
Page Formatting
Line-counter and Page-size
Page Width
Using When and @
Multiple Output Destinations
Reading Data into an Editor
Labels
Line-by-line control
Printer Controls
Exporting Data
Fixed Length Fields
Delimiters
Your Own Delimiters
Unusual Situations
Centering Text
Report Writers
Conclusion

Using the App Builder

What IS the UIB?
Components of the UIB
Getting Started
Building A Browser
Opening A Query
UIB Preprocessor Names
Property Sheets
Group Properties
Re-opening the query
Importing Data

Maintenance Applications

Principles
Container
The Call-program Procedure
Create-Link
Goodbye
Send-message
The Control Panel
set-broker
toggle-buttons
Edit Button
Add Button
Delete Button
OK Button
Cancel Button
The Viewer
Viewer Methods
add-mode
apply-entry
assign-fields
clear-frame
delete-record
disable-fields
display-data
display-defaults
enable-fields
find-address
find-company
hide-frame
view-frame
The Order Viewer
find-record
open-query
The Browser
Procedures
disable-widgets
enable-widgets
get-company
get-order
get-person
open-query
refresh-browse
set-broker
Interface Events
Value-changed of browser
Choose of company
Choose of order
Choose of Person
Message Names and Procedure Names
Summary

Using Smart Objects

Overview
Getting Started
The Container and Folder
Building Instances
Browsers
Transaction Management
Modifying a Master's Properties
Establishing Links
Method Overriding
States
Smart Queries
Attributes
The Value-changed Trigger
Simple Debugging
Custom Objects
Conclusion

WebSpeed

A Little Background
HTML (HyperText Markup Language)
Why WebSpeed?
WebSpeed Architecture
WebSpeed Development Environment
Transaction States
Advantages Versus Disadvantages

Programming for Performance

Magnification of Inefficiencies
Magnification of Effort
How to Detect the Data Magnification Problem
What Causes Performance Problems?
Database Design
Database vs. Code
Why Do You Need Indexes?
Rapid Access
Relational Joins
Unique Records
Data Validation
Index Redundancy
Bracketing Rules
What is a Bracket?
How do You Know if You've Bracketed?
Range Match
Index Selection Rules
Single
Multiple
None
How do you Know What Index is Selected?
Rule S-1: Equality Matches and Unique Index
S-2 Most Active Equality Matches
S-3 Most Active Range Matches
S-4 Most Active Sort Matches
S-5 Primary Index
S-6 Alphabetical Order
Multi-index Rules
Index Rules Summary
Is Single-Index Support So Bad?
Order of the Query vs. Order of the Index
Overhead of Multiple Indexes
Application Structure
Redundant Record Reads
Insidious Redundancy
Smart Coding
Break-by
Reducing Program Calls with Includes, Internal Procedures and Functions
Progress Language Use
Should I Use Use-index?
Other Ways of Reducing Traffic
Field Lists
Application Server
Inner Joins
Don't Build Extra Records
Use No-lock
If One Action Will Supersede Another, Create a Conditional Statement
Don't do Unnecessary Tests to Filter Data
Eliminate Unnecessary Assignments
Don't Use a "For Each" in Place of a Find
Use "For First" if it Makes Sense
File Linking Without Indexes
Drawbacks to Recid Joins
Using "Entity" or "Instance" Files
Variables, Transactions and Efficiency
Subtransactions
No-Undo Variables
Smaller Savings: Assigns, Nested Functions, Immediate If
Multiple Assigns
Multiple Assigns and Index Updating
Initializing Arrays
Using Trim
Immediate If
Nesting Functions
Conclusion

Testing and Debugging

Successful Application Testing
Test Data
Unit Testing
Acceptance Testing
Avoid Repetition
Post Acceptance Testing
The Pilot
Stress Testing
Implementation Scheduling
Planning For Problems
Debugging Code
Compiler Options
The Venerable Message Statement
Debugging With The Preprocessor
Debugging Batch Programs
Using the Debugger
Debugger Basics
Returning Control to the Debugger
Setting Break Points
Writing Your Own Debugger
Explanation of the Variable Usage


Disaster Prevention

Making the System Available
Have You Met the Chairman of the Board? Keeping It Available
How Long Can you be Down?
Data Loss
UPS
Mirroring
On-Line Backups
Backing up the Database
Full vs. Incremental Backups
Incremental Backup & Restore
Replication
Synchronous (real-time) Replication
Asynchronous (deferred) Replication
How Does it Work?
Synchronous Distribution
Asynchronous Distribution
Consolidation
After Imaging
On-line Backup with AI
Getting it Back
Using After Imaging
What About RAID?
On-line Schema Changes
Summary

System Performance


What is the Progress Database?
How do You Measure Performance?
Your Objective
Moving Data in Progress
A Look at Shared Memory
Database Buffers
Tuning the Buffer Size
The BI File
BI Internals
BI Cluster Re-use
Checkpoints
BI Cluster Size
BI Block Size
BI Buffers
BI Buffer Internals
BI Buffer Size
Improving Writes from the BI Buffers
Other BI File Issues
Multi-Volume
BI File Location
Truncating the BI file
Truncation and Multi-volume
Asynchronous Page Writers (APWs)
APWs and Checkpointing
Servers and Users
Multiple Brokers
After-Imaging
The Hash Table
Client Side Tuning
Quick-Start
Schema Cache
SRT File Basics
Program Library
Prolib Memory
Moving Data Back to the Server
Increasing DB Efficiency
Multi-volume
Creating a Multi-volume Environment
Creating a Structure Description File
Block Size
Raw Partitioning
Multi-CPU Systems
The Spin Parameter
Setting Spin Parameters
Procedural Issues
Truncating the BI file
Rebuilding Indexes
After Imaging and Performance
System Deployment
Summary