Revision: 1307
http://mrbs.svn.sourceforge.net/mrbs/?rev=1307&view=rev
Author: cimorrison
Date: 2010-03-21 08:54:33 +0000 (Sun, 21 Mar 2010)
Log Message:
-----------
The room editing pages (admin.php and edit_area_room.php) will now recognise
user defined columns in the room table, displaying them in the room editing
form as appropriate. This enables information about the rooms to be added to
the system (eg coffee machine? whiteboard? etc.). At the moment only text,
varchar, int, smallint and tinyint are supported, displayed as textarea, text
or checkbox fields as appropriate. Smaallints and tinyints are assumed to be
booleans and are displayed as checkboxes. Text descriptions are looked for in
the lang files with the tag room.column_name, eg room.coffee_machine, enabling
translations to be provided. If not present, the column name will be used for
labels etc.
Modified Paths:
--------------
mrbs/trunk/web/admin.php
mrbs/trunk/web/dbsys.inc
mrbs/trunk/web/edit_area_room.php
mrbs/trunk/web/mrbs-ielte6.css
mrbs/trunk/web/mrbs.css.php
mrbs/trunk/web/mysql.inc
mrbs/trunk/web/mysqli.inc
mrbs/trunk/web/pgsql.inc
Added Paths:
-----------
mrbs/trunk/web/images/check.png
Modified: mrbs/trunk/web/admin.php
===================================================================
--- mrbs/trunk/web/admin.php 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/admin.php 2010-03-21 08:54:33 UTC (rev 1307)
@@ -2,6 +2,8 @@
// $Id$
+define ('MAX_TEXT_LENGTH', 20); // the maximum number of characters to
display in the room table
+
require_once "defaultincludes.inc";
// Get form variables
@@ -186,12 +188,16 @@
}
else
{
+ // Get the information about the fields in the room table
+ $fields = sql_field_info($tbl_room);
+
// Build an array with the room info
$rooms = array();
for ($i = 0; ($row = sql_row_keyed($res, $i)); $i++)
{
$rooms[] = $row;
}
+
// Display it in a table [Actually two tables side by side so that we can
// achieve a "Freeze Panes" effect: there doesn't seem to be a good way of
// getting a colgroup to scroll, so we have to distort the mark-up a
little]
@@ -248,9 +254,33 @@
echo "<table>\n";
echo "<thead>\n";
echo "<tr>\n";
- echo "<th><div>" . get_vocab("description") . "</div></th>\n";
- echo "<th><div>" . get_vocab("capacity") . "</div></th>\n";
- echo "<th><div>" . get_vocab("room_admin_email") . "</div></th>\n";
+ // ignore these columns, either because we don't want to display them,
+ // or because we have already displayed them in the header column
+ $ignore = array('id', 'area_id', 'room_name', 'sort_key');
+ foreach($fields as $field)
+ {
+ if (!in_array($field['name'], $ignore))
+ {
+ switch ($field['name'])
+ {
+ // the standard MRBS fields
+ case 'description':
+ case 'capacity':
+ case 'room_admin_email':
+ $text = get_vocab($field['name']);
+ break;
+ // any user defined fields
+ default:
+ $text = substr($tbl_room, strlen($db_tbl_prefix)); // strip the
prefix off the table name
+ $text .= "." . $field['name']; // add on the fieldname
+ // then if there's a string in the vocab array for $tag use that
+ // otherwise just use the fieldname
+ $text = (isset($vocab[$text])) ? get_vocab($text) : $field['name'];
+ break;
+ }
+ echo "<th><div>" . htmlspecialchars($text) . "</div></th>\n";
+ }
+ }
echo "</tr>\n";
echo "</thead>\n";
echo "<tbody>\n";
@@ -259,9 +289,48 @@
{
$row_class = ($row_class == "even_row") ? "odd_row" : "even_row";
echo "<tr class=\"$row_class\">\n";
- echo "<td><div>" . htmlspecialchars($r['description']) . "</div></td>\n";
- echo "<td class=\"int\"><div>" . $r['capacity'] . "</div></td>\n";
- echo "<td><div>" . htmlspecialchars($r['room_admin_email']) .
"</div></td>\n";
+ foreach($fields as $field)
+ {
+ if (!in_array($field['name'], $ignore))
+ {
+ switch ($field['name'])
+ {
+ // the standard MRBS fields
+ case 'description':
+ case 'room_admin_email':
+ echo "<td><div>" . htmlspecialchars($r[$field['name']]) .
"</div></td>\n";
+ break;
+ case 'capacity':
+ echo "<td class=\"int\"><div>" . $r[$field['name']] .
"</div></td>\n";
+ break;
+ // any user defined fields
+ default:
+ if (($field['nature'] == 'boolean') ||
+ (($field['nature'] == 'integer') && isset($field['length'])
&& ($field['length'] <= 2)) )
+ {
+ // booleans: represent by a checkmark
+ echo "<td class=\"int\"><div>";
+ echo (!empty($r[$field['name']])) ? "<img
src=\"images/check.png\" alt=\"check mark\" width=\"16\" height=\"16\">" :
" ";
+ echo "</div></td>\n";
+ }
+ elseif (($field['nature'] == 'integer') &&
isset($field['length']) && ($field['length'] > 2))
+ {
+ // integer values
+ echo "<td class=\"int\"><div>" . $r[$field['name']] .
"</div></td>\n";
+ }
+ else
+ {
+ // strings
+ $text = htmlspecialchars($r[$field['name']]);
+ echo "<td title=\"$text\"><div>";
+ echo substr($text, 0, MAX_TEXT_LENGTH);
+ echo (strlen($text) > MAX_TEXT_LENGTH) ? " ..." : "";
+ echo "</div></td>\n";
+ }
+ break;
+ }
+ }
+ }
echo "</tr>\n";
}
echo "</tbody>\n";
@@ -314,4 +383,4 @@
require_once "trailer.inc"
-?>
+?>
\ No newline at end of file
Modified: mrbs/trunk/web/dbsys.inc
===================================================================
--- mrbs/trunk/web/dbsys.inc 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/dbsys.inc 2010-03-21 08:54:33 UTC (rev 1307)
@@ -548,6 +548,60 @@
}
+// This function returns information about columns in the database in a manner
+// that is independent of the underlying database. It was originally
designed
+// for use by MRBS pages that have user defined columns in the relevant table
+// and to enable them to decide how to represent the column on a page. For
example
+// a smallint is often used to represent a boolean, which should be
represented by a
+// checkbox. (Smallints are used by MRBS for booleans in PostgreSQL because
booleans return
+// a PHP boolean type, rather than a 0 or 1 which MySQL does, and so this
makes testing
+// of the results difficult).
+//
+// Returns an array with the following indices for each column
+//
+// 'name' the column name
+// 'type' the type as reported by MySQL or PostgreSQL
+// 'nature' the type mapped onto one of a generic set of types
+// (boolean, integer, real, character, binary). This enables
+// the nature to be used by MRBS code when deciding how to
+// display fields, without MRBS having to worry about the
+// differences between MySQL and PostgreSQL type names.
+// 'length' the maximum length of the field in bytes, octets or
characters
+// (Note: this could be NULL)
+//
+// NOTE: the type mapping is incomplete and just covers the types commonly
+// used by MRBS
+//
+// The difficulty is that MySQL and PostgreSQL return different formats
+// of answer for the type of field when using sql_field_type. For example
+// for a smallint, PostgreSQL will just return int, and there is no exact
equivalent
+// of the mysql_ field_ len() function. Although pg_field_size is a close
+// approximation and returns 2 for a smallint, enabling it to be distinguished
+// from an int, when used with variable length character types such as text or
+// varying character it returns -1.
+//
+// [There must be a better way of doing all this???!]
+function sql_field_info($table)
+{
+ if (func_num_args() > 1)
+ {
+ $handle = func_get_arg(1);
+ $db_sys = $handle['system'];
+ $db_conn = $handle['connection'];
+ }
+ else
+ {
+ global $dbsys;
+
+ $db_sys = $dbsys;
+ $db_conn = null;
+ }
+
+ $f = "sql_${db_sys}_field_info";
+ return $f($table, $db_conn);
+}
+
+
// Connect to a database host and select the supplied database
function sql_connect($system, $host, $username, $password, $db_name,
$persist = 0)
Modified: mrbs/trunk/web/edit_area_room.php
===================================================================
--- mrbs/trunk/web/edit_area_room.php 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/edit_area_room.php 2010-03-21 08:54:33 UTC (rev 1307)
@@ -1,6 +1,51 @@
<?php
// $Id$
+// If you want to add some extra columns to the room table to describe the room
+// then you can do so and this page should automatically recognise them and
handle
+// them. At the moment support is limited to the following column types:
+//
+// MySQL PostgreSQL Form input type
+// ----- ---------- ---------------
+// bigint bigint text
+// int integer text
+// mediumint text
+// smallint smallint checkbox
+// tinyint checkbox
+// text text textarea
+// tinytext textarea
+// character varying textarea
+// varchar(n) character varying(n) text/textarea, depending on the value of
n
+// character text
+// char(n) character(n) text/textarea, depending on the value of
n
+//
+// NOTE 1: For char(n) and varchar(n) fields, a text input will be presented if
+// n is less than or equal to TEXT_INPUT_MAX, otherwise a textarea box will be
+// presented.
+//
+// NOTE 2: PostgreSQL booleans are not supported, due to difficulties in
+// handling the fields in a database independent way (a PostgreSQL boolean
+// will return a PHP boolean type when read by a PHP query, whereas a MySQL
+// tinyint returns an int). In order to have a boolean field in the room
+// table you should use a smallint in PostgreSQL or a smallint or a tinyint
+// in MySQL.
+//
+// You can put a description of the column that will be used as the label in
+// the form in the appropriate lang file(s) using the tag 'room.[columnname]'.
+// For example if you want to add a column specifying whether or not a room
+// has a coffee machine you could add a column to the room table called
+// 'coffee_machine' of type tinyint(1), in MySQL, or smallint in PostgreSQL.
+// Then in the appropriate lang file(s) you would add the line
+//
+// vocab["room.coffee_machine"] = "Coffee machine"; // or appropriate
translation
+//
+// If MRBS can't find an entry for the field in the lang file, then it will use
+// the fieldname, eg 'coffee_machine'.
+
+define('TEXT_INPUT_MAX', 70); // Maximum size in characters of a user defined
+ // column for a text input to be used.
Greater than
+ // this and a textarea will be used
+
require_once "defaultincludes.inc";
require_once "mrbs_sql.inc";
@@ -44,6 +89,33 @@
$change_room = get_form_var('change_room', 'string');
$change_area = get_form_var('change_area', 'string');
+// Get the information about the fields in the room table
+$fields = sql_field_info($tbl_room);
+
+// Get any user defined form variables
+foreach($fields as $field)
+{
+ switch($field['nature'])
+ {
+ case 'character':
+ $type = 'string';
+ break;
+ case 'integer':
+ $type = 'int';
+ break;
+ // We can only really deal with the types above at the moment
+ default:
+ $type = 'string';
+ break;
+ }
+ $var = "f_" . $field['name'];
+ $$var = get_form_var($var, $type);
+ if (($type == 'int') && ($$var === ''))
+ {
+ unset($$var);
+ }
+}
+
// If we dont know the right date then make it up
if (!isset($day) or !isset($month) or !isset($year))
{
@@ -82,6 +154,7 @@
$valid_room_name = TRUE;
+
// PHASE 2
// -------
// Unauthorised users shouldn't normally be able to reach Phase 2, but just in
case
@@ -131,11 +204,63 @@
// If everything is still OK, update the databasae
else
{
- $sql = "UPDATE $tbl_room SET room_name='" . addslashes($room_name)
- . "', sort_key='" . addslashes($sort_key)
- . "', description='" . addslashes($description)
- . "', capacity=$capacity, area_id=$new_area, room_admin_email='"
- . addslashes($room_admin_email) . "' WHERE id=$room";
+ $sql = "UPDATE $tbl_room SET ";
+ $n_fields = count($fields);
+ $first_field = TRUE;
+ foreach ($fields as $field)
+ {
+ if ($field['name'] != 'id') // don't do anything with the id field
+ {
+ if (!$first_field)
+ {
+ $sql .= ", ";
+ }
+ else
+ {
+ $first_field = FALSE;
+ }
+ switch ($field['name'])
+ {
+ // first of all deal with the standard MRBS fields
+ case 'area_id':
+ $sql .= "area_id=$new_area";
+ break;
+ case 'room_name':
+ $sql .= "room_name='" . addslashes($room_name) . "'";
+ break;
+ case 'sort_key':
+ $sql .= "sort_key='" . addslashes($sort_key) . "'";
+ break;
+ case 'description':
+ $sql .= "description='" . addslashes($description) . "'";
+ break;
+ case 'capacity':
+ $sql .= "capacity=$capacity";
+ break;
+ case 'room_admin_email':
+ $sql .= "room_admin_email='" . addslashes($room_admin_email) .
"'";
+ break;
+ // then look at any user defined fields
+ default:
+ $var = "f_" . $field['name'];
+ switch ($field['nature'])
+ {
+ case 'integer':
+ if (!isset($$var))
+ {
+ $$var = 'NULL';
+ }
+ break;
+ default:
+ $$var = "'" . addslashes($$var) . "'";
+ break;
+ }
+ $sql .= $field['name'] . "=" . $$var;
+ break;
+ }
+ }
+ }
+ $sql .= " WHERE id=$room";
if (sql_command($sql) < 0)
{
fatal_error(0, get_vocab("update_room_failed") . sql_error());
@@ -287,13 +412,12 @@
// THE ROOM FORM
if (!empty($room))
{
- $res = sql_query("SELECT * FROM $tbl_room WHERE id=$room");
+ $res = sql_query("SELECT * FROM $tbl_room WHERE id=$room LIMIT 1");
if (! $res)
{
fatal_error(0, get_vocab("error_room") . $room . get_vocab("not_found"));
}
$row = sql_row_keyed($res, 0);
- sql_free($res);
?>
<form class="form_general" id="edit_room" action="edit_area_room.php"
method="post">
@@ -345,37 +469,81 @@
echo "<input type=\"hidden\" name=\"old_area\" value=\"" .
$row['area_id'] . "\">\n";
echo "</div>\n";
- // Room name
- echo "<div>\n";
- echo "<label for=\"room_name\">" . get_vocab("name") . ":</label>\n";
- echo "<input type=\"text\" id=\"room_name\" name=\"room_name\" value=\""
. htmlspecialchars($row["room_name"]) . "\"$disabled>\n";
- echo "<input type=\"hidden\" name=\"old_room_name\" value=\"" .
htmlspecialchars($row["room_name"]) . "\">\n";
- echo "</div>\n";
+ foreach ($fields as $field)
+ {
+ if (!in_array($field['name'], array('id', 'area_id'))) // Ignore
certain fields
+ {
+ echo "<div>\n";
+ switch($field['name'])
+ {
+ // first of all deal with the standard MRBS fields
+ case 'room_name':
+ echo "<label for=\"room_name\">" . get_vocab("name") .
":</label>\n";
+ echo "<input type=\"text\" id=\"room_name\" name=\"room_name\"
value=\"" . htmlspecialchars($row["room_name"]) . "\"$disabled>\n";
+ echo "<input type=\"hidden\" name=\"old_room_name\" value=\"" .
htmlspecialchars($row["room_name"]) . "\">\n";
+ break;
+ case 'sort_key':
+ echo "<label for=\"sort_key\" title=\"" .
get_vocab("sort_key_note") . "\">" . get_vocab("sort_key") . ":</label>\n";
+ echo "<input type=\"text\" id=\"sort_key\" name=\"sort_key\"
value=\"" . htmlspecialchars($row["sort_key"]) . "\"$disabled>\n";
+ break;
+ case 'description':
+ echo "<label for=\"description\">" . get_vocab("description") .
":</label>\n";
+ echo "<input type=\"text\" id=\"description\"
name=\"description\" value=\"" . htmlspecialchars($row["description"]) .
"\"$disabled>\n";
+ break;
+ case 'capacity':
+ echo "<label for=\"capacity\">" . get_vocab("capacity") .
":</label>\n";
+ echo "<input type=\"text\" id=\"capacity\" name=\"capacity\"
value=\"" . $row["capacity"] . "\"$disabled>\n";
+ break;
+ case 'room_admin_email':
+ echo "<label for=\"room_admin_email\">" .
get_vocab("room_admin_email") . ":</label>\n";
+ echo "<input type=\"text\" id=\"room_admin_email\"
name=\"room_admin_email\" maxlength=\"75\" value=\"" .
htmlspecialchars($row["room_admin_email"]) . "\"$disabled>\n";
+ break;
+ // then look at any user defined fields
+ default:
+ $tag = substr($tbl_room, strlen($db_tbl_prefix)); // strip the
prefix off the table name
+ $tag .= "." . $field['name']; // add on the fieldname
+ // then if there's a string in the vocab array for $tag use that
+ // otherwise just use the fieldname
+ $label_text = (isset($vocab[$tag])) ? get_vocab($tag) :
$field['name'];
+ echo "<label for=\"f_" . $field['name'] .
"\">$label_text:</label>\n";
+ // Output a checkbox if it's a boolean or integer <= 2 bytes
(which we will
+ // assume are intended to be booleans)
+ if (($field['nature'] == 'boolean') ||
+ (($field['nature'] == 'integer') && isset($field['length'])
&& ($field['length'] <= 2)) )
+ {
+ echo "<input type=\"checkbox\" class=\"checkbox\" " .
+ "id=\"f_" . $field['name'] . "\" " .
+ "name=\"f_" . $field['name'] . "\" " .
+ "value=\"1\" " .
+ ((!empty($row[$field['name']])) ? " checked=\"checked\""
: "") .
+ "$disabled>\n";
+ }
+ // Output a textarea if it's a character string longer than the
limit for a
+ // text input
+ elseif (($field['nature'] == 'character') &&
isset($field['length']) && ($field['length'] > TEXT_INPUT_MAX))
+ {
+ echo "<textarea rows=\"8\" cols=\"40\" " .
+ "id=\"f_" . $field['name'] . "\" " .
+ "name=\"f_" . $field['name'] . "\" " .
+ "$disabled>\n";
+ echo htmlspecialchars($row[$field['name']]);
+ echo "</textarea>\n";
+ }
+ // Otherwise output a text input
+ else
+ {
+ echo "<input type=\"text\" " .
+ "id=\"f_" . $field['name'] . "\" " .
+ "name=\"f_" . $field['name'] . "\" " .
+ "value=\"" . htmlspecialchars($row[$field['name']]) .
"\"" .
+ "$disabled>\n";
+ }
+ break;
+ }
+ echo "</div>\n";
+ }
+ }
- // Sort key
- echo "<div>\n";
- echo "<label for=\"sort_key\" title=\"" . get_vocab("sort_key_note") .
"\">" . get_vocab("sort_key") . ":</label>\n";
- echo "<input type=\"text\" id=\"sort_key\" name=\"sort_key\" value=\"" .
htmlspecialchars($row["sort_key"]) . "\"$disabled>\n";
- echo "</div>\n";
-
- // Description
- echo "<div>\n";
- echo "<label for=\"description\">" . get_vocab("description") .
":</label>\n";
- echo "<input type=\"text\" id=\"description\" name=\"description\"
value=\"" . htmlspecialchars($row["description"]) . "\"$disabled>\n";
- echo "</div>\n";
-
- // Capacity
- echo "<div>\n";
- echo "<label for=\"capacity\">" . get_vocab("capacity") . ":</label>\n";
- echo "<input type=\"text\" id=\"capacity\" name=\"capacity\" value=\"" .
$row["capacity"] . "\"$disabled>\n";
- echo "</div>\n";
-
- // Room admin email
- echo "<div>\n";
- echo "<label for=\"room_admin_email\">" . get_vocab("room_admin_email")
. ":</label>\n";
- echo "<input type=\"text\" id=\"room_admin_email\"
name=\"room_admin_email\" maxlength=\"75\" value=\"" .
htmlspecialchars($row["room_admin_email"]) . "\"$disabled>\n";
- echo "</div>\n";
-
// Submit and Back buttons (Submit only if they're an admin)
echo "<fieldset class=\"submit_buttons\">\n";
echo "<legend></legend>\n";
Added: mrbs/trunk/web/images/check.png
===================================================================
(Binary files differ)
Property changes on: mrbs/trunk/web/images/check.png
___________________________________________________________________
Added: svn:mime-type
+ image/png
Modified: mrbs/trunk/web/mrbs-ielte6.css
===================================================================
--- mrbs/trunk/web/mrbs-ielte6.css 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/mrbs-ielte6.css 2010-03-21 08:54:33 UTC (rev 1307)
@@ -8,6 +8,9 @@
.form_admin label {height: 2.0em} /* min-height not recognised by
IE6 and below */
.form_admin input {margin-top: 0} /* negative margins remove the
input border in IE6 */
.form_admin input.submit {display: inline} /* stops IE6 "double margin float
bug" appearing */
+div#header_column {width: 20%} /* IE6 doesn't understand
max-width */
+#header_column table {width: 100%} /* so force the table to fill all
of the 20% */
+div#body_columns {width: 80%}
/* ------------ DAY/WEEK/MONTH.PHP ------------------*/
div.cell_container {height: 100px} /* NOTE: if you change the value
of height, make sure you */
Modified: mrbs/trunk/web/mrbs.css.php
===================================================================
--- mrbs/trunk/web/mrbs.css.php 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/mrbs.css.php 2010-03-21 08:54:33 UTC (rev 1307)
@@ -99,7 +99,7 @@
width: auto; margin-top: 1.2em; margin-left: <?php echo
number_format(($admin_form_gap + $admin_form_label_width), 1, '.', '')?>em
}
.admin h2 {clear: left}
-div#area_form, div#room_form {float: left; margin: 0 0 2em 1em}
+div#area_form, div#room_form {float: left; width: 95%; padding: 0 0 2em 1em}
#area_form form {float: left; margin-right: 1em}
#area_form label#area_label {display: block; float: left; font-weight: bold;
margin-right: <?php echo $admin_form_gap ?>em}
#areaChangeForm select {display: block; float: left; margin: -0.1em 1.5em 0 0}
@@ -108,7 +108,10 @@
background-color: transparent; border: 0; padding: 0}
#areaChangeForm button img {vertical-align: middle}
-div#header_column, div#body_columns {float: left}
+div#room_info {width: 100%; float: left}
+div#header_column, div#body_columns {position: relative; float: left;
overflow-x: scroll; overflow-y: hidden}
+div#header_column {max-width: 20%}
+div#body_columns {max-width: 80%}
#room_info table {border-spacing: 0px; border-collapse: collapse;
border-color: <?php echo $admin_table_border_color ?>; border-style: solid;
border-top-width: 0; border-right-width: 1px; border-bottom-width: 1px;
border-left-width: 0}
@@ -129,7 +132,6 @@
#room_info #header_column th:first-child {border-left-color: <?php echo
$admin_table_header_back_color ?>}
-
/* ------------ DAY/WEEK/MONTH.PHP ------------------*/
<?php
Modified: mrbs/trunk/web/mysql.inc
===================================================================
--- mrbs/trunk/web/mysql.inc 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/mysql.inc 2010-03-21 08:54:33 UTC (rev 1307)
@@ -326,6 +326,92 @@
}
+// Get information about the columns in a table
+// Returns an array with the following indices for each column
+//
+// 'name' the column name
+// 'type' the type as reported by MySQL
+// 'nature' the type mapped onto one of a generic set of types
+// (boolean, integer, real, character, binary). This enables
+// the nature to be used by MRBS code when deciding how to
+// display fields, without MRBS having to worry about the
+// differences between MySQL and PostgreSQL type names.
+// 'length' the maximum length of the field in bytes, octets or
characters
+// (Note: this could be NULL)
+//
+// NOTE: the type mapping is incomplete and just covers the types commonly
+// used by MRBS
+function sql_mysql_field_info($table, $db_conn = null)
+{
+ sql_mysql_ensure_handle($db_conn);
+
+ // Map MySQL types on to a set of generic types
+ $nature_map = array('bigint' => 'integer',
+ 'char' => 'character',
+ 'double' => 'real',
+ 'float' => 'real',
+ 'int' => 'integer',
+ 'mediumint' => 'integer',
+ 'smallint' => 'integer',
+ 'text' => 'character',
+ 'tinyint' => 'integer',
+ 'tinytext' => 'character',
+ 'varchar' => 'character');
+
+ // Length in bytes of MySQL integer types
+ $int_bytes = array('bigint' => 8, // bytes
+ 'int' => 4,
+ 'mediumint' => 3,
+ 'smallint' => 2,
+ 'tinyint' => 1);
+
+ $fields = array();
+ $res = sql_mysql_query("SHOW COLUMNS FROM $table");
+ if ($res && (sql_mysql_count($res) > 0))
+ {
+ for ($i = 0; ($row = sql_mysql_row_keyed($res, $i)); $i++)
+ {
+ $name = $row['Field'];
+ $type = $row['Type'];
+ // split the type (eg 'varchar(25)') around the opening '('
+ $parts = explode('(', $type);
+ // map the type onto one of the generic natures, if a mapping exists
+ $nature = (array_key_exists($parts[0], $nature_map)) ?
$nature_map[$parts[0]] : $parts[0];
+ // now work out the length
+ if ($nature == 'integer')
+ {
+ // if it's one of the ints, then look up the length in bytes
+ $length = (array_key_exists($parts[0], $int_bytes)) ?
$int_bytes[$parts[0]] : 0;
+ }
+ elseif ($nature == 'character')
+ {
+ // if it's a character type then use the length that was in parentheses
+ // eg if it was a varchar(25), we want the 25
+ if (isset($parts[1]))
+ {
+ $length = preg_replace('/\)/', '', $parts[1]); // strip off the
closing ')'
+ }
+ // otherwise it could be any length (eg if it was a 'text')
+ else
+ {
+ $length = defined('PHP_INT_MAX') ? PHP_INT_MAX : 9999;
+ }
+ }
+ else // we're only dealing with a few simple cases at the moment
+ {
+ $length = NULL;
+ }
+
+ $fields[$i]['name'] = $name;
+ $fields[$i]['type'] = $type;
+ $fields[$i]['nature'] = $nature;
+ $fields[$i]['length'] = $length;
+ }
+ }
+ return $fields;
+}
+
+
// Connect to a database server and select a database, optionally using
// persistent connections
function sql_mysql_connect($host, $username, $password, $db_name, $persist = 0)
Modified: mrbs/trunk/web/mysqli.inc
===================================================================
--- mrbs/trunk/web/mysqli.inc 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/mysqli.inc 2010-03-21 08:54:33 UTC (rev 1307)
@@ -355,6 +355,92 @@
}
+// Get information about the columns in a table
+// Returns an array with the following indices for each column
+//
+// 'name' the column name
+// 'type' the type as reported by MySQL
+// 'nature' the type mapped onto one of a generic set of types
+// (boolean, integer, real, character, binary). This enables
+// the nature to be used by MRBS code when deciding how to
+// display fields, without MRBS having to worry about the
+// differences between MySQL and PostgreSQL type names.
+// 'length' the maximum length of the field in bytes, octets or
characters
+// (Note: this could be NULL)
+//
+// NOTE: the type mapping is incomplete and just covers the types commonly
+// used by MRBS
+function sql_mysqli_field_info($table, $db_conn = null)
+{
+ sql_mysqli_ensure_handle($db_conn);
+
+ // Map MySQL types on to a set of generic types
+ $nature_map = array('bigint' => 'integer',
+ 'char' => 'character',
+ 'double' => 'real',
+ 'float' => 'real',
+ 'int' => 'integer',
+ 'mediumint' => 'integer',
+ 'smallint' => 'integer',
+ 'text' => 'character',
+ 'tinyint' => 'integer',
+ 'tinytext' => 'character',
+ 'varchar' => 'character');
+
+ // Length in bytes of MySQL integer types
+ $int_bytes = array('bigint' => 8, // bytes
+ 'int' => 4,
+ 'mediumint' => 3,
+ 'smallint' => 2,
+ 'tinyint' => 1);
+
+ $fields = array();
+ $res = sql_mysqli_query("SHOW COLUMNS FROM $table");
+ if ($res && (sql_mysqli_count($res) > 0))
+ {
+ for ($i = 0; ($row = sql_mysqli_row_keyed($res, $i)); $i++)
+ {
+ $name = $row['Field'];
+ $type = $row['Type'];
+ // split the type (eg 'varchar(25)') around the opening '('
+ $parts = explode('(', $type);
+ // map the type onto one of the generic natures, if a mapping exists
+ $nature = (array_key_exists($parts[0], $nature_map)) ?
$nature_map[$parts[0]] : $parts[0];
+ // now work out the length
+ if ($nature == 'integer')
+ {
+ // if it's one of the ints, then look up the length in bytes
+ $length = (array_key_exists($parts[0], $int_bytes)) ?
$int_bytes[$parts[0]] : 0;
+ }
+ elseif ($nature == 'character')
+ {
+ // if it's a character type then use the length that was in parentheses
+ // eg if it was a varchar(25), we want the 25
+ if (isset($parts[1]))
+ {
+ $length = preg_replace('/\)/', '', $parts[1]); // strip off the
closing ')'
+ }
+ // otherwise it could be any length (eg if it was a 'text')
+ else
+ {
+ $length = defined('PHP_INT_MAX') ? PHP_INT_MAX : 9999;
+ }
+ }
+ else // we're only dealing with a few simple cases at the moment
+ {
+ $length = NULL;
+ }
+
+ $fields[$i]['name'] = $name;
+ $fields[$i]['type'] = $type;
+ $fields[$i]['nature'] = $nature;
+ $fields[$i]['length'] = $length;
+ }
+ }
+ return $fields;
+}
+
+
// Connect to a database server and select a database, optionally using
// persistent connections
function sql_mysqli_connect($host, $username, $password,
Modified: mrbs/trunk/web/pgsql.inc
===================================================================
--- mrbs/trunk/web/pgsql.inc 2010-03-19 09:40:34 UTC (rev 1306)
+++ mrbs/trunk/web/pgsql.inc 2010-03-21 08:54:33 UTC (rev 1307)
@@ -362,6 +362,75 @@
}
+// Get information about the columns in a table
+// Returns an array with the following indices for each column
+//
+// 'name' the column name
+// 'type' the type as reported by PostgreSQL
+// 'nature' the type mapped onto one of a generic set of types
+// (boolean, integer, real, character, binary). This enables
+// the nature to be used by MRBS code when deciding how to
+// display fields, without MRBS having to worry about the
+// differences between MySQL and PostgreSQL type names.
+// 'length' the maximum length of the field in bytes, octets or
characters
+// (Note: this could be NULL)
+//
+// NOTE: the type mapping is incomplete and just covers the types commonly
+// used by MRBS
+function sql_pgsql_field_info($table, $db_conn = null)
+{
+ sql_pgsql_ensure_handle($db_conn);
+
+ // Map PostgreSQL types on to a set of generic types
+ $nature_map = array('bigint' => 'integer',
+ 'boolean' => 'boolean',
+ 'bytea' => 'binary',
+ 'character' => 'character',
+ 'character varying' => 'character',
+ 'double precision' => 'real',
+ 'integer' => 'integer',
+ 'real' => 'real',
+ 'smallint' => 'integer',
+ 'text' => 'character');
+
+ $fields = array();
+ $res = sql_pgsql_query("SELECT column_name, data_type, numeric_precision,
+ character_maximum_length,
character_octet_length
+ FROM information_schema.columns
+ WHERE table_name ='$table'
+ ORDER BY ordinal_position");
+ if ($res && (sql_pgsql_count($res) > 0))
+ {
+ for ($i = 0; ($row = sql_pgsql_row_keyed($res, $i)); $i++)
+ {
+ $name = $row['column_name'];
+ $type = $row['data_type'];
+ // map the type onto one of the generic natures, if a mapping exists
+ $nature = (array_key_exists($type, $nature_map)) ? $nature_map[$type] :
$type;
+ // Get a length value; one of these values should be set
+ if (isset($row['numeric_precision']))
+ {
+ $length = (int) floor($row['numeric_precision'] / 8); // precision is
in bits
+ }
+ elseif (isset($row['character_maximum_length']))
+ {
+ $length = $row['character_maximum_length'];
+ }
+ elseif (isset($row['character_octet_length']))
+ {
+ $length = $row['character_octet_length'];
+ }
+
+ $fields[$i]['name'] = $name;
+ $fields[$i]['type'] = $type;
+ $fields[$i]['nature'] = $nature;
+ $fields[$i]['length'] = $length;
+ }
+ }
+ return $fields;
+}
+
+
// Connect to a database server and select a database, optionally using
// persistent connections
function sql_pgsql_connect($host, $username, $password, $db_name,
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits