Linux lhjmq-records 5.15.0-118-generic #128-Ubuntu SMP Fri Jul 5 09:28:59 UTC 2024 x86_64
Your IP : 3.149.254.35
<?php
/*
These are data access constant used by the data definition class. They are used
to remember what kind of data a field was so that we don't need to query back the
database before putting to it.
NDT = NumberedDataType
DT = DataType
*/
define("MYSQL_NDT_INT", 0);
define("MYSQL_NDT_REAL", 1);
define("MYSQL_NDT_DATE", 2);
define("MYSQL_NDT_DATETIME", 3);
define("MYSQL_NDT_TIMESTAMP", 4);
define("MYSQL_NDT_TIME", 5);
define("MYSQL_NDT_YEAR", 6);
define("MYSQL_NDT_STRING", 7);
define("MYSQL_NDT_BLOB", 8);
define("MYSQL_DT_0", "Integer Number");
define("MYSQL_DT_1", "Real Number");
define("MYSQL_DT_2", "Date");
define("MYSQL_DT_3", "Date and Time");
define("MYSQL_DT_4", "Time Stamp");
define("MYSQL_DT_5", "Time");
define("MYSQL_DT_6", "Year");
define("MYSQL_DT_7", "Character String");
define("MYSQL_DT_8", "Blob");
/*
This class is in charge of reading a mysql result resource and using the stored
information using a fetch array to create an interface to this data.
This tool can also be called a data interface collection. It is in charge of
keeping an index of the data fetched for fast fetch to the database. The index
needs a primary key to work with. Then you can add any information needed
*/
class data_interfacer{
//System objects
var $mysql_server;
var $query_builder;
var $interface;
var $item;
//Variables/Arrays
var $indexes = array();
var $curindex = 0;
var $primary_table;
var $primary_key;
//Constructor
function data_interfacer(&$mysql_server, &$query_builder){
//Store the server
$this->mysql_server = &$mysql_server;
$this->query_builder = &$query_builder;
}
/*Will create from a query an interface. For now, we assume
the query passed is normal query and not require a query builder object.*/
function &interface_query(){
//Connect to the database
$this->mysql_server->open();
//Create an interface object
$newint = new data_interface($this->query_builder->tables);
//Execute the query twice to get the fields and a result for the values
$result = $this->mysql_server->send_result_sql($this->query_builder->generate_select(), 1);
$fieldlist = $this->mysql_server->send_result_sql($this->query_builder->generate_select(), 1);
$flaglist = $this->mysql_server->send_result_sql($this->query_builder->generate_select(), 1);
//get the first row to insert values in the interface
$data = mysql_fetch_array($result);
//Used to loop the fields
$fieldcount = mysql_num_fields($fieldlist);
//Loop the data field definition and add the field in the end
for($curfield = 0; $curfield < $fieldcount; $curfield++){
//Get the current field
$datadef = mysql_fetch_field($fieldlist);
//Get the current flags
$flags = mysql_field_flags($flaglist, $curfield);
$fieldflags = explode(" ", $flags);
//Reset the data
$primary_key = 0;
$auto_increment = 0;
//Get all the other params from the field definition
$fieldname = $datadef->name;
$sourcetable = $datadef->table;
$datatype = constant("MYSQL_NDT_" . strtoupper($datadef->type));
$fieldvalue = $data[$datadef->name];
$datasize = $datadef->max_length;
//Check all the field flags
foreach($fieldflags as $key => $value){
if($value == "primary_key"){
$primary_key = 1;
}elseif($value == "auto_increment"){
$auto_increment = 1;
}
}
//Add the field to the data_interface
$newint->add_field($fieldname, $fieldvalue, $datatype, $datasize, $primary_key, $auto_increment, $sourcetable);
}
//Execute the FORCE commands <@primary@><@autoincrement@><@exclude@>
if(is_array($this->query_builder->primarykeys)){
foreach($this->query_builder->primarykeys as $keyarray){
//Create Fieldname
$fieldname = $keyarray[1] . "_" . $keyarray[0];
//Force a field definition to be primary
$newint->data_definitions["$fieldname"]->primary = 1;
}
}
if(is_array($this->query_builder->autoincrements)){
foreach($this->query_builder->autoincrements as $autoincarray){
//Create Fieldname
$fieldname = $autoincarray[1] . "_" . $autoincarray[0];
//Force a field definition to be primary
$newint->data_definitions["$fieldname"]->autoinc = 1;
}
}
if(is_array($this->query_builder->excludes)){
foreach($this->query_builder->excludes as $excludearray){
//Create Fieldname
$fieldname = $excludearray[1] . "_" . $excludearray[0];
//Force a field definition to be primary
$newint->data_definitions["$fieldname"]->exclude = 1;
}
}
//Close the connection
$this->mysql_server->close();
//Return the newly created interface
$this->interface = &$newint;
//Build the index before leaving
$this->build_index();
}
/*Builds and indexation system for the NEXT and PREV functions*/
function build_index(){
//Verify that the interface is a real object
if(!is_object($this->interface)){
return 0;
}
//Get the primary table
$tablename = $this->interface->database_tables[0];
//Loop all the fields in the interface to find the primary key for
//the table
foreach($this->interface->data_fields as $fieldkey => $fieldname){
//Verify the field's table and primary key field
if($this->interface->data_definitions["$fieldname"]->primary == 1 and $this->interface->data_definitions["$fieldname"]->sourcetable == "$tablename"){
//The key we found is the table and key name together, remove the table name
$keyname = str_replace($tablename . "_", "", $fieldname);
}
}
//Save the primary table and primary key to the system
$this->primary_table = $tablename;
$this->primary_key = $keyname;
//Get a resultset of the data to fetch later one
$this->mysql_server->open();
$result = $this->mysql_server->send_result_sql($this->query_builder->generate_select(), 1);
$this->mysql_server->close();
//Loop the values
while($row = mysql_fetch_array($result)){
//Get the value and add it to the index
$this->indexes[] = $row[$keyname];
}
//Set current index to -1, next_item will take the first one because of this
$this->curindex = -1;
//Return a result
return 1;
}
//debug show:debug function, shows the index array
function debug_indexes(){
//Loop the indexing array and show all keys and indexes
echo "Array of interfacer indexes:<br>";
foreach($this->indexes as $keyname => $value){
echo "Index #" . $keyname . ": " . $value . "<br>";
}
}
//item: Gets the requested data from the database server and returns it
function &item_by_index($index){
//Check that the id is not over the maximum
if($index <= count($this->indexes) - 1 and $index >= 0){
//Get the id from the indexing array
$id = $this->indexes[$index];
//Send the id to the item_by_id function
return $this->item_by_id($id);
}else{
//Return an empty object
return 0;
}
}
//item_by_id: get the item by it's database id and return it
function &item_by_id($id){
//Modify the id if it's a string
if(!is_numeric($id)){
$id = "'" .$id . "'";
}
//Backup the wheres inside the query builder
$this->query_builder->backup_wheres = $this->query_builder->wheres;
//Modify the clause to add the primary key to it and return the correct row
if(count($this->query_builder->wheres) > 0){
$this->query_builder->wheres["<@sys:index_selector@>"] = array("AND", $this->primary_table, $this->primary_key, "=", $id);
}else{
$this->query_builder->wheres["<@sys:index_selector@>"] = array("", $this->primary_table, $this->primary_key, "=", $id);
}
//Fetch the object from the database
$this->mysql_server->open();
$data = mysql_fetch_array($this->mysql_server->send_result_sql($this->query_builder->generate_select(), 1));
$fieldlist = $this->mysql_server->send_result_sql($this->query_builder->generate_select(), 1);
$this->mysql_server->close();
//For all the fields in the interface (We will find them in the interface_data)
//We change the data and send back the interface to the user
$fieldcount = mysql_num_fields($fieldlist);
//Loop the data field definition and add the field in the end
for($curfield = 0; $curfield < $fieldcount; $curfield++){
//Get the current field
$datadef = mysql_fetch_field($fieldlist);
//Get all the other params from the field definition
$fieldname = $datadef->name;
$sourcetable = $datadef->table;
$fieldvalue = $data["$datadef->name"];
$interface_name = $sourcetable . "_" . $fieldname;
//Change the value in the interface
$this->interface->$interface_name = $fieldvalue;
}
//Put the backup right on the modified wheres
$this->query_builder->wheres = $this->query_builder->backup_wheres;
//Return the object
return $this->interface;
}
//next_item: Moves the cur index to the next one and fetch the object
function &next_item(){
//Check the boundaries(If at max, we reset to index 0)
if($this->curindex + 1 <= count($this->indexes) - 1){
//Augment the cur index
$this->curindex++;
//Get this item
return $this->item_by_index($this->curindex);
}else{
//Reset the cur index to -1 so that we don't return anything
$this->curindex = -1;
//Return EOF or 0 in this case
return 0;
}
}
//prev_item: Moves the cur index to the previous one and fetch the object
function &prev_item(){
//Check the boundaries(If at max, we reset to index 0)
if($this->curindex - 1 >= 0){
//Augment the cur index
$this->curindex--;
//Get this item
return $this->item_by_index($this->curindex);
}else{
//Reset the cur index to -1 so that we don't return anything
$this->curindex = count($this->indexes);
//Return 0 even if we are at the end so that we don't loop infinitly
return 0;
}
}
}
/*
Class that keeps and acts as a data interface to the user. Each field in the query
will be available from outside the class using a simple -> operation.
Class contains no public variables, these are set on construction. The only 2
variables that is declared and that should never be used is the data definition
array. The only usage of the data definition array is to read what TYPE of data
the field is and that is all.
The other variable is an array called data_fields, it contains an array of
available fields. Used by enumerators like form builders to build intelligent
forms based on data in the interface without having any knowledge of what is in
the interface.
*/
class data_interface{
/*System Data*/
var $data_definitions;
var $data_fields;
/*Friend data*/
var $database_tables;
/*Constructor*/
function data_interface($tables){
//Save the table array
$this->database_tables = $tables;
}
/*Function that adds/configure a data field, definition and member to the inteface.
Should only be used by system objects like the data interfacer not by the user.*/
function add_field($fieldname, $fieldvalue, $datatype, $datasize){
//Check if the optionnal params where passed
$numargs = func_num_args();
switch($numargs){
case 7:
$sourcetable = func_get_arg(6);
case 6:
$autoinc = func_get_arg(5);
case 5:
$primary = func_get_arg(4);
}
//Set to 0 all optionals not set
if(!isset($primary)){$primary = 0;}
if(!isset($autoinc)){$autoinc = 0;}
if(!isset($sourcetable)){$sourcetable = $this->database_tables[0];} //Use default table
if(!isset($exclude)){$exclude = 0;}
//Create the final field interface name
$fieldname = $sourcetable . "_" . $fieldname;
//Create the data definition for this field
$definition = new data_definition($datatype, $datasize, $primary, $autoinc, $sourcetable, $exclude);
$this->data_definitions["$fieldname"] = &$definition;
//Store the value by adding it as a virtual member
$this->$fieldname = $fieldvalue;
//Add this field to the field array
$this->data_fields[] = "$fieldname";
}
/*Clears the class and makes it new to be used by anything*/
function clear(){
//Unset all the dynamic members
foreach($this->data_definitions as $key => $value){
//Unset the dynamic member and data definition
unset($this->data_definitions[$key]);
unset($this->$key);
}
//Unset the field list
unset($this->data_fields);
}
/*Debug function that prints out everything*/
function debug(){
//For each dynamic fields
foreach($this->data_fields as $key => $value){
//Echos all data definitions, field names and values
echo "Dynamic field: " . $value . " = " . $this->$value . "<br>";
//Debug the data definition
$this->data_definitions[$value]->debug();
echo "<br>";
}
}
/*Creates an Insert String to be used on table*/
function generate_insert(){
//Check if a table name was passed
if(func_num_args() > 0){
//Current table is specified table
$GenerateForTable = func_get_arg(0);
}else{
//No table specified, use default table number 0
$GenerateForTable = $this->database_tables[0];
}
//Generate basic setup
$sql = "INSERT INTO " . $GenerateForTable . " (";
//Setup
$seperator = "";
//Loop all fields
foreach($this->data_fields as $id => $interfacename){
//Check if field is autoincrement (We do not insert values for autoincrement and for excludes)
if($this->data_definitions[$interfacename]->autoinc == 0 and $this->data_definitions[$interfacename]->exclude == 0 and $this->data_definitions[$interfacename]->sourcetable == "$GenerateForTable"){
//Temporary field name stripped from the table name
$fieldname = str_replace($this->data_definitions[$interfacename]->sourcetable . "_", "", $interfacename);
//Get that field name into the list of fields
$fieldlist .= $seperator . $fieldname;
//Get the value in the value list
$valuelist .= $seperator . $this->data_definitions[$interfacename]->generate_output($this->$interfacename);
//Setup
$seperator = ", ";
}
}
//Assemble data into one
return $sql .= $fieldlist . ") VALUES(" . $valuelist . ")";
}
function generate_update(){
//Check if a table name was passed
if(func_num_args() > 0){
//Current table is specified table
$GenerateForTable = func_get_arg(0);
}else{
//No table specified, use default table number 0
$GenerateForTable = $this->database_tables[0];
}
//Generate basic setup
$sql = "UPDATE " . $GenerateForTable . " SET ";
//Setup
$seperator = "";
//Loop all fields
foreach($this->data_fields as $id => $interfacename){
//Exclude the primary keys, autoincrement keys and fields from other tables from update statement
if($this->data_definitions[$interfacename]->primary == 0 and $this->data_definitions[$interfacename]->sourcetable == "$GenerateForTable" and $this->data_definitions[$interfacename]->autoinc == 0){
//Extract the field name from the interface name
$fieldname = str_replace($this->data_definitions[$interfacename]->sourcetable . "_", "", $interfacename);
//Get that field name into the list of fields
$setlist .= $seperator . $fieldname . " = " . $this->data_definitions[$interfacename]->generate_output($this->$interfacename);
//Setup
$seperator = ", ";
}
}
//Loop all fields to find the primary keys
foreach($this->data_fields as $id => $interfacename){
//Setup
$and = "";
//Exclude all fields that are not primary and excluded
if($this->data_definitions[$interfacename]->exclude == 0 and $this->data_definitions[$interfacename]->primary == 1 and $this->data_definitions[$interfacename]->sourcetable == "$GenerateForTable"){
//Extract the field name from the interface name
$fieldname = str_replace($this->data_definitions[$interfacename]->sourcetable . "_", "", $interfacename);
//Add to the primary key listing
$primarykeys .= $and . $fieldname . " = " . $this->data_definitions[$interfacename]->generate_output($this->$interfacename);
//setup
$and = " AND ";
}
}
//Assemble data into one
return $sql .= $setlist . " WHERE " . $primarykeys;
}
function generate_delete(){
//Check if a table name was passed
if(func_num_args() > 0){
//Current table is specified table
$GenerateForTable = func_get_arg(0);
}else{
//No table specified, use default table number 0
$GenerateForTable = $this->database_tables[0];
}
//Generate basic setup
$sql = "DELETE FROM " . $GenerateForTable . " WHERE ";
//Loop all fields to find the primary keys
foreach($this->data_fields as $id => $interfacename){
//Setup
$and = "";
//Exclude all fields that are not primary and excluded
if($this->data_definitions[$interfacename]->exclude == 0 and $this->data_definitions[$interfacename]->primary == 1 and $this->data_definitions[$interfacename]->sourcetable == "$GenerateForTable"){
//Extract the field name from the interface name
$fieldname = str_replace($this->data_definitions[$interfacename]->sourcetable . "_", "", $interfacename);
//Add to the primary key listing
$primarykeys .= $and . $fieldname . " = " . $this->data_definitions[$interfacename]->generate_output($this->$interfacename);
//setup
$and = " AND ";
}
}
//Return the sql command
return $sql . $primarykeys;
}
}
/*
This class is a simple class that keeps data from a field in the interface. When
using a update or insert statement, the data_interface will be able to build a well
formated sql command to update without a problem.
*/
class data_definition{
/*Private members that no one should use, this class should be system restricted*/
var $ndt;
var $size;
var $primary;
var $autoinc;
var $sourcetable;
var $exclude;
/*Constructor*/
function data_definition($datatype, $datasize, $primary, $autoinc, $sourcetable, $exclude){
//Copy the information for the datatype, datasize
$this->ndt = $datatype;
$this->size = $datasize;
$this->primary = $primary;
$this->autoinc = $autoinc;
$this->sourcetable = $sourcetable;
$this->exclude = $exclude;
}
/*Debug function that prints out all data in data definition*/
function debug(){
//Print out
echo " -> Data Definition: ". constant("MYSQL_DT_" . $this->ndt) . "(" . $this->size . ") Flags(";
if($this->primary) echo "PRIMARY ";
if($this->autoinc) echo "AUTO_INCREMENT ";
if($this->exclude) echo "EXCLUDED ";
echo ") SourceTable: " . $this->sourcetable;
}
/*Generate a correctly formated output for an sql string*/
function generate_output($data){
//Check the type of data to format
if($this->ndt == MYSQL_NDT_INT){
//Return the value as is
return $data;
}else{
//Transform the already /' in a system code
$data = str_replace("\\'", "sys:code:bsqu", $data);
//Transform all the ' in to /'
$data = str_replace("'", "\\'", $data);
//Retranform the system code back into /'
$data = str_replace("sys:code:bsqu", "\\'", $data);
//Return the data in quoted format
return "'" . $data . "'";
}
}
}
?>
|