PHP: Text File Database Manual

Php Text Database API Manual

Copyright (C) 2005 by c-worker.ch

With the "Txt-Db-API" you can access normal Text Files like a SQL Database.
You don't need any special Database Software on the Webserver, yet you can still use SQL!
You can use the API to create, query, change, or delete tables, and you don't
have to bother with the Text-Files themse. Almost everthing can be done with
the included API calls.

--

Read this documents first:

Installation
Design/Structure/Understand and use the API

Since Version 0.2.2-Beta-01 the Text Db Api is under a BSD License

--

Version: 0.3.1-Beta-01
(Help Version matches API Version)

Newest PHP Version the API is compatible with: 5.0.3
Minimum required PHP version: 4.1.0 (not sure)

Latest Version and additional Infos:


Rechtliche Hinweise

Legal statement

BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THIS PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

There are still many errors in this programm and the documentation!

License:

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.


News

Changelog

Because the changelog.txt file is in english, only important changes will be written here!
See the changelog.txt file for the other changes.

New since Version 0.3.1-Beta-01

Added support for IN and NOT IN (numbers and strings)

Added support for JOINS (LEFT [OUTER], RIGHT [OUTER] and INNER)

The tbedit script (a table file editor) is now included in the releases. It can be startet by the url webgui/tbedit.php or from a link in the webgui.

Added support for COUNT(*) and COUNT(table.*) SELECT Queries

For more see changelog.txt..


Installation

Since Version 0.3.x the Text-DB-Api Zip also includes the WebGUI and a
Table Editor. To use the Text-DB-API its still sufficient to upload only the
8 main .php Files (resultset.php, database.php, etc...) and to configure the
txt-db-api.php File.
This form of installation is described below in the paragraph "Manual Installation".

Since the 0.3.x Verions you can also install and configure the API and the included
GUI's with a Wizard (installer.php). The installer.php script must be downloaded separately
from the Sourceforge Page.
To install the API this way, you have to upload the Text-DB-API Zip and the installer.php
file into the SAME directory on the webserver. Then you only have to call the isntaller.php
script and the Wizard will guide you through the installation.

Manual Installation

Upload the files:

All PHP Files ot the Txt-Db-Api must be uploaded in one directory.

Change the File txt-db-api.php

Before uploading all the .php files the file txt-db-api.php must be changed.
You have to set the two Vars $API_HOME_DIR and $DB_DIR to correct values.

$API_HOME_DIR:
This variable must be set to the absolute or relative path where all the Txt-Db-Api Files are located.
For example: /home/c-worker.ch/public_html/php-api/

$DB_DIR:
This variable must be set to the absolute or relative path where the database folders are.
For example if you have a database folder at /home/c-worker.ch/dbs/TestDB, set
$DB_DIR to /home/c-worker.ch/dbs/. Now you can have 1 or more folders in the
/home/c-worker.ch/dbs/ folder, each representing a singe database.

The file txt-db-api.php doesn't change in new versions. Don't overwritte it when you
install a new version. Just keep the old file! If this file will change, i'll put a big notice
in the changelog!

Absolute or relative Paths for API_HOME_DIR and DB_DIR

You can set the $API_HOME_DIR and $DB_DIR vars to either relative (relative to the file which
includes txt-db-api.php) or absolute (relative to the server root) paths.

If you use absolute paths, you only need one txt-db-api.php file.
This file should be placed by the other files of the Text-Db-Api (where it is by default
when the zip file is extracted).

If you use relative Paths, I REALLY RECOMMEND to let each project have its own
txt-db-api.php file. This file should be placed in the Folder of the corresponding project.
This is neccessary because differrent projects may have another relative Path to the
API and Database Directory. So each project will now include its own txt-db-api.php
File located in its folder.
In the API Folder you now, no longer need a txt-db-api.php file, sience each project has its own.

If you want, you can also let each project have its own txt-db-api.php file when using
absolute paths. This might be usefull if you want to use different Database-Roots for
each Project.


Configuration

There are some Settings in the file const.php which you can change if you wish, but you can
also leave the Default-Settings. You will find this Settings in the file const.php after the
"User Settings" Comment:

Setting | Default Value | Description
DEBUG | 0 | 0=Debug disabled, 1=Debug enabled Prints out some Debug Infos. Usefull if you have an error or would like to report a Bug.
LIKE_CASE_SENSITIVE | 0 | 0=LIKE is case insensitive, 1=LIKE is case sensitive
ORDER_CASE_SENSITIVE | 0 | 0=ORDER BY is case insensitive (a -> b -> P -> X) 1=ORDER BY is case sensitive (P -> X -> a -> b).
ASSUMED_RECORD_SIZE | 30 | Set this to the average size of one record. This constant doesn't limit the max size of a record. It's only the assmued size of a record when a table is read for appending. If not a whole record is contained in ASSUMED_RECORD_SIZE bytes, the the number of bytes read is increased until a whole record was read. Choosing this value wisely may result in a better INSERT performance. If in doubt, leave the default value!
PRINT_ERRORS | 1 | 0 = Errors are NOT displayed, 1 = Errors are displayed. Since Errors are an Error from the Developer most of the times (expect you use dynamic SQL Stataments), I recommend to set this to 1, expect you use dynamic generated SQL Strings.
PRINT_WARNINGS | 0 | 0 = Warnings are NOT displayed, 1 = Warnings are displayed.


PHP: Text File Database Manual

Security

The table files and the directories where they are stored must have appropriate permissions, so that the text-db-api can read and write to these files. This causes a side effect that these table files also can be viewed directly with the browser, IF someknow knows the location on the webserver where the reside.

To solve this problem you can place a .htacces file like this in the directory where the tables files reside:

<Files>
Order deny,allow
Deny from all
</Files>

More information about .htaccess files can be found in the internet


Using Txt-db-api with PEAR

In the pear Directory there is a file txtdbapi.php.
This File is a Text-Db-Api Database-Wrapper for PEAR.

Installation

Copy this file to the other Database Wrapper into the directory

/usr/share/php/DB/ (common for *nix installations) or <php-installation>/PEAR/DB (windows).

The connect-String for the Txt-Db-Api looks like this:
txtdbapi://localhost/<dbname>

Example

A Database Query could look like this:
Code:
<?

include "DB.php";
include "txt-db-api.php";

$dbc = DB::connect("txtdbapi://localhost/soulspring");
//$dbc = DB::connect("mysql://user:password@localhost/soulspring");

$dbc->setFetchMode(DB_FETCHMODE_ASSOC);

// Simple SELECT with output
$result = $dbc->query("SELECT * FROM news");

if (PEAR::isError($result)) {
print $result->getUserInfo();
}

if ($result->numRows()) {
$row = array();
while($row = $result->fetchRow()) {
print_r($row);
}
} else {
print "No results available\n";
}

// Test for UPDATE and affectedRows()
$dbc->query("UPDATE news SET titel = 'Txt-Db-Api goes PEAR' WHERE id = '5' ");
print "Affected Rows: " . $dbc->affectedRows();

// Other Tests:
// getAll() returns all Records
// getCol() returns a single Column
print_r($dbc->getAll("SELECT * FROM programm", null, DB_FETCHMODE_ASSOC));
print_r($dbc->getCol("SELECT * FROM programm", 1));

$dbc->disconnect();

?>

If you have no access to the PEAR directory, it should suffice (I'm not sure) to copy only the following files to the webserver:

Code:
WEB-ROOT
|
|--include
| |
| `-- DB
| |
| |-- common.php
| |-- storage.php
| `-- txtdbapi.php
|-- DB.php
`-- PEAR.php

In the source you can include the PEAR::DB Module like this:
include "/include/DB.php"

This Workaround is experimental and may be unstable.


PHP: Text File Database Manual

Design / Structure of the Databases

Each Database is represented by a Directory. A Database has the same name as the Directory.
All Database-Directories have to be in the same Directory, and this Directory (the one containing all Database Directories)
is set with the Setting $DB_DIR in the file txt-db-api.php.

Small Example:

$DB_DIR is set to "/home/websites/myhome/Databases/".
So you can have 1 or More Database (=> Database Folders) under /home/websites/myhome/Databases/.
If you want a Database called MyDb, it will be located in /home/websites/myhome/Databases/MyDb.
If you want a second Database called MySecondDB, it will be located in /home/websites/myhome/Databases/MySecondDB....
I recommend you to add a .htaccess File to each Database folder or the .txt files in any folders that can be directly
read trough a browser (i.e. especially if the name is known).

$DB_DIR can also be set to a Windows Path of course, like C:\myWeb\bla\Databases\

Now if you want to execute a SQL-Statements on the Database MyDb you have to
create a Database-Object first. For example:

$db=new Database("MyDb");

The argument in the constructor is the name (i.e. folder) of the database relative to the $DB_DIR directory.

ATTENTION: Database names are case sensitive

Now if you have a Database instance ($db) you can execute some SQL Statements.
For example, to create a table :

$db->executeQuery("CREATE TABLE people (nr inc, name str, surname str, age int)");

You can also create Tables manualy.

Tables are stored as .txt Files in the Database Directory. But this is not so important, if you wish you can do everything with API calls without ever touching the .txt Files.

Only one thing is very important: All databases are really folders which must all be locatet in $DB_DIR!

IMPORTANT: The Database Directories must be create via FTP, and do not forgett to do a chmod()
on the directory or the CREATE TABLE calls will fail!

Another example:

The Website-Root is under /home/website/myPage/

The API Files are under /home/website/myPage/txt-db-api/

The Directory containing the Databases is /home/website/myPage/Databases

Two Databases are installed named TestDB and ProdDB, therefore, the following directories exist:

/home/website/myPage/Databases/TestDB/
and
/home/website/myPage/Databases/ProdDB/

The rights to these folders where changed with chmod() (i.e. to 777 or something permitting write access).

For this Directory-Structures the Settings in the txt-db-api.php would look like this:

$API_HOME_DIR="/home/website/myPage/txt-db-api/";
$DB_DIR="/home/website/myPage/Databases/";

A php script in the Directory /home/website/myPage/ would start like:

<? php
include("txt-db-api/txt-db-api.php");
.....


SQL Syntax (Einschränkungen für Txt-Db-Api)

SQL Syntax of the Txt-Db-Api (Limitations)

Abstract

The Txt-Db-Api does not support all SQL keywords/statements nor the SQL Standard.
On this Page the sql syntax for the txt-db-api and its limitations are listed.
Everything in [] is optional, "..." means that any more elements can follow,
| means OR (AND|OR => you can put AND or OR at this place).

As in Standard SQL: Do always enclose values for str (String) fields in quotes (' ' or " ") !

SELECT

Syntax

SELECT [DISTINCT]
[function(][table_name.]column[)] [AS alias_name] [, [function(][table_name].column[)] [AS alias_name] , ...]
FROM tablex [AS table_alias] [, tabley [AS table_alias], ... ]
[[LEFT|RIGHT|INNER] [OUTER] JOIN [table] ON table2, ... ]
[WHERE column=value AND|OR column=column AND|OR ...]
[GROUP BY column, ...]
[ORDER BY column [ASC | DESC] ,...]
[LIMIT [offset,]rows [;]

Supported

- look at the syntax...

- Instead of column names (column in the syntax above) you may also use direct values.
This can be numbers or strings in ' ' or " ", for example SELECT 1234, 'bla', name FROM people;

- The following functions: UNIX_TIMESTAMP(), MD5(column), NOW(), ABS(column), LCASE(column), UCASE(column), LOWER(column), UPPER(column), EVAL(column *-+/ value|column...)
- The functions in the line above are also supported in the WHERE, ORDER BY and GROUP BY part.
- The following grouping functions: MAX(column), MIN(column), COUNT(column), SUM(column), AVG(column)
- You can also use direct values as parameters for the functions, instead of columns, for example md5('bla')

- * instead of field names
- table.*, combinations are also allowed, for example: SELECT table1.*, people.Name, table3.* ...
- SELECT COUNT([table.]*)

- Aliases for Tables

- In the WHERE part, the following operators are supported: =,>,<,>=,<=, !=, <>, LIKE / NOT LIKE (you can use % or _ as wildcards), IN / NOT IN
- In the WHERE part, you can use field=value, value=value or field=field conditions
(to query tables linked, e.g. "person.typ_id = types.id", for field=field conditions all the above
listed operators can be used)
- In the WHERE part you can use countless AND's and OR's
- In the WHERE part brackets can be used, and also be nested

- JOIN's (INNER, LEFT [OUTER] and RIGHT [OUTER])
- DISTINCT: only unique rows are returned
- GROUP BY: the result will be grouped by this columns

- LIMIT: only rows Rows are returned, starting with offset (The first Row has offset 0!)

- When using DISTINCT and GROUP BY always the first value is taken
Example: "SELECT time, ip FROM log GROUP BY time"

time | ip
10348395 | 192.168.0.1
10348395 | 192.168.0.3
>
 time | ip
10348395 | 192.168.0.1

Not supported

- Appending of Fields like SELECT name & " " & prename AS whole_name or
SELECT name + prename AS whole_name
- Everything not found under Syntax or supported !

Examples

SELECT prename, person.name, types.typ AS person_typ FROM person, types
WHERE person.typ_id = types.id AND (person.Nr>=10 OR person.prename='Hans')
ORDER BY prename

SELECT COUNT(m.name), AVG(m.age) AS avgAge, c.name FROM members AS m, course AS c
WHERE m.course_nr=course.id GROUP BY c.name;

SELECT md5('bla');

Tip's

ATTENTION: Before and after each OR or AND must be a Space (" "). This is
requied for the parser, that can distinguish between field names containing
OR or AND as part of it, or real OR or AND's. The same applies for LIKE.
Examples:
Wrong: Name='Test'OR Nr>20
Right: Name='Test' OR Nr>20

ATTENTION: Use LIKE only if it's really necessary. Normal String compares are much
faster then LIKE. For example, if you want to query all records where the name is exactly
'tom', do it like this: SELECT * FROM table WHERE name='tom'
AND NOT: SELECT * FROM table WHERE name LIKE 'tom'
AND ALSO NOT: SELECT * FROM table WHERE name LIKE '%tom%'

INSERT

Syntax

INSERT [INTO] table [(column1, column2, column_n, ...)]
VALUES  (  [function(] value [)] [, [function(] value2 [)], value_n, ...]) [;]
    or
INSERT [INTO] table
SET column=[function(]value[)] [,column2= [function(]value2[)], column_n= [function(] value_n [)] , ...] [;]

Supported

- Look at syntax
- The following functions: UNIX_TIMESTAMP(), MD5(value), NOW(), ABS(value), LCASE(value), UCASE(value), LOWER(value), UPPER(value), EVAL(column *-+/ value|column...)
- Only values can be used as parameters for the functions in INSERT (an NOT columns)

Not supported

- INSERT with SELECT
- Insert more then one Record per SQL Statement
- Grouping functions MAX(), MIN() etc.
- Everything not under Syntax

Examples

INSERT INTO person (prename, name) VALUES ('hans','meier');

INSERT INTO passwords (user, password) VALUES ( 'user1', md5('mypassword') );

INSERT INTO person SET prename=upper('hans'), age=abs(-55), added=NOW() ;

DELETE

Syntax

DELETE FROM table [WHERE <same as in SELECT>] [;]

Supported

- Look at Syntax
- Deleting the whole Table (drop the WHERE part, for example: "DELETE FROM tableXY;")
- Same WHERE Syntax as in SELECT (functions are also supported!)

Not supported

- LIMIT
- Same restrictions for the WHERE part as by SELECT
- Everything not found in the Syntax above..

Examples

DELETE FROM person WHERE prename='Hans';

DELETE FROM person WHERE password=md5('mypw') AND abs(age)=abs(-5);

UPDATE

Syntax

UPDATE table SET column=[function(]value[)] [,column2=[function(]value2[)], column_n=[function(]value_n[)], ...]
[WHERE <same as in SELECT>] [;]

Supported

- Look at Syntax..
- The following functions for the values: UNIX_TIMESTAMP(), MD5(column or value), NOW(), ABS(column or value), LCASE(column or value),
UCASE(column or value), LOWER(column or value), UPPER(column or value)
- Update the whole Table (drop the WHERE part)
- Assign the value of one column to another
- Same syntax for the WHERE part as SELECT

Not supported

- LIMIT
- ORDER BY
- Everything not found in the Syntax above..

Examples

UPDATE person SET prename='Hans2000' WHERE prename='Hans';

UPDATE person SET prename=name WHERE prename='Hans';

UPDATE person SET password=md5(password);

UPDATE person SET age=abs(-20), name=upper(name);

CREATE TABLE

Syntax

CREATE TABLE (column_name  type [DEFAULT 'defaultValue'] [, column_name2  type2 [DEFAULT 'defaultValue'] , ... ]) [;]

Supported

- Look at Syntax
- DEFAULT (Enclose the Default-Value in ' ')
- ONLY the following Synatx: (column_name type , column_name type , ....), and the Keyword DEFAULT, and thats all !
- If you specify an Default-Value for an inc column, the first records inc values will be set to DefaultValue+1,
and for all other Records the Default-Value is ignored.

Not supported

- Everything not found under Syntax !!
- SQL Standard types, type can only be inc (Autoincrement), int (Number) or str (String,Text).

Example

CREATE TABLE people (id inc, prename str DEFAULT 'john', name str);

DROP TABLE

Syntax

DROP TABLE table1 [, table2, ...][;]

Supported

- Look at Syntax
- Drop 1 or more tables in one statement

Not supported

- Everything not found under Syntax !!

Example

DTOP TABLE people;

LIST TABLES

Syntax

LIST TABLES [WHERE ...]
[GROUP BY spalten_name, ...]
[ORDER BY spalten_name [ASC | DESC] ,...]
[LIMIT [offset,]anzahl] [;]

Supported

- Look at Syntax
- Returns a ResultSet Object containing one Column with the name "table",
which contains all Table names of the Database as String.
- For the WHERE, GROUP BY, ORDER BY and LIMIT syntax see SELECT

Not Supported

- Everything not found under Syntax !!
- Functions

Example

LIST TABLES;

CREATE DATABASE

Syntax

CREATE DATABASE database_name [;]

Supported

- Look at Syntax
- Only one Database can be created in one Statement.
- This Statement should only be executed on a ROOT_DATABASE Database!
You can get an instance of it with a $db=new Database(ROOT_DATABASE); call.
ROOT_DATABASE is a defined constant.

Not Supported

- Everything not found under Syntax !!

Example

CREATE DATABASE myDatabase;

DROP DATABASE

Syntax

DROP DATABASE database_name [;]

Supported

- Look at Syntax
- Only one Database can be deleted in one Statement.
- This Statement should only be executed on a ROOT_DATABASE Database!
You can get an instance of it with a $db=new Database(ROOT_DATABASE); call.
ROOT_DATABASE is a defined constant.

Not Supported

- Everything not found under Syntax !!

Example

DROP DATABASE myDatabase;


Escape Zeichen

Escape Characters

The SQL-Parser requires that some characters need to be escaped.
This means putting the backslash character (i.e. \ ) in front of other characters.
This is necessary for double or single quote (i.e. " or ') characters embedded in strings.

If you want to insert the value foo"bar into the column col1, you can't write the following statement:

INSERT INTO personen (col1,col2) VALUES ("foo"bar","bla");

You have to escape the " between foo and bar:

INSERT INTO personen (col1,col2) VALUES ("foo\"bar","bla");

The following charactes must be escaped: (only between ' ' or " "):
' (Single Quote), " (Double Quote), \ (the Backslash itself)

There are 3 different variants to write a SQL Statement in the PHP Code. In each variant the escape character is used differently.
The first variant is the most frequently used and if you have some luck, you never need to escape anything :)

Variant 1: Form Fields

If you want to use values of HTML form fields directly in the SQL stataments, you don't need to change anything.
The Content of Form Fields are automaticly correctly escaped .

Example:

$db->executeQuery("INSERT INTO person VALUES('$formField1','$formField2') ");

Variant 2: SQL Statement is between " "

In a Double Quoted String (" ") the following characters must be escaped (PHP rule):

character | Escaped
" (Double Quote) | \"
\ (Backslash) | \\

But these characters must also be escaped for the SQL-Parser, so you have to escape them twice, because PHP itself will remove one "escaping":

character | escaped (for PHP) | escaped for the SQL Parser
" (Double Quote) | \" | \\\"
\ (Backslash) | \\ | \\\\
' (Single Quote) | ' (no escape char needed between " ") | \'

Example:

$db->executeQuery("INSERT INTO person VALUES('double: \\\" ','single: \' '); ");

Variant 3: SQL Statement is between ' '

In a Single Quote String (' ') the following characters must be escaoed (PHP rule):

character | Escaped
' (Double Quote) | \'
\ (Backslash) | \\

But these characters must also be escaped for the SQL-Parser, so you have to escape them twice, because
PHP itself will remove one "escaping":

character | Escaped (for PHP) | escaped for the SQL Parser
" (Double Quote) | " (no escape char needed between ' ') | \"
\ (Backslash) | \\ | \\\\
' (Singe Quote) | \' | \\\'

$db->executeQuery('INSERT INTO person VALUES("double: \" "," single: \\\' "); ');


Fliesskomma-Zahlen

Floating point values

If you want to store floating point values in a table, you have to use the data type str (String).
Also, if you want to use floating point values in SQL Statements, you have to insert them between single quotes(' ') or double quotes (" ")" ".

Using str for floating point values does not hinder ORDER BY from working with floating point values.
For example, '50.1' is greater then '9.99999', event if '9.99999' comes first in the alphabet.


Error Handling

General

With the settings PRINT_ERRORS and PRINT_WARNINGS (in the file const.php) you can control if errors are printed.
Independent of this settings the Text-Db-Api manages an error stack. This is an array which contains all errors.
To do this, the Text-Db-Api sets its own PHP error handler. This error handler catches all errors and stores
them in the error stack and depending on the configuration these errors are printed out or not.
The error handler is set in the executeQuery() function and removed at the end of this function.
Also, each time you call executeQuery() the error stack will be cleared, this has the adventage that you
only have errors of the last executeQuery() call in the stack.

With the following functions you can query errors and clear the stack:

txtdbapi_clear_errors
txtdbapi_error_occurred
txtdbapi_get_errors
txtdbapi_get_last_error

Its also important to mention that the Text-Db-Api error handler also catches an stores all PHP Errors
(which occur in executeQuery) in the stack. So if you set PRINT_ERRORS and PRINT_WARNINGS to 0, you
should not see any error messages which occur in executeQuery().


The Database Object

(since Version 0.0.1)
Database -- This Object represents a Database (a Folder)

Description:

Before you can do something with a Table, you need an instance of a Database Object.

With this instance you then can execute SQL Statements, use the function executeQuery() to do this.

Example:

$db = new Database("MyDatabase");

$resultSet = $db->executeQuery("SELECT nr, name, prename FROM person WHERE nr=1");
while($resultSet->next()) {
    echo "<br>" . $resultSet->getCurrentValueByName("nr") . ": " . $resultSet->getCurrentValueByName("name") . "<br>";
}


Database (Construktor)

Database (Constructor)

(since Version 0.0.1)
Database - Constructor of the Database class

Description:

Database ([string dbName])

Constructor of the Database class. Creates and initializes a new Database Object.
With the parameter dbName you can select the Database you want to use
(matches the folder of the DB, in which the Table Text Files are)
If no Parameter dbName is supplied, the default database "defaultDb" will be used.
The database folder is relative to the directory set by the variable $DB_DIR in
the configuration file (txt-db-api.php).

Parameter:

dbName
 (optional, Default Value="defaultDb")
Name (Folder) of the Database

Return Value:

--


executeQuery

(since Version 0.0.1)
executeQuery -- Executes a SQL-Statement, and returns (depending on the Type of SQL-Statement) a ResultSet Object or an int

Description:

ResultSet/int executeQuery (string sqlQueryString)

Executes a SQL-Statement on the Database.
Not all Keywords and Statements of the SQL Standard are supported (See the SQL Syntax Page of this Manual)

Dont forget to escape " with a \ (See Escape Page of this Manual)

Parameter:

sqlQueryString
 Sql Statement String (example:"SELECT nr, name FROM person WHERE person.name=\"HANS\";")

Return Value:

SELECT/LIST TABLES Satements:
- A ResultSet Object, containing the Data returned by the Query
- In case of an Error false is returned.

UPDATE/INSERT/DELETE Statements:
- The Number of Rows changed is returned as int
- In case of an Error false is returned. (Attention: FALSE and 0 do not have the same meaning!)

CREATE TABLE/DROP TABLE/CREATE DATABASE/DROP DATABASE Statements:
- If ok: true
- In case of an Error false is returned.


getLastInsertId

(since Version 0.2.0)
getLastInsertId -- Returns the Insert ID

Description:

int getLastInsertId ()

Returns the value of the fist inc column, for the last record which was added by
a INSERT Statement.
(You must execute a INSERT Statement on a Database instance, or it want return a Insert Id)

Return value:

last Insert ID


The Database Object

The ResultSet Object

(since Version 0.0.1)
ResultSet -- This Object represents the Retult of a SELECT Query

Description:

After you execute a SELECT Statement with a $myDatabaseInstace->executeQuery() call, this
function returns a ResultSet Object. You can navigate trough this Object and read all
the Results of the Query.

Example:

$db = new Database("MyDatabase");

$resultSet = $db->executeQuery("SELECT nr, name, prename FROM person WHERE nr=1");
while($resultSet->next()) {
    echo "<br>" . $resultSet->getCurrentValueByName("nr") . ": " . $resultSet->getCurrentValueByName("name") . "<br>";
}


next

(since Version 0.0.1)
next -- Navigates to te next row (so it will be the current row)

Description:

bool next ()

Sets the Position of the ResultSet Object to the next Record (row).

Return value:

If there was a next Record: TRUE
If the end of the ResultSet is reached: FALSE


prev

(since Version 0.0.1)
prev -- Navigates to te previous row (so it will be the current row)

Description:

bool prev ()

Sets the Position of the ResultSet Object to the previous Record (row).

Return value:

If there was a previous Record: TRUE
If the start of the ResultSet is reached: FALSE


reset

(since Version 0.0.1)
reset -- Set's the Position of the Resultset to 1 before the first Record

Beschreibung:

reset ()

This Functions does set the Position of the Resultset before the first Record.
Why before the first record and no directly to the first record ??:
Because with a call to next() you will go to the first record, and
the following code will be possible:

$resultSet->reset();
while($resultSet->next()) {
    echo "Current Row: ";
    $arr=$resultSet->getCurrentValues();
    print_r($arr);
}

Return Value:

nothing..


getPos

(since Version 0.0.1)
getPos -- Returns the current Position (row) of the ResultSet

Description:

int getPos ()

Returns the current Position (row) of the ResultSet

Return Value:

A Value from -1 (before the first record) to getRowCount()-1


setPos

(since Version 0.0.1)
setPos -- Sets the Position (current Row) of the ResultSet

Description:

setPos (int pos)

Sets the current Position of the ResultSet Object.

Parameter:

pos
 The new Position, a Value from -1 (Before the first record) to getRowCount()-1

Return value:

nothing..


getRowCount

(since Version 0.0.1)
getRowCount -- Returns how much Rows the ResultSet has

Description:

int getRowCount ()

Returns the row-count of the Result Set.

Return value:

How much rows the ResultSet has as int.


getRowSize

(since Version 0.0.1)
getRowSize -- Returns the number of columns the ResultSet has (= the number of fields per row)

Description:

int getRowSize ()

Returns the number of columns the ResultSet has (= the number of fields per row)

Return value:

The number of columns the ResultSet


getColumnNames

(since Version 0.0.1)
getColumnNames -- Returns a array containing the column-names of the ResultSet

Description:

array getColumnNames ()

Returns a array containing the column-names of the ResultSet.
This values can be used, for example, in
getCurrentValueByName() or getValueByName() calls.

Returns:

an array containing the column-names of the ResultSet


getCurrentValueByName

(since Version 0.0.1)
getCurrentValueByName -- Returns the Value of the Column colName of the current Row

Beschreibung:

string getCurrentValueByName (string colName)

Returns the Value of the Column colName of the current Row.
The current Row can be changed with the functions next(), prev() oder setPos().

Parameter:

colName
Name of the Column for which the value is to read

Return value:

Value of the Column colName at the current Position (row)


getCurrentValueByNr

(since Version 0.0.1)
getCurrentValueByNr -- Returns the Value of the Column colNr at the current Position (row)

Description:

string getCurrentValueByNr (int colNr)

Returns the Value of the Column colNr at the current Position (row).
The current Position (Record, row) can be changed with the functions
next(), prev() or setPos().

Parameter:

colNr
Numver of the Column in which the Value is to read. Columns are in the same Order as in the SQL Query. The first column has the Number 0.

Return Value:

The Value of the Column colNr at the current Position (row)


getValueByName

(since Version 0.0.1)
getValueByName -- Returns the Value of the Coumn colNome of the Row rowNr.

Description:

string getValueByName (int rowNr, string colName)

Returns the Value of the Coumn colNome of the Row rowNr

Parameter:

rowNr
 Number of the Row
colName
Name of the Column

Return value:

Value of the Coumn colNome and the Row rowNr as string


getValueByNr

(since Version 0.0.1)
getValueByNr -- Returns the Value of the Column colNr of the Row rowNr.

Beschreibung:

string getValueByNr (int rowNr, int colNr)

Gibt den Wert der Spalte colNr der Reihe rowNr zurück.

Parameter:

rowNr
 Number of the Row, the first row has the number 0.
colNr
Number of the Column. Columns in the ResultSet have the same Order as in the SQL Statement. The first column has the number 0.

Return value:

Returns the Value of the Column colNr and the Row rowNr as string.


getCurrentValues

(since Version 0.0.1)
getCurrentValues -- Returns the Values of the current Row as array.

Description:

array getCurrentValues ()

Returns the Values of the current Row as array. The values in the Array have the same order as in
the SQL Query you supply.
The current Row (position) can be changed with the functions next(), prev() or setPos().

The PHP function list() somes in very handy here:

$db=new Database("MyDatabase");

$rs=$db->executeQuery("SELECT nr, name, address, email FROM person");
while($rs->next()) {
    list($idNr, $name, $address, $mail)=$rs->getCurrentValues();
    echo "$idNr: $name from $address (Email: $mail)";
}

Return Value:

The Values of the current Row as array.


getCurrentValues

getCurrentValuesAsHash

(since Version 0.1.3-alpha05)
getCurrentValuesAsHash -- Returns the Values of the current Row as hash array.

Description:

array getCurrentValuesAsHash ()

Returns the Values of the current Row as hash array. The values in the Array have the same order as in
the SQL Query you supply.
The current Row (position) can be changed with the functions next(), prev() or setPos().

Because its a hash array, you can access the array with the column names:

$db=new Database("MyDatabase");

$rs=$db->executeQuery("SELECT nr, name, address, email FROM person");
while($rs->next()) {
    $arr=$rs->getCurrentValuesAsHash();
    echo $arr['name'] . " " . $arr['address'] . "<br>";
}

Return Value:

The Values of the current Row as hash array.


getValues

(since Version 0.0.1)
getValues -- Returns the Values of the row rowNr as array

Description:

array getValues (int rowNr)

Returns the Values of the row rowNr as array. The values in the array have the same
Order as in the SQL Statement. (and if you use *, the same order as in the table)

Parameter:

rowNr
Number of the row

Return value:

Returns the Values of the row rowNr as array.


dump

(since Version 0.0.1)
dump -- Prints out the content of a ResultSet

Description:

dump ()

Prints out the content of a ResultSet

Return Value:

--


txtdbapi_version

(since Version 0.1.1)
txtdbapi_version -- Returns the Version of the API (as String)

Description:

string txtdbapi_version ()

Returns the Version of the API as String

Return Value:

Version of the API as String.


txtdbapi_clear_errors

(since Version 0.2.0)
txtdbapi_clear_errors -- Clears the error stack

Description:

txtdbapi_clear_errors ()

Clears the error stack. The error stack is cleared each time executeQuery() is called, so
you always have only Errors of the last executeQuery() call in the stack and it should not be
necessary to call this function.

Return value:

none


txtdbapi_error_occurred

(since Version 0.2.0)
txtdbapi_error_occurred -- Returns true if errors occurred since the last executeQuery() call

Description:

bool txtdbapi_error_occurred ()

Returns true if errors occurred since the last executeQuery() call and
false if no errors occurred .

Return value:

true if errors occurred since the last executeQuery() call and
false if no errors occurred


txtdbapi_get_errors

(since Version 0.2.0)
txtdbapi_get_errors -- Returns all errors as array

Description:

array txtdbapi_get_errors ()

Returns all errors as array of strings. The error stack will be cleared in this function.

Return value:

All errors as array


txtdbapi_get_last_error

(since Version 0.2.0)
txtdbapi_get_last_error -- Returns the last error and removes it from the stack

Description:

string txtdbapi_get_last_error ()

Returns the last error as string and removes it from the error stack. So if you call txtdbapi_get_last_error()
again you will get the next error.

Return value:

the last error as string


PHP: Text File Database Manual

Tutorial 1: Use the txt-db-api

The txt-db-api is simple to use. A php-site which uses the api does the following steps:

1. Include the Txt-Db-Api

<?php
include ("../php-api/txt-db-api.php");
?>

It's important that you specify the correct path to the txt-db-api.php file. That's the only
file you need to inlcude in order to work with the txt-db-api library.

2. Create a Database Object

If you have done the installation correctly and the corresponding folder for the database were created
(via FTP or with a CREATE DATABASE statement), you can now create a Database Object.
You must specify the name (i.e. a subfolder of $DB_DIR) of the Database in the constructor.
Database names are case-sensitive.

$db = new Database("myDatabase");

3. Execute SQL Statements

Once you have a Database Object, you can now execute as many SQL-Statemens on it as you like.
To execute a SQL-Statement use the executeQuery() function.

$rs=$db->executeQuery("SELECT
      name, prename, zip AS zipCode FROM people WHERE zip='1234' ORDER BY name;
      ");

The ";" at the end of the SQL-String is optional. The executeQuery() method returns a different value dependant on the SQL-Statement type. It can be either a boolean, a int or a ResultSet. (the return types are documented here)

4. Display the ResultSet (Only with SELECT Statements)

SELECT statements return a result set object, which contains the data of the query. There are different ways to query the data stored in a result set object.

Example #1: A while-loop method:

while($rs->next())

    { ... }

The next() method above traverses the result set to the next row. Note that before the next() method is called for the first time, the position of the result set is not at the beginning, it is one record before the beginning. Therefore, the first reference to next() will be at the first record!.

While in the while loop, you can now use any of the following 3 methods to obtain current row values:

  • getCurrentValues
  • getCurrentValueByName
  • getCurrentValueByNr

    Example:
    list($name,$prename,$zip)=$rs->getCurrentValues();
    echo "$name $prename  has the zip code $zip";


PHP: Text File Database Manual

Tutorial 2: Create Tables manually

Attention: The table format changed in version 0.1.3-Alpha-02 and 0.1.5-Alpha-01!

If you don't want to create new Tables with a CREATE TABLE call you can also create a table file on your own.

1. Create a Text File

Create a File with the Extension .txt

2. Define the columns (first line of the file)

In the first line of the text files, you have to write all column name.
Each column-name is finished with a #.

Example:
Nr#Name#Prename#Adress#Age

3. Define Data-type's (second line of the file)

Using the same format as above, you have to define the data type of each column now.
The supported datatypes are listed here.

Example for the second line::

inc#str#str#str#int

4. Define Default Values (third line of the file)

Using the same format as above, you have to define the default value for each column now.
The default values are used if you don't specify all columns when using an INSERT Statement.

Example for the third line::

0#default name#default prename#no adress#40

5. (Voluntary) Insert Data

Using the same format again, you can now insert some data in your table.
The finished table-text-file could look like this:

Nr#Name#Prename#Adress#Age
inc#str#str#str#int
0#default name#default prename#no adress#40
0#Tom#Smith#Teststreet 9#40
1#Max#Payne#Superstreet 1#22

6. Set permissions

Once you have uploaded the Text-File on your webserver, you have to change the permissions for it.
This can be done with most FTP client. You could use a chmod 777 for example.
To make it impossible that the Text-File can be viewed from the brower directly, it's m recommendable to
change the .htaccess File in the Folder where the Text-File is located.
Deny GET and POST access for to this folder.

7. Hints

If you want to use % or # as part of a column name or value, you have to write %p instead of % and %h instead of #.
This is necessary because # and % have a special meaning in table files.
You ONLY have to bother about the # and % characters if you enter the data manually into the text file.
CREATE TABLE and all other SQL Statements will handle this automatically for you.

Examples:

nr#link
inc#str
##
1#http://www.abc.de/index.htm%hanchor
2#http://www.abc.de/start.htm%hanchor2
nr#person#discount
inc#str#str
##10%p
1#müller#5%p
2#maier#7,5%p


FAQ

How can I store a date ?

Suggested variant:
Save the date as timestamp in an int field. Before you display the data you just have to convert it into a date.
When using this solution, sorting works automatically correctly.

Other variant:
.. save the date as string, for example in a format like yyyymmdd, for example 20030203. The sorting works also correctly
when you use such a format (because the year comes before the month which comes before the day).
You may want to convert the stored value before showing it also.
Maybe a format like yyyy-mm-dd is even more simple to parse.

If you don't want to make operations on the stored date (like plus 1 day), you could also just save the
return value of date("D M j H:i:s Y") as string and display/overwrite it unconverted. This may be usefull for
a guestbook or a forum, etc.


Reserved Words and Chars

Do NOT use the followig Words as Column Names:

AND
AS
ASC
BY
CREATE
DATABASE
DELETE
DESC
DISTINCT
DROP
FROM
GROUP
INSERT
INTO
LIKE
LIMIT
LIST
OR
ORDER
SELECT
SET
TABLE
UPDATE
VALUES
WHERE

Do NOT use the following Chars as Part of a Column Name:

<>
!=
>=
<=
=
<
>
(
)
;
, (Komma)
. (Punkt)
' (Einfache Quote)
" (Doppelte Quote)
!


About

About: Php Text Database API

Help Version: 0.3.1-Beta-01 (for the corresponding API Version)

Newest PHP Version the API is compatible with: 5.0.3

Developer API: | www.c-worker.ch, (Super)Mario sansone
Developer WebGUI: | Gobo
Documentation/Manual: | www.c-worker.ch, Lester (corrections)

Thanks to:

Mike, Wolfgang, www.codeforum.ch, Lester , Jakob Wankel,
jens rauschning, Mario Sansone, Gobo , Armin Gelhausen, deep:blue,
Sam Thursfield, stefan, stepan