Documentation
Download Latest VersionIndex JumpStart History Classes Properties Methods
CapeSoft Logo

CapeSoft Reflection
Documentation

Installed Version Latest Version

Introduction

The Reflection class allows generic code (libraries) to work on structures in a more powerful way. This is done through the use of Extended Name Attributes which are declared with the structure. These attributes can then be used so that libraries better understand the structure.

The Reflection class acts as a parser for the extended attributes layer, and also allows you to alter attributes at run time.

Because the extensive use of Reflection encourages libraries to support more complex data structures (queues-in- queues etc) the Reflection class also provides a number of Helper methods to perform common tasks that these libraries will need. For example DISPOSEing complex structures is complicated, so Reflection has a helper method which does that for you.

This is a required layer for some other CapeSoft Accessories, and is provided free of charge.

Requirements

Reflection requires StringTheory 3.

ClarionLive

An introduction to this class, and the way in which it works, was described in ClarionLive session #637 , recorded on 12 November 2021.

Installation

Run the supplied installation file.

Jump Start

Add the global extension to your app file.

Support

Your questions, comments and suggestions are welcome. Check our web page (www.capesoft.com) for new versions. You can also contact us in one of the following ways:

CapeSoft Support
Email support@capesoft.com
Telephone +27 87 828 0123
(087) 828 0123

License and Distribution

No additional files are required for shipping.

The files in this product are copyright 2024 by CapeSoft.

This product is provided free of charge for the use by the Clarion community. It can be ordered (for free) from ClarionShop.

Other 3rd party suppliers are explicitly allowed to create their own libraries making use of this library.

This product is provided as-is. CapeSoft Software and CapeSoft Electronics (collectively trading as CapeSoft), their employees and dealers explicitly accept no liability for any loss or damages which may occur from using this package. Use of this package constitutes agreement with this license. This package is used entirely at your own risk.

Use of this product implies your acceptance of this, along with the recognition of the copyright stated above. In no way will CapeSoft , their employees or affiliates be liable in any way for any damages or business losses you may incur as a direct or indirect result of using this product.

For the full EULA see https://capesoft.com/eula.html

AnyScreen

Reflection is a class product, and has no User Interface, so it is completely compatible with programs running under AnyScreen.

Use in a Hand-Coded Project

  1. Add the line
    Include('Reflection.Inc'),Once
    to your project in the appropriate scope, so the class is in scope.
  2. Set the Conditional Compile in your project
    ReflectionLM => 1
  3. Set the Conditional Compile in your project
    ReflectionDM => 0

The Naming of Things

The word "name" is used rather casually when referring to a declaration. In order to properly understand the sections that follow, it is important to be precise in the usage.  The simplest Clarion declaration consists of a LABEL and a TYPE;

x  Long

This declaration has no NAME attribute. So in this situation the NAME of the field defaults to the UPPER CASE of the LABEL. So the NAME of this field is X.

Fields can be declared with a specific name;

s  String(255),Name('Title')

In this case the LABEL of the field is S (LABELS are ALWAYS UPPERCASE) and the NAME of the field is Title. (Names are always Case Sensitive.)

In the Clarion language LABELS have to be unique, NAMES do not have to be unique. However the ReflectClass identifies things based on their Structure Name (known as the GroupName) and the NAME (known as the ColumnName). So for the purposes of using the ReflectClass the NAME attribute has to be unique in the structure.

a1  String(255),Name('Address1')
a2  String(255),Name('Address2')
a3  String(255),Name('Address3')


In external data structures, like JSON and XML, these names translate into the TagNames used in those structures. However in those (and other) external structures, those TagNames do not need to be unique. For this reason the ReflectClass supports the Rename attribute.

a1  String(255),Name('Address1 | Rename(Address)')
a2  String(255),Name('Address2 | Rename(Address)')
a3  String(255),Name('Address3 | Rename(Address)')


But wait, there's more.

It is possible that one structure will be used to export data to multiple different formats. And conceptually these names may be different from one format to another. In this situation the declaration may look like this;

a1  String(255),Name('Address1 | Rename(Address) | XMLName(ADDR) | JsonName(address)')

In this case, when matching to XML (importing or exporting) it is ideal to use ADDR, when matching to JSON use address (lower case) and when matching to anything else use Address (mixed case). In order for the object to know which external tagname to use, a property called tag exists. This property can be set before parsing the structure. For example;

reflection  ReflectClass
  code
  reflection.tag = 'xmlname'


When this is set, and the structure is parsed, then the XMLName (if it exists) will be placed in the Rename Attribute for the field.

Hint: The Name attribute is limited to 100 characters long by the Clarion language.

Getting Started

The ReflectClass class is declared in Reflection.Inc and the code for the class is in Reflection.Clw. The goal of the class is to accept structures (Group, Queue, File and View) and to parse out their attributes, and extended attributes. This can then be used when writing generic functions.

A small template (Reflection.Tpl) is also provided for use in an App - This includes a global template for Activating the class in a program, and a Local template for instantiating instances of the class in procedures. Reflection can also be used in hand-coded projects, or included in other classes.

In most cases the use of ReflectClass will be simple;

1) Parse the structure

3) While looping through the records in the structure, use the GET methods to discover the attributes for the columns, and make the appropriate changes to input and output.

In more complex cases it's possible to include some more steps;

2) Add additional attributes to the columns in the structure using one or more of the SET methods.

4) Depending on your structures (especially queue-in-queue and queue-in-group nested structures) make use of the DISPOSE methods.

Using ReflectClass

The class primarily takes in a structure, parses it, and then provides a number of methods for accessing the structure for use by the calling class.

The first step is to declare an object of the class.

Reflection  ReflectClass

The next step is to pass a structure to the class for parsing. A single object can manage the parsing for multiple different structures. To do this a Structure Name (known internally as the GroupName) is used with the Parse method.

HomeQueue      Queue
House            String(255),name('House')
Photo            &StringTheory,name('Photo | StringTheory | Binary')
Date             Long,name('Date | date | @d6')
Pets             &PetsQueueType,name('Pets | Queue | RowName(Pet) | Rename(xPets)')
               End 

PetsQueueType  Queue,type
id               Long,name('Id | attribute')
Name             Group,name('Name')
WholeName          String(20),name('WholeName')
NickName           String(20),name('Nickname | attribute')
                 End
               End

  code
  reflection.Start()
  reflection.Parse('homequeue',HomeQueue)


Structures may contain child queues. If these queues are assigned to something (ie not null) then they will be parsed when the parent is parsed. If they are null then they are not parsed and will need to be parsed later, when set to something.

Structures may contain child groups. These are parsed when the parent is parsed.

Once the structure has been parsed the items in the structure can be accessed using the GetAttributeExists and GetAttributeValue methods with a combination of the group name and column name.
The GetAttributeExists method will return rf:ok if the attribute exists, and rf:notok if it does not.

x = reflection.GetAttributeExists('homequeue','photo','binary')

If the attribute has a value (in other words it is of the form attribute(value) ) then use the GetAttributeValue method and the value will be returned.

s = reflection.GetAttributeValue('homequeue','pets','rowname')

You can specifically set an attribute using the SetAttribute method for a field in code - in other words supplementing the attributes in the declaration;

reflection.SetAttribute('homequeue','pets','req')

While most attributes can be accessed via the GetAttribute and SetAttribute methods, some attributes cannot, and are more easily obtained via specialized methods. These attributes are the PICTURE, TYPE and RENAME attributes. they are accessed using the GetPicture, GetType and GetRename methods.

p = reflection.GetPicture('homequeue','date')
t = reflection.GetType('homequeue','date')
r = reflection.GetRename('homequeue','pets')


These are matched with SetPicture, SetType and SetRename.

Helper Methods

A number of Helper methods are provided for working with complex structures. While these are not specifically part of reflection, they support using the complex structures that reflection encourages.

DisposeGroup and DisposeQueue dispose the contents of these structures, in a way that does not leak memory. Using reflection, and extended attributes, they free queues-in-queues as well as &string, &cstring, &pString, &stringtheory fields. (They do not need to Parse structures before use, so can be used in cases even where the ReflectClass is not being used.)

reflection   ReflectClass

code
  reflection.Dispose(whateverQueue)


ClearTable is similar to Clarion's Clear(Table) except that it clears BLOB and MEMO fields as well.

reflection   ReflectClass

code
  reflection.ClearTable(Customers)


ClearGroup is similar to Clarion's Clear(Group) however nested Queues and StringTheory objects are freed.

Assigning Methods

Importing data into complex structures (ie structures with references) can be complicated. The ReflectClass provides a number of methods for making this easier.

AssignStringPtr, AssignCStringPtr, AssignPStringPtr, AssignStringTheoryPtr allows values to be assigned into a structure, where the destination field is a &String, &Cstring, &Pstring or &StringTheory respectively. If the value is null it will be NEW'd. If the allocated space is too small, it will be enlarged.

Debugging Methods

Two debugging methods exist;

Trace allows you to send strings to DebugView.

Walk allows you to send the current contents of the GroupsQueue and FieldsQueue properties to Debugview.

Hint: The Name attribute is limited to 100 characters long by the Clarion language.

WHO Versus Prop:Name

There are fundamentally two ways to get the external field name for a field. The first is using the WHO function, and the second is using the Field{prop:Name} syntax. At first glance these appear to both return the same thing, but actually there is a slight difference between the two.

The WHO value is set when the program is compiled, and it cannot be changed at run time. It is Read-Only, and will not change during the life of the program.

The Prop:Name value is read/write. It can be written to at run time.

The Reflection class uses the WHO approach to parse the table, so the attributes there are fixed and are not writable. However additional attributes can be added to a structure using any of the SET methods.

Hint: The Name attribute is limited to 100 characters long by the Clarion language.

Creating Tables

The Clarion CREATE command has a bug (PTSS #43215) where field names in the table are created WITH with extended attributes as part of the name. However it uses the prop:name approach when determining the name.

For this reason the ReflectClass includes a method, FixCreate, for removing the extended properties from the prop:name, and leaving them in the WHO value. Libraries are thus encouraged to use WHO when parsing external properties directly.

The FixCreate method only changes the Table structure on the current thread. It does not change the prop:name for the table running on other threads.

Blobs and Memos

Blobs and Memos do not work with the WHO command. But they also do not use the External Name Attribute at all when creating tables. So The FixCreate method does not need to adjust the prop:name.

When parsing Memos and Blobs, the ReflectClass uses the prop:name and not WHO.

Supported Field Types

These are the Type attributes which are supported by the ReflectClass engine. Not all of these attributes will be applicable to, or supported by, libraries using the ReflectClass. Consult the library documentation to determine which attributes are supported. In some cases there are multiple attributes for the same equate to allow for programming naming preferences.

Attribute Equate Description
& , &*
See Reference
Any rf:Any Field is an ANY field.
BFloat4 rf:Bfloat4 Contains a Clarion BFloat4
BFloat8 rf:BFloat8 Contains a Clarion BFloat8
Bool, Boolean rf:Boolean
Contains either True or False or 1 or 0.
Byte rf:Byte Contains a Clarion byte field, which can contain a number from 0 to 255.
CString rf:Cstring Field is a CString
&Cstring, CStringPtr rf:CStringPtr Field is a reference to a Cstring
CStringJson rf:CstringJson String contains valid JSON text.
CStringXml rf:CStringXml String contains valid XML text.
CStringJsonPtr rf:CStringJsonPtr Field contains a reference to a cstring, which contains valid JSON text.
CStringXmlPtr rf:CStringXmlPtr Field contains a reference to a cstring, which contains valid XML text.
Decimal rf:Decimal Field contains a decimal
DWord
See ULong
File, &File, Table, &Table rf:Table
Field is a reference to a FILE structure.
Float
See Real
Group rf:Group
Field is a Group structure.
JsonClass, &JsonClass rf:JsonClass Field is a reference to a JSONClass object
Key rf:key Field is a reference to a KEY structure
Long rf:Long Contains a Clarion LONG which can contain a signed 32 bit number.
Numeric rf:Numeric Contains a number
Object rf:Object Contains a reference to an object.
Pointer
See Reference
PDecimal rf:PDecimal Field contains a PDecimal
PString rf:PString Field is a PString
&PString, PStringPtr rf:PStringPtr Field is a reference to a PString
Queue, &Queue rf:Queue
Field contains a reference to a Queue structure.
Real rf:Real Contains a Clarion REAL which can contain a signed 32 bit number.
Reference rf:Reference
Field contains a reference to an unspecified data type.
Report rf:Report Field contains a reference to a report structure.
Short rf:Short Contains a Clarion SHORT which can contain a signed 16 bit number.
Signed
See Long
String rf:String Field is a String
&String, StringPtr rf:StringPtr
Field contains a reference to a string.
StringJson rf:StringJson
String contains valid JSON text.
&StringJson rf:StringJsonPtr
Field contains a reference to a string, which contains valid JSON text.
StringXML rf:StringXML
String contains valid XML text.
&StringXML rf:StringXMLPtr
Field contains a reference to a string, which contains valid XML text.
StringTheory, &StringTheory rf:StringTheory
Field contains a reference to a StringTheory object
StringTheoryJson, &StringTheoryJson rf:StringTheoryJson Field contains a reference to a StringTheory object, which contains valid JSON text.
StringTheoryXML, &StringTheoryXML rf:StringTheoryXML Field contains a reference to a StringTheory object, which contains valid XML text.
Table, &Table
See File
ULong rf:Ulong Contains a Clarion ULONG which can contain an unsigned 32 bit number.
Unsigned rf:Unsigned See Long
UShort rf:Ushort Contains a Clarion USHORT which can contain an unsigned 16 bit number.
View, &View rf:View
Field is a reference to a VIEW structure.
Window rf:Window Field is a reference to a WINDOW structure
Word
See UShort
xmlTreeClass, &xmlTreeClass rf:XmlTreeClass Field is a reference to an XMLTreeClass object

Examples


Template Reference

Global Extension

This template activates the reflection class in the application.

General Tab

Disable All Reflection Features
If this is ticked on then the template does nothing.

Options Tab

Call FixCreate for ISAM
If this is ticked on then the FixCreate method will be called for ISAM tables in the ABC FileManager class, PreCreate method. This means the extended attributes will automatically be removed from ISAM driver files before the call to CREATE. See Creating Tables.
Call FixCreate for SQL
If this is ticked on then the FixCreate method will be called for SQL tables in the ABC FileManager class, PreCreate method. This means the extended attributes will automatically be removed from SQL driver files before the call to CREATE. See Creating Tables.

Multi-DLL Tab

This is part of a Multi-DLL program
Tick this on if this app is part of a multiple-app system. This is turned on for all the DLL's and the EXE's.
Export Reflection Class from this DLL
Tick this on in the app which will export the class. This is almost always the Data DLL app. In all other apps, DLLs and EXE's, leave this off.

Classes Tab

Class Version
The last date when the class was parsed from the LibSrc folder. Used internally. Do not change.

Class Reference


Types

ReflectionGroupQueueType
Field Type Description
GroupName Cstring(rf:StringLen)
ReflectionFieldQueueType
Field Type Description
GroupName Cstring(rf:StringLen)
ColumnName Cstring(rf:StringLen) Clarion name for field - ie 1st part of external name. If missing label is used.
FieldNumber Long
Attributes &StringTheory
LowerAttributes &StringTheory
Description &StringTheory
Rename Cstring(rf:StringLen) Contents of rename attribute
Picture Cstring(64) Attribute starting with @
Type Long
GroupReference &Group
Size Long Only populated for String, Pstring Cstring, Group
Array Long Number of items in the array

Properties

Property Type Description
Tag String This is used to specify the specific external name attribute to use as the rename attribute. See The Naming of Things for more information on using this property.
TagCase Byte Specifies the case to use for the structure names. Set to rf:CaseAsIs by default, which uses the name exactly as it appears in the Name attribute or the LABEL (which is always upper case) if the name is not set.
GroupsQueue ReflectionGroupQueueType A list of all the groupnames currently parsed. Groups are only parsed once (to allow reparsing call the START method.)
FieldsQueue ReflectionFieldQueueType A list of all the fields, in all the groups, that have been parsed, and all their associated attributes.


Properties used by AdjustColumnName
MaxPrefixLength Byte The maximum length of the prefix in the structure (including the colon). PrefixChars in the string after this length will not be treated as prefix separators.
PrefixChars
cString(4) The character (or characters) which separate the prefix from the column name. This is usually a colon ( : ) but in web applications may be an underscore ( _ ).
RemovePrefix
Byte If this is set to true, then prefixes will be removed from the name.
ReplaceChars
Byte
If this is set to true, then any PrefixChars in the name are replaced with ReplacementChars.
ReplacementChars cString(4) Replaces any Prefix chars in the string, if the ReplaceChars property is true.

Methods

Classes

AdjustColumnName

AdjustColumnName(String pColumnName, Long pTagCase)
AdjustColumnName(StringTheory pColumnName, Long pTagCase)

Description

A worker method. This method takes in a name, possibly containing a prefix, and returns the name without the prefix. The case of the name may also be changed, based on the contents of the pTagCase parameter.

Parameters

Parameter Description
pColumnName A string containing a field name. If the fieldname contains a pipe character (|) then that character, and everything after that character are removed
pTagCase One of rf:CaseUpper, rf:CaseLower or rf:CaseAsIs.

Return Value

The adjusted name. If the StringTheory form of the procedure is called then nothing is returned, but the pColumnName parameter is changed.

Example

reflection.AdjustColumnName(str,rf:CaseLower)

See Also

 

Classes

AssignStringPtr

AssignStringPtr(*? pField,String pValue)
AssignCStringPtr(*? pField,String pValue)
AssignPStringPtr(*? pField,String pValue)
AssignStringtheoryPtr(*? pField,String pValue)

AssignStringPtr(*? pField,StringTheory pValue)
AssignCStringPtr(*? pField,StringTheory pValue)
AssignPStringPtr(*? pField,StringTheory pValue)
AssignStringtheoryPtr(*? pField,StringTheory pValue)


Description

Helper functions. These assist with assigning a value to a field in a structure, where that field is a pointer to a string or stringtheory type.
Typically the first parameter is an ANY field, which is set using a call to WHAT, and you want to assign something into that field.

Parameters

Parameter Description
pField An ANY reference to the field to be set. This field is of the appropriate pointer type (as specified in the method name).
If the field is currently NULL, then a new value will be created.
pValue The value to assign into the field.

Return Value

Nothing

Example



See Also

ReadStringPtr / ReadCStringPtr / ReadPStringPtr / ReadStringTheoryPtr

Classes

CleanFieldName

CleanFieldName(*StringTheory pFieldName)

Description

Takes in a StringTheory object containing an Extended Name , and removes everything from the first pipe onwards. If the name contains a prefix (designated by a :) then it is removed.

Parameters

Parameter Description
pFieldName The extended name of a field, as might be returned by the WHO command.

Return Value

Nothing. The passed StringTheory object is adjusted to contain the clean field name, without the attributes or prefix.

Example

reflection.CleanFieldName(str)

See Also

GetField, GetFieldName, GetFieldNumber, GetFieldValue

Classes

ClearAttribute

ClearAttribute(*Cstring pGroupName, String pAttribute)

Description

Deletes an attribute from all fields in the group.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pAttribute The name of the attribute to delete.

Return Value

Nothing

Example

reflection.ClearAttribute(GroupName,'private')

See Also

SetAttribute, GetAttributeExists, GetAttributeValue, DeleteAttribute, SetAttributes , ClearAttribute .

Classes

ClearGroup

ClearGroup(*Cstring pGroupName, *Group pGroup)
ClearGroup(*Group pGroup)

Description

Clears all the fields in a group structure. Pointer fields are NOT cleared. StringTheory Objects are FREE'd. Queue References are FREE'd. Pointers to strings are set back to blank strings. This method can only be used after the Group structure has been parsed.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pGroup The group structure.

Return Value

Nothing

Example

reflection.ClearGroup(GroupName,TaxGroup)

See Also

DisposeGroup, DisposeQueue, ClearGroup, ClearQueue, ClearTable, Parse .

Classes

ClearQueue

ClearQueue(*Cstring pGroupName, *Queue pQueue)
ClearQueue(*Queue pQueue)

Description

Clears all the fields in a queue structure.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pQueue The Queue structure

Return Value

Nothing

Example

reflection.ClearQueue(GroupName,PetsQueue)

See Also

DisposeGroup, DisposeQueue, ClearGroup, ClearQueue, ClearTable, Parse .

Classes

ClearTable

ClearTable(*Cstring pGroupName, *FILE pTable)

Description

Clears the record buffer for the table. If the table is OPEN then any MEMO and BLOB fields are cleared as well.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pTable The table to be cleared.

Return Value

Nothing

Example

reflection.ClearTable(GrouName,Customers)

See Also

DisposeGroup, DisposeQueue, ClearGroup, ClearQueue, ClearTable, Parse .

Classes

CountFieldsInGroup

CountFieldsInGroup(*Group pGroup)

Description

Counts the number of fields inside a GROUP structure.

Parameters

Parameter Description
pGroup The group to count the fields in.

Return Value

Long. The number of fields in a group

Example

ax = reflection.CountFieldsInGroup(Cus:Record)

See Also



Classes

DeleteAttribute

DeleteAttribute(*Cstring pGroupName,*Cstring pColumnName, String pAttribute)

Description

Deletes an attribute from a field.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pAttribute The name of the attribute to delete.

Return Value

Nothing

Example

reflection.DeleteAttribute(GroupName,ColumnName,'binary')
reflection.DeleteAttribute(GroupName,ColumnName,'rename')

See Also

SetAttribute, GetAttributeExists, GetAttributeValue, DeleteAttribute, SetAttributes , ClearAttribute .

Classes

DisposeGroup

DisposeGroup(*Group pGroup,Long pDispose=false)

Description

Checks a group for any string pointer, stringtheory, queue fields and follows any queue references, freeing memory as needed.

Parameters

Parameter Description
pGroup The group to check.
pDispose Set to true if the passed in Group should be disposed as well. False by default.

Return Value

Nothing

Example

reflection.DisposeGroup(PetsGroup)

See Also

DisposeGroup, DisposeQueue, ClearGroup, ClearQueue, ClearTable .

Classes

DisposeQueue

DisposeQueue(*Queue pQueue,Long pDispose=false)

Description

Checks a queue for any string pointer, StringTheory, queue fields and follows any queue references, freeing memory as needed. The Queue is FREE'd and (optionally) disposed as well.

Parameters

Parameter Description
pQueue The queue to dispose
pDispose Set to true if the passed in queue should be disposed as well. False by default.

Return Value

Nothing

Example

reflection.DisposeQueue(PetsQueue)

See Also

DisposeGroup, DisposeQueue, ClearGroup, ClearQueue, ClearTable .

Classes

FixCreate

FixCreate(*File pTable)

Description

Removes any ExternalNameAttributes from the prop:name of each field in a table. This should be called before calling the CREATE statement on a table. This only affects the prop:name of each field, not the WHO of the field, so parsing the structure is unaffected by this call.

Only the table structure on this thread is altered - the table structure on other threads is not altered.

Parameters

Parameter Description
pTable the table to adjust, before calling Create.

Return Value

Nothing

Example

reflection.FixCreate(Customers)

See Also



Classes

GetAnySize

GetAnySize(*? pField )

Description

Uses the (undocumented) TUFO interface to get the size of a field.

Parameters

Parameter Description
pField Any field

Return Value

The SIZE of the field.

Example

l = reflection.GetAnySize(someString)

See Also

GetAnyType

Classes

GetAnyType

GetAnyType(*? pField )

Description

Uses the (undocumented) TUFO interface to get the type of a field.

Parameters

Parameter Description
pField Any field

Return Value

The rf:whatever type equate for the field.

Example

t = reflection.GetAnyType(someField)

See Also

GetAnySize .

Classes

GetArray

GetArray(*Cstring pGroupName,*Cstring pColumnName)

Description

Returns the number of array elements in the field. Default is 1 for fields which are not arrays.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

The method returns a LONG containing the number of array elements.

Example

If reflection.GetArray(groupname,columnname) > 1
  ! field is an array
End

See Also

GetField, GetFieldValue , GetArray.

Classes

GetAttributeExists

GetAttributeExists(*Cstring pGroupName,*Cstring pColumnName, String pAttribute)
GetAttributeExists(String pAttribute)

Description

Checks to see if an attribute exists for the column. Use the short form only when the queues are already loaded with With.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pAttribute The name of the attribute to get.

Return Value

The method returns rf:ok if the attribute exists or rf:notok if it does not exist.

Example

If reflection.GetAttributeExists(groupname,columnname,'binary') = rf:ok
  ! do something
End

See Also

SetAttribute, GetAttributeValue, DeleteAttribute, SetAttributes .

Classes

GetAttributeValue

GetAttributeValue(*Cstring pGroupName,*Cstring pColumnName, String pAttribute)

Description

Adds

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pAttribute The name of the attribute to get.

Return Value

If the attribute is a simple one then the method returns rf:ok if the attribute exists or rf:notok if it does not exist. If the attribute is of the form attribute(value) then the value is returned as a string.

Example

If reflection.GetAttribute(groupname,columnname,'binary') = rf:ok
! do something
End

See Also

SetAttribute, GetAttributeExists, DeleteAttribute, SetAttributes .

Classes

GetColumnName [1]

GetColumnName(*Group pGroup,Long pIndex)
GetColumnName(*Queue pQueue,Long pIndex)
GetColumnName(*Table pTable,Long pIndex)

Description

Gets the column name for a field at a specific place in the structure. Useful for all the methods that take a group name, and a column name.

Parameters

Parameter Description
pGroup
pQueue
pTable
The structure to reflect.
pIndex The number of the field inside that structure. (This is not necessarily the same number returned by GetNumber)

Return Value

A string containing the column name of that field.

Example

columnName = reflection.GetColumnName(Customers,3)

See Also

GetColumnName [2] .

Classes

GetColumnName [2]

GetColumnName(*Cstring pGroupName,*Cstring pTagName)

Description

Returns the ColumnName of the structure, based on the Rename attribute (which matches the tagname in the external structure, xml, json, etc.)

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pTagName The external tagname, as specified in the rename() or specific rename attribute. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

The column name of the field. This name can then be used in all the other methods that take a group name and a column name.

Example



See Also

GetColumnName [1] .

Classes

GetDescription

GetDescription(*Cstring pGroupName,*Cstring pColumnName)

Description

Gets the description value for a field.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

The contents of the field's description, as set by an earlier call to SetDescription.

Example


See Also

GetField, GetFieldName, GetFieldNumber, GetFieldValue , SetDescription .

Classes

GetField

GetField(Group pGroup,String pColumnName, <Long pIndex>)

Description

A utility method for making it easier to write code against generic structures. Returns an ANY variable which points to the specific field as named. Does not reference the parsed group list, so can be called without parsing.

Parameters

Parameter Description
pGroup A Group, or Queue structure.
pColumnName The name of the column.
pIndex If the field is an array then specifies which element in the array to get. If omitted the default value is 1. If the pIndex is larger than the items in the array then a null is returned.

Return Value

An ANY Long containing a pointer to the field. May be NULL.

Example

color  Group
red      byte
green    byte
blue     byte
       End

a  ANY
  code
  a &= reflection.GetField(color,'green')

See Also

GetField, GetFieldName, GetFieldNumber, GetFieldValue , GetArray.

Classes

GetFieldName

GetFieldName(Group pGroup,Long pFieldNumber, Long pCase=self.TagCase)

Description

A utility method for making it easier to write code against generic structures. Returns the clean name of the field. This is the name before the first pipe symbol, and with the prefix removed. The case is adjusted using the pCase parameter. Does not reference the parsed group list, so can be called without parsing.

Parameters

Parameter Description
pGroup A Group, or Queue structure.
pFieldNumber The number of the field inside the group.
pCase One of rf:CaseAsIs, rf:CaseUpper, rf:CaseLower, rf:CaseAny. If omitted then the current value in the TagCase property is used.

Return Value

A String containing the clean name.

Example


color  Group
red      byte
green    byte,name('Green | @n3)
blue     byte
       End
s      String(100)
  code
  s = relection.GetFieldName(color,2)
! returns Green

See Also

GetField, GetFieldName, GetFieldNumber, GetFieldValue , SetTagCase, CleanFieldName

Classes

GetFieldNumber

GetFieldNumber(Group pGroup,String pColumnName)

Description

A utility method for making it easier to write code against generic structures. Returns a LONG variable which points to the specific field as named. Does not reference the parsed group list, so can be called without parsing.

Parameters

Parameter Description
pGroup A Group, or Queue structure.
pColumnName The name of the column.This parameter is case insensitive.

Return Value

A Long containing the number of the field inside the group.

Example

color  Group
red      byte
green    byte
blue     byte
       End
x      Long
  code
  x = relection.GetFieldNumber(color,'Green')
! returns 2

See Also

GetField, GetFieldName, GetFieldNumber, GetFieldValue .

Classes

GetFieldValue

GetFieldValue(Group pGroup,String pColumnName, <Long pIndex>)

Description

A utility method for making it easier to write code against generic structures. Returns a clipped string containing the value of the field in the group. Does not reference the parsed group list, so can be called without parsing.

Parameters

Parameter Description
pGroup A Group, or Queue structure.
pColumnName The name of the column.
pIndex If the field is an array then specifies which element in the array to get. If omitted the default value is 1. If the pIndex is larger than the items in the array then a blank string is returned.

Return Value

An ANY Long containing a pointer to the field. May be NULL.

Example


color  Group
red      byte
green    byte
blue     byte
       End
x      byte
  code
  color.green = 100
  x = relection.GetFieldValue(color,'Green')
! returns 100

See Also

GetField, GetFieldName, GetFieldNumber, GetFieldValue , GetArray .

Classes

GetNumber

GetNumber(*Cstring pGroupName,*Cstring pColumnName)

Description

Returns the FieldNumber for a column. This is nominally the location of the field in the structure (although technically it could be any number.) This works on the FieldsQueue, so relies on the structure already being PARSEd.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

A Long containing the field number.

Example

x = relection.GetNumber(GroupName,ColumnName)

See Also

GetNumber, SetNumber, GetColumnName, Parse

Classes

GetPicture

GetPicture(*Cstring pGroupName,*Cstring pColumnName)

Description

Gets the picture attribute for a column.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

A string containing the picture attribute for the field. If no picture attribute is set, then a blank string is returned.

Example

pic = reflection.GetPicture(GroupName,ColumnName)

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType .

Classes

GetRename

GetRename(*Cstring pGroupName,*Cstring pColumnName)

Description

Returns the Rename attribute for a field. If the Tag property is set when the structure is parsed, then this returns the contents of the tag property. If that is not set then it returns the rename property.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

A string containing the <tag> attribute or the rename attribute.

Example

s = reflection.GetRename(groupname,columnname)

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType, The Naming of Things .

Classes

GetTagCase

GetTagCase()

Description

Gets the value of the TagCase property. The default value for the property is rf:CaseAsIs

Return Value

A BYTE equate. One of rf:CaseAsIs, rf:CaseUpper, rf:CaseLower, rf:CaseAny.


Example

x = reflection.GetTagCase()

See Also

SetTagCase

Classes

GetType

GetType(*Cstring pGroupName,*Cstring pColumnName)

Description

Gets the field type (as set in the extended attributes).


Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the column. This has to be set in a CSTRING variable, and passed as a CSTRING variable.

Return Value

A LONG equate. See Supported Field Types.


Example

x = reflection.GetType(GroupName,ColumnName)

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType, Supported Field Types .

Classes

Parse

Parse(String pGroupName, *Group pGroup)
Parse(*Group pGroup)

Parse(String pGroupName,*Queue pQueue)
Parse(*Queue pQueue)

Parse(String pGroupName,*File pTable)
Parse(*File pTable)

Parse(String pGroupName,*View pView)
Parse(*View pView)


Description

Parses a structure.

Parameters

Parameter Description
pGroupName A string name which identifies the structure. This will be used when querying the object. If this parameter is omitted then the name will be set to group, queue, file, and view respectively. 
pGroup, pQueue, pTable, pView The Structure which will be parsed.

Notes

This parses all the extended attributes for the structure.

Additional attributes, or changing an attribute, can be done after calling Parse by using one of the SET methods.

The values of one or more attributes can be obtained using the GET methods.


Return Value

Nothing

Example

reflection.parse('customers',CustomersTable)

See Also



Classes

ParseField

ParseField(*Cstring pGroupName,StringTheory pExternalName)

Description

Takes in a single field, and a set of attributes. Parses them as-if the field was in a group, and the attributes were attached to the field. Useful for dealing with stand-alone fields.


Parameters

Parameter Description
pGroupName A collective name for the single fields.
pExternalName A pipe-delimited string containing the attributes for the field.

Return Value

A String containing the column name. (The Column name being extracted from the pExternalName.)


Example

  tag = reflection.ParseField('singles','Date | @d6')

See Also

  .

Classes

ReadStringPtr

ReadStringPtr(*? pField)
ReadCStringPtr(*? pField)
ReadPStringPtr(*? pField)
ReadStringTheoryPtr(*? pField)

Description

Helper functions. These assist with reading the value in a field in a structure, where that field is a pointer to a string or stringtheory type.
Typically the first parameter is an ANY field, which is set using a call to WHAT, and you want to assign something into that field.

Parameters

Parameter Description
pField An ANY reference to the field to be read. This field is of the appropriate pointer type (as specified in the method name). If the pointer is null, then a blank string is returned.

Return Value

A string containing the value.

Example



See Also

AssignStringPtr / AssignCStringPtr / AssignPStringPtr / AssignStringTheoryPtr , ReadStringPtr / ReadCStringPtr / ReadPStringPtr / ReadStringTheoryPtr .

Classes

ReadStringPtrLength

ReadStringPtrLength(*? pField)
ReadCStringPtrLength(*? pField)
ReadPStringPtrLength(*? pField)
ReadStringTheoryPtrLength(*? pField)

Description

Helper functions. These assist with reading the length of a field in a structure, where that field is a pointer to a string or stringtheory type.
Typically the first parameter is an ANY field, which is set using a call to WHAT, and you want to assign something into that field.

Parameters

Parameter Description
pField An ANY reference to the field to be read. This field is of the appropriate pointer type (as specified in the method name). If the pointer is null, then a length of 0 is returned.

Return Value

A long containing the length of the string (in bytes, not characters).

Example



See Also

AssignStringPtr / AssignCStringPtr / AssignPStringPtr / AssignStringTheoryPtr, ReadStringPtr / ReadCStringPtr / ReadPStringPtr /ReadStringTheoryPtr .

Classes

SetAttributes

SetAttributes(*Cstring pGroupName,*Cstring pColumnName, StringTheory pExternalName)
SetAttributes(String pGroupName,String pColumnName, String pExternalName)

Description

Takes a pipe-separated string (as returned by the WHO command) and parses out all the attributes in the string, setting them for the column.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure.
pColumnName The name of the field.
pExternalName A pipe-delimited string of attributes - as might be returned by the WHO command, or as might be set in the program code.

Return Value

Nothing

Example

str.SetValue('somename | @D6')
reflection.SetAttributes(GroupName,ColumnName,str)

See Also

SetAttribute, GetAttributeExists, GetAttributeValue, DeleteAttribute, SetAttributes .

Classes

SetAttribute

SetAttribute(*Cstring pGroupName,*Cstring pColumnName, String pAttribute)
SetAttribute(String pGroupName,String pColumnName, String pAttribute)

Description

Sets an attribute for a column. Using this method directly allows attributes to be added for fields in structures, where they can't be added to the structure directly as an extended name attribute. It also allows for an extended name attribute to be overridden.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure.
pColumnName The name of the field.
pAttribute The name of the attribute. If the attribute is of the form attribute(value) then include the value, and brackets, in this parameter.

Return Value

Nothing

Example

reflection.setAttribute(GroupName,ColumnName,'binary')
reflection.setAttribute(GroupName,ColumnName,'xmlname(paid)')

See Also

SetAttribute, GetAttributeExists, GetAttributeValue, DeleteAttribute, SetAttributes .

Classes

SetDescription

SetDescription(*Cstring pGroupName,*Cstring pColumnName, String pDescription)
SetDescription(String pGroupName,String pColumnName, String pDescription)

Description

Sets the description for a specific column.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure.
pColumnName The name of the field.
pDescription A description to use for the column.

Return Value

Nothing

Example

reflection.SetPicture(GroupName,ColumnName,'@d6')

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType , GetDescription.

Classes

SetNumber

SetNumber(*Cstring pGroupName,*Cstring pColumnName, Long pColumnNumber)

Description

Sets the number for a specific column. This is usually the position of the field in the structure, but this method could be used to override that number. However this is not recommended.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the field. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnNumber A number to use for the column.

Return Value

Nothing

Example

reflection.SetNumber(GroupName,ColumnName,14)

See Also

GetNumber, SetNumber .

Classes

SetPicture

SetPicture(*Cstring pGroupName,*Cstring pColumnName, String pPicture)
SetPicture(String pGroupName,String pColumnName, String pPicture)

Description

Sets the picture for a specific column.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure.
pColumnName The name of the field.
pPicture A format picture to use for the column.

Return Value

Nothing

Example

reflection.SetPicture(GroupName,ColumnName,'@d6')

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType .

Classes

SetRename

SetRename(*Cstring pGroupName,*Cstring pColumnName, String pRename)

Description

Sets the Rename attribute for a specific column.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the field. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pRename The value to use for the Rename attribute of the field.

Return Value

Nothing

Example

reflection.SetRename(GroupName,ColumnName,'happy')

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType .

Classes

SetTagCase

SetTagCase(Byte pCase)

Description

Sets the TagCase for the object.

Parameters

Parameter Description
pCase One of rf:CaseAsIs, rf:CaseUpper, rf:CaseLower, rf:CaseAny. The default value is rf:CaseAsIs.

Return Value

Nothing

Example

reflection.SetTagCase(rf:CaseLower)

See Also

GetTagCase.

Classes

SetType

SetType(*Cstring pGroupName,*Cstring pColumnName, Long pFieldType)
SetType(String pGroupName,String pColumnName, Long pFieldType)

Description

Sets the specific Type attribute for a column.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the field. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pFieldType An equate, taken from the list of Supported Field Types which best describes the field.

Return Value

Nothing

Example

reflection.SetType(GroupName,ColumnName,rf:stringtheory)

See Also

GetPicture, GetRename, GetType, SetPicture, SetRename, SetType, Supported Field Types .

Classes

Start

Start()

Description

Returns the object to a virgin state, as if it has never been used.


Return Value

Nothing

Example

reflection.start()

See Also



Classes

TableFieldToColumn

TableFieldToColumn(FILE pTable,String pLabel )

Description

Given a table label (including prefix), returns the Column name for that field.

Parameters

Parameter Description
pTable The Table
pLabel The label of a field in the table (including prefix)

Return Value

String containing the column name (as set by the external name.) If not set then the label, (possibly minus the prefix, if RemovePrefix is set, and adjusted to the TagCase) is returned.

Example

Column = reflection.TableFieldToColumn(Customers,'cus:Name') ! returns say, Name

See Also

  .

Classes

Trace

Trace(string pStr)

Description

Sends a string to the Windows Debug Output, where it can be monitored using Debugview. Useful when debugging the class.

Parameters

Parameter Description
pStr The String to send to Debugview. The string will be prepended with the identifier [guts]

Return Value

None

Example

Self.Trace('Hello World')

See Also

Walk .
Classes

Walk

Walk()

Description

A debugging method which sends the contents of the GroupsQueue and FieldsQueue properties to debugview. This can be helpful in understanding what the parser discovered when it parsed a structure, and will also help to identify specific group names and column names.

Return Value

Nothing. Output is to Debugview.

Example

reflection.walk()

See Also

Trace

Classes

With

With(*Cstring pGroupName,*Cstring pColumnName, Long pCreate=true)
With(*Cstring pGroupName)

Description

Long form fetches a row from the FieldsQueue property, which matches the GroupName and ColumnName. (Does not load the GroupsQueue property.)
Short form fetches a row from the GroupsQueue property which matches the GroupName.

Parameters

Parameter Description
pGroupName The GroupName parameter as previously passed to the Parse procedure. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pColumnName The name of the field. This has to be set in a CSTRING variable, and passed as a CSTRING variable.
pCreate If the record is not found, and this field is set to true (the default) then the row is added to the FieldsQueue.

Return Value

rf:ok if the row is found, rf:notok if it is not.

Example

reflection.With(GroupName,ColumnName)

See Also



Version History

1.30 - 14 October 2024
1.29 - 4 July 2024
1.28 - 8 April 2024
1.27 - 7 November 2023
1.26 - 25 October 2023
1.25 - 10 August 2023
1.24 - 20 September 2023
1.23 - 26 July 2023
1.22 - 26 June 2023
1.21 - 19 June 2023
1.20 - 31 May 2023
1.19 - 23 May 2023
1.18 - 5 April 2023
1.17 - 20 February 2022
1.16 - 27 January 2022
1.15 - 26 January 2022
1.14 - 3 October 2022
1.13 - 17 September 2022
1.12 - 6 September 2022
1.11 - 22 August 2022
1.10 - 16 August 2022
1.02 - 19 November 2021
1.01 - 15 November 2021
1.00 - 5 November 2021