TEXT
The TEXT
data type stores large text data.
Syntax
TEXT
Usage
A BYTE
or TEXT
variable is a handle for a large object (LOB),
that is stored in a file or in memory. Such data type is a complex type that cannot be used like
INTEGER
or CHAR
basic types: It is designed to handle a large
amount of data and has different semantics as simple types. The main difference with simple data
types, is the fact that you must specify the storage with the LOCATE
instruction, before using
BYTE
and TEXT
variables.
The maximum size of data that can be handled by BYTE
and TEXT
variable is theoretically 2^31 bytes (~2.14 Gigabytes), but the practical limit depends on the disk
or memory resources available to the process.
BYTE
and TEXT
variable must be initialized with the
LOCATE
instruction before usage.
APIs such as the util.JSON
class will automatically allocate
TEXT
/BYTE
variables in memory if these are not located, when
converting a JSON string to an FGL variable with the util.JSON.parse()
method.
LOCATE
instruction basically defines where the large data object has to be
stored (in a named file, in a temporary file, or in memory). This instruction will actually allow
you to fetch a LOB into memory or into a file, or insert a LOB from memory or from a file into the
database. When located in a temporary file (IN FILE
), the temp directory can be
defined by the DBTEMP environment
variable.DEFINE t TEXT
LET t = "aaaa" -- invalid, t is not located
LOCATE t IN MEMORY
LET t = "aaaa" -- valid, now t is located in memory
TEXT
/BYTE
variables are not comparable: Comparing
TEXT
/BYTE
variable does not result in an error, but the result of
the comparison operator will always be NULL
, which is equivalent to
FALSE
in an IF
statement:DEFINE t1, t2 TEXT
IF t1 == t2 THEN -- Always NULL/FALSE
...
END IF
BYTE
and TEXT
types, you can insert/update/fetch large
objects of the database. The native database type to be used depends on the type of database server.
After defining the storage with LOCATE
, load / assign its value, and then you can
use it directly in the SQL statements, or fetch data from LOB columns of the database, like simple
data
types:DEFINE t1, t2 TEXT
...
CREATE TABLE mytable ( id INT, data TEXT )
...
LOCATE t1 IN MEMORY
CALL t1.readFile("lob.4gl")
INSERT INTO mytable VALUES ( 1, t1 )
LOCATE t2 IN FILE
SELECT data INTO t2 FROM mytable WHERE id=1
...
BYTE
and TEXT
types implement the readFile()
and writeFile()
methods to read/write the whole large object data from/to files.
These methods can be used to easily interface with other software
components:DEFINE t TEXT
LOCATE t IN MEMORY
CALL t.readFile("orig.txt")
CALL t.writeFile("copy.txt")
For more details about LOB types methods, see BYTE data type as class and TEXT data type as class.
BYTE
or TEXT
variable to
NULL
(INITIALIZE var TO NULL
), if the variable
is located in a file, the file is truncated (file size will be zero). If the variable is located in
memory, the data in memory will be truncated. A subsequent usage of the variable (for example,
FETCH INTO
or LET
assignment) is still
possible:DEFINE b BYTE
LOCATE b IN FILE "picture.png"
INITIALIZE b TO NULL
-- The file "picture.png" is now empty.
Resources allocated to a BYTE
or TEXT
variable can be
deallocated with the FREE
instruction.
When the TEXT
or BYTE
variable is already
located, a new LOCATE
will free the allocated resource: If the prior
LOCATE
was using the IN FILE
clause, the temporary file is
dropped, if the prior LOCATE
was using IN MEMORY
, the memory is
freed.
FREE
will remove the file if the LOB variable is located in a (named or
temporary) file. When located in memory, the FREE
instruction will deallocate the
memory. After freeing the resources of a LOB variable, it must be re-located with a
LOCATE
instruction:DEFINE b BYTE
LOCATE b IN FILE
CALL b.readFile("picture.png") -- ok
FREE b
CALL b.readFile("picture.png") -- Invalid, b is not located.
LOCATE b IN MEMORY
CALL b.readFile("picture.png") -- ok
TEXT
and BYTE
are reference types. This implies that assigning
two variables (LET
, passing a variable as parameter to a function, returning a
result from a function) does not copy the value (Only the handle is copied. As a result, modifying
the data with a TEXT
/BYTE
variable assigned from another
TEXT
/BYTE
variable will in fact modify the same LOB data.
Furthermore, the storage resource (file or memory) that was used by the assigned variable becomes
unreferenced and is lost:DEFINE b1, b2 BYTE -- Could be TEXT: same behavior
LOCATE b1 IN FILE "mydata" -- reference file directly
LOCATE b2 IN MEMORY -- use memory instead of file
CALL b2.readFile("mydata") -- read file content into memory
# FREE b2 -- this should be done to free memory before LET
LET b2 = b1 -- Now b2 points directly to the file (like b1)
INITIALIZE b1 TO NULL -- truncates reference file
DISPLAY IIF( b2 IS NULL, "b2 is null", "b2 is not null")
-- Displays "b2 is null"
img BYTE
variable in a temporary variable (tmp
), with the typical programming pattern to
save the value before modification. In fact the LET tmp=img
assignment does not
copy the data of the LOB like for simple data types (STRING
,
VARCHAR
, DECIMAL
), only the reference (i.e. handle) to the data is
copied:-- WARNING: THIS IS AN INVALID CODE EXAMPLE
DEFINE img, tmp BYTE
LOCATE img IN MEMORY
CALL img.readFile("picture1.png")
LOCATE tmp IN MEMORY
LET tmp = img -- Expecting to save the current data, but now
-- both variables reference the same data...
CALL img.readFile("picture2.png")
LET img = tmp -- Does not restore the old value: Same data.
writeFile()
/
readFile()
methods:IMPORT os
MAIN
DEFINE src, dst BYTE, fn STRING
LOCATE src IN MEMORY
CALL src.readFile("picture1.png") -- Original image file
LOCATE dst IN MEMORY
LET fn = os.Path.makeTempName()
CALL src.writeFile(fn)
CALL dst.readFile(fn)
LET status = os.Path.delete(fn)
END MAIN
It is possible to assign TEXT
variables to/from VARCHAR
,
CHAR
and STRING
variables.