Skip to content

Language Reference Collections

Andreas AFENTAKIS edited this page Oct 9, 2025 · 18 revisions

**PAGE UNDER CONSTRUCTION **

Language Reference Collections

In FBASIC, collections are fundamental data structures used to manage lists of values and result sets from data sources. While traditional single variables hold one value, collections allow a program to store and iterate over multiple related items efficiently. The two primary collection types referenced in the language are SDATA (or Static) and CURSOR (or Fetchable).

Understand the concept

FBASIC is an extensible computer programming language whose core interpreter provides fundamental structures common to all modern languages, facilitating the easy, statement-by-statement translation to other programming environments. Within FBASIC, data management is distinguished by two primary collection types: static collections, which are typically one-dimensional arrays of data stored directly and contiguously in memory for fast access, and fetchable collections, which are designed for sequential, row-by-row access and do not support direct, indexed lookup of individual rows.

Characteristic Static Fetchable
In memory Yes No
Access row by index Yes No
Access row by fetch Yes Yes
Need reset Yes Yes
Foreach loop Yes Yes
Known number of items Yes No
Multi field support No Yes
Dynamic field naming No Yes
Need data source No Yes
Data from the program (via SDATA) Yes No
Statement SSET Yes No

1. SDATA Collections (Static Data)

An SDATA collection is a dynamic, in-memory structure primarily designed to store and manage lists of primitive values (like strings or numbers) generated or manipulated within the FBASIC program's execution flow. It serves a similar role to an array or list in other languages, allowing for flexible data aggregation.

Creation and Population

The SDATA collection is created and populated using the SDATA statement.

Statement / Element Purpose Example
SDATA collection value Appends a single value to the end of the collection. sdata names "John"
SSET collection index identifier Change the item that the index points to the value or variable SSET names 1 "Jim"
SCNT("collection") Function returns the total number of elements (count) currently stored in the SDATA collection. print SCNT("names")
SCI("collection", index) Function returns the value of the item at the specified 1-based index in the SDATA collection. print SCI("names",1)
[collection.Item] An identifier with a special syntax used to reference the current fetched item's value. Need FETCH or FOREACH loop before use it. [names.Item]
RESET collection Reset a collection and move the underlyning cursor to the first item RESET names
FOREACH collection Move the underlyning cursor to the next row of a collection. FOREACH names ..... ENDFOREACH

Special attention:

  • Function names for collections use capital (uppercase) letters (e.g., SCNT), which contradicts the convention for most other functions in FBASIC. Remember that statements are case-insensitive, but functions are case-sensitive.
  • The collection name passed to these functions is treated as a string value or variable, not an identifier. Therefore, a literal collection name must be enclosed in quotes.

Population Example (from code)

The following example demonstrates initializing an SDATA collection and populating it within a loop:

inputLoop:  
   input nameInput

   If nameInput \= "." Then  
      GoTo endInput  
   EndIf

   REM Store the name into the SDATA collection  
   sdata names \[nameInput\]  
     
   GoTo inputLoop  
endInput:

Retrieval and Iteration

The standard way to access all items in an SDATA collection is using the FOREACH...ENDFOREACH loop structure.

Statement Purpose
FOREACH collection Move the underlyning cursor to the next row of a collection.
[collection.Field_Name] An identifier with a special syntax used inside a FOREACH loop to reference the current item's value.
ENDFOREACH collection Closes the loop structure.

Example of Iteration:

Foreach customers  
   print \[names.FirstName\]  
EndForeach customers

Explicit SDATA Manipulation Statements and Functions

FBASIC provides dedicated statements and functions for advanced management of SDATA collections, granting array-like control.

Statement/Function Syntax Type Description
SSET SSET collectionName, index, value Statement Sets/updates the value of an item at a specific, 1-based index in the SDATA collection.
SCNT() SCNT(collectionName) Function Returns the total number of elements (count) currently stored in the SDATA collection.
SCI() SCI(collectionName, index) Function Returns the value of the item at the specified 1-based index in the SDATA collection.

Example using SSET and SCNT():

sdata scores ""  
sdata scores \[95\]  REM stores 95 at index 1  
sdata scores \[88\]  REM stores 88 at index 2

let total \= SCNT(scores)  
print "Total items: " \+ total  REM Prints 2

SSET scores, 2, 90  REM Change value at index 2 from 88 to 90  
let newScore \= SCI(scores, 2\)  
print "New score at index 2: " \+ newScore REM Prints 90

2. CURSOR Collections (Dynamic Data)

The CURSOR collection is a special type of collection that acts as a wrapper for external data sources, specifically SQL results. It is designed for efficient, record-by-record retrieval of data without loading the entire dataset into memory at once.

Creation

The CURSOR collection is created using the CURSOR statement, which typically executes a SQL query against a configured data provider.

Syntax: Cursor collectionName, "SQL Statement"

Example:

Cursor DATA1, "select top 20 id,name where type='S' from sysobjects order by name"

Retrieval and Navigation Statements and Functions

Statement/Function Syntax Type Description
FETCH FETCH collectionName Statement Reads the next record from the cursor's result set, making its fields accessible for use.
RESET RESET collectionName Statement Resets the cursor position back to the beginning of the result set, allowing the program to iterate over the data again.
EOD() EOD("collectionName") Function Returns a boolean value (true/false) indicating if the End Of Data has been reached for the specified cursor.
Field Access [collectionName.FieldName] Syntax Accesses the value of a field from the currently fetched record.

A. Standard FOREACH Loop

This is the most common and robust method for processing all records in the result set.

Foreach DATA1  
   sdata names \[DATA1.name\]  
EndForeach DATA1

B. Manual FETCH Loop

This method offers fine-grained control over reading records, often used with conditional branching using EOD().

dataloop1:  
fetch DATA1  
If EOD("DATA1") Then  
   GoTo exitloop  
EndIf

let msg= "ID: " \+ sql(\[DATA1.id\]) \+ ", Name: " \+ sql(\[DATA1.name\])  
print msg

GoTo dataloop1

exitloop:

3. Data Provider Concept

The Data Provider is a crucial component that extends FBASIC's core functionality, serving as the bridge between the program's execution environment and external data sources, typically relational databases accessible via SQL.

Role and Function

The Data Provider is an external adapter, configured at the interpreter level, that executes the following responsibilities:

  1. Connection Management: It establishes and maintains the necessary connection to the external database (e.g., SQL Server, Oracle, or a file-based database).
  2. SQL Execution: It receives the raw SQL query string passed through the CURSOR statement. It executes this query against the configured database.
  3. Result Set Wrapping: Instead of returning the raw data, the Data Provider wraps the query results into a CURSOR collection. This design ensures that FBASIC can efficiently process large datasets record-by-record without loading the entire result into memory, facilitating data streaming.

The CURSOR collection is entirely dependent on a correctly configured Data Provider being available to the FBASIC environment. If the Data Provider is not configured or fails to execute the SQL, the CURSOR statement will result in a runtime exception.

Clone this wiki locally