Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: mantisbt/mantisbt
base: 2d4072892423
...
head fork: mantisbt/mantisbt
compare: b5194d98fd75
  • 9 commits
  • 8 files changed
  • 0 commit comments
  • 1 contributor
Commits on Mar 24, 2014
Damien Regad dregad Install: special processing for pgsql boolean columns
The upgrade of ADOdb library to version 4.96 with Mantis release
1.1.0 introduced a change in the way type 'L' columns are created
(SMALLINT before, BOOLEAN after).

This requires special handling to fix the database schema, because the
normal schema upgrade steps do not cover it (since from the MantisBT
installer's perspective the column type has not changed).

Fixes #16392
e2e0a9d
Damien Regad dregad Install: pgsql bool check now handles nullable columns
Issue #16392
ddba1d9
Damien Regad dregad Fix travis build errors for PostgreSQL
The errors were caused by executing queries with params in wrong order.

To fix the problem, this commit adds Database API functions to push the
current parameter number onto a stack and pop the value after query
execution, allowing build of multiple queries concurrently.

The caller can call db_param_push() when needed prior to starting the
build of a new query while another one is still pending execution.
db_query_bound() will call db_param_pop() after running the query.

Fixes #14398
592cbb9
Damien Regad dregad Move parameter count management to a class
The MantisDbParam class handles the logic for:
- assignment of parameters, db_param() calls
- push onto stack, db_param_push() calls
- pop stack
8bdc969
Damien Regad dregad Update ADOdb to latest 5.19dev 2b5a700
Damien Regad dregad Travis before script: use variable for port number
This facilitates local debugging using the PHP built-in web server when
there is another one running on default port 80.
21d0f53
Damien Regad dregad Travis: stop ignoring build failures for PostgreSQL e5ab6ea
Damien Regad dregad Coding guidelines
- $v_ prefix for extracted variables
- $t_ prefix for other local variables
37e5732
Damien Regad dregad Merge PostgreSQL fixes branch
This covers several fixes to (re-)enable support for pgsql database in
master branch, which has been broken since upgrade to unpatched ADOdb
5.11 several years ago. With these, PostgreSQL should now be
operational:

- Correct handling for booleans, including fix of installer/upgrade
  process to convert pre 1.1.0 instances SMALLINT columns to BOOLEAN
- Finally fixing the broken Travis builds. This required new DB API
  calls to push/pop the parameter count to a stack, to enable concurrent
  build of multiple queries (required as pgsql uses positional
  parameters). Initial implementation 124f79e was procedural, then I moved
  this to a simple class in d09d5ad
- ADOdb update to latest development head (includes a required fix to
  ADODB_postgres64->Param() )

Also includes .travis.yml changes to stop ignoring pgsql build failures.

Pull request #143
b5194d9
2  .travis.yml
View
@@ -27,9 +27,7 @@ branches:
- master-2.0.x
matrix:
- # Until #14398 is fixed, PostgreSQL should not cause entire build to fail
allow_failures:
- - env: DB=pgsql
# Notifications
52 admin/install.php
View
@@ -838,12 +838,62 @@ function print_test( $p_test_description, $p_result, $p_hard_fail = true, $p_mes
}
}
+ $dict = NewDataDictionary( $g_db );
+
+ # Special processing for specific schema versions
+ # This allows execution of additional install steps, which are
+ # not a Mantis schema upgrade but nevertheless required due to
+ # changes in the code
+
+ if( $t_last_update > 51 && $t_last_update < 189 ) {
+ # Since MantisBT 1.1.0 / ADOdb 4.96 (corresponding to schema 51)
+ # 'L' columns are BOOLEAN instead of SMALLINT
+ # Check for any DB discrepancies and update columns if needed
+ $t_bool_columns = check_pgsql_bool_columns();
+ if( $t_bool_columns !== true ) {
+ # Some columns need converting
+ $t_msg = "PostgreSQL: check Boolean columns' actual type";
+ if( is_array( $t_bool_columns ) ) {
+ print_test(
+ $t_msg,
+ count( $t_bool_columns ) == 0,
+ false,
+ count( $t_bool_columns ) . ' columns must be converted to BOOLEAN'
+ );
+ } else {
+ # We did not get an array => error occured
+ print_test( $t_msg, false, true, $t_bool_columns );
+ }
+
+ # Convert the columns
+ foreach( $t_bool_columns as $t_row ) {
+ extract( $t_row, EXTR_PREFIX_ALL, 'v' );
+ $t_null = $v_is_nullable ? 'NULL' : 'NOT NULL';
+ $t_default = is_null( $v_column_default ) ? 'NULL' : $v_column_default;
+ $t_sqlarray = $dict->AlterColumnSQL(
+ $v_table_name,
+ "$v_column_name L $t_null DEFAULT $t_default"
+ );
+ print_test(
+ "Converting column $v_table_name.$v_column_name to BOOLEAN",
+ 2 == $dict->ExecuteSQLArray( $t_sqlarray, false ),
+ true,
+ print_r( $t_sqlarray, true )
+ );
+ if( $g_failed ) {
+ # Error occured, bail out
+ break;
+ }
+ }
+ }
+ }
+ # End of special processing for specific schema versions
+
while(( $i <= $lastid ) && !$g_failed ) {
if( !$f_log_queries ) {
echo '<tr><td bgcolor="#ffffff">';
}
- $dict = @NewDataDictionary( $g_db );
$t_sql = true;
$t_target = $upgrade[$i][1][0];
4 core/custom_field_api.php
View
@@ -116,7 +116,7 @@ function custom_field_cache_row( $p_field_id, $p_trigger_errors = true ) {
$t_result = db_query_bound( $t_query, array( $p_field_id ) );
$t_row = db_fetch_array( $t_result );
-
+
if( !$t_row ) {
if( $p_trigger_errors ) {
error_parameters( 'Custom ' . $p_field_id );
@@ -632,6 +632,8 @@ function custom_field_get_linked_ids( $p_project_id = ALL_PROJECTS ) {
$t_custom_field_table = db_get_table( 'custom_field' );
$t_custom_field_project_table = db_get_table( 'custom_field_project' );
+ db_param_push();
+
if( ALL_PROJECTS == $p_project_id ) {
$t_project_user_list_table = db_get_table( 'project_user_list' );
$t_project_table = db_get_table( 'project' );
78 core/database_api.php
View
@@ -73,10 +73,58 @@
}
/**
- * Tracks the query parameter count for use with db_aparam:().
- * @global int $g_db_param_count
+ * Mantis Database Parameters Count class
+ * Stores the current parameter count, provides method to generate parameters
+ * and a simple stack mechanism to enable the caller to build multiple queries
+ * concurrently on RDBMS using positional parameters (e.g. PostgreSQL)
+ * @package MantisBT
+ * @subpackage classes
*/
-$g_db_param_count = 0;
+class MantisDbParam {
+ /** Current parameter count */
+ public $count = 0;
+
+ /** Parameter count stack */
+ private $stack = array();
+
+ /**
+ * Generate a string to insert a parameter into a database query string
+ * @return string 'wildcard' matching a parameter in correct ordered format for the current database.
+ */
+ public function assign() {
+ global $g_db;
+ return $g_db->Param( $this->count++ );
+ }
+
+ /**
+ * Pushes current parameter count onto stack and resets its value to 0
+ */
+ public function push() {
+ $this->stack[] = $this->count;
+ $this->count = 0;
+ }
+
+ /**
+ * Pops the previous value of param count from the stack
+ * This function is called by {@see db_query_bound()} and should not need
+ * to be executed directly
+ */
+ public function pop() {
+ global $g_db;
+
+ $this->count = (int)array_pop( $this->stack );
+ if( db_is_pgsql() ) {
+ # Manually reset the ADOdb param number to the value we just popped
+ $g_db->_pnum = $this->count;
+ }
+ }
+}
+
+/**
+ * Tracks the query parameter count
+ * @global object $g_db_param
+ */
+$g_db_param = new MantisDbParam();
/**
* Open a connection to the database.
@@ -275,6 +323,7 @@ function db_check_identifier_size( $p_identifier ) {
/**
* execute query, requires connection to be opened
* An error will be triggered if there is a problem executing the query.
+ * This will pop the database parameter stack {@see MantisDbParam} after a successful execution
* @global array of previous executed queries for profiling
* @global adodb database connection object
* @global boolean indicating whether queries array is populated
@@ -285,7 +334,7 @@ function db_check_identifier_size( $p_identifier ) {
* @return ADORecordSet|bool adodb result set or false if the query failed.
*/
function db_query_bound( $p_query, $arr_parms = null, $p_limit = -1, $p_offset = -1 ) {
- global $g_queries_array, $g_db, $g_db_log_queries, $g_db_param_count;
+ global $g_queries_array, $g_db, $g_db_log_queries, $g_db_param;
$t_db_type = config_get_global( 'db_type' );
@@ -368,28 +417,33 @@ function db_query_bound( $p_query, $arr_parms = null, $p_limit = -1, $p_offset =
array_push( $g_queries_array, array( '', $t_elapsed ) );
}
- # We can't reset the counter because we have queries being built
- # and executed while building bigger queries in filter_api. -jreese
- # $g_db_param_count = 0;
-
if( !$t_result ) {
db_error( $p_query );
trigger_error( ERROR_DB_QUERY_FAILED, ERROR );
return false;
} else {
+ $g_db_param->pop();
return $t_result;
}
}
/**
* Generate a string to insert a parameter into a database query string
- * @return string 'wildcard' matching a paramater in correct ordered format for the current database.
+ * @return string 'wildcard' matching a parameter in correct ordered format for the current database.
*/
function db_param() {
- global $g_db;
- global $g_db_param_count;
+ global $g_db_param;
+ return $g_db_param->assign();
+}
- return $g_db->Param( $g_db_param_count++ );
+/**
+ * Pushes current parameter count onto stack and resets its value
+ * Allows the caller to build multiple queries concurrently on RDBMS using
+ * positional parameters (e.g. PostgreSQL)
+ */
+function db_param_push() {
+ global $g_db_param;
+ $g_db_param->push();
}
/**
59 core/install_helper_functions_api.php
View
@@ -82,6 +82,65 @@ function db_unixtimestamp( $p_date = null, $p_gmt = false ) {
}
/**
+ * Check PostgreSQL boolean columns' type in the DB
+ * Verifies that columns defined as type "L" (logical) in the Mantis schema
+ * have the correct type in the underlying database.
+ * The ADOdb library bundled with MantisBT releases prior to 1.1.0 (schema
+ * version 51) created type "L" columns in PostgreSQL as SMALLINT, whereas later
+ * versions created them as BOOLEAN.
+ * @return mixed true if columns check OK
+ * error message string if errors occured
+ * array of invalid columns otherwise (empty if all columns check OK)
+ */
+function check_pgsql_bool_columns() {
+ global $f_db_type, $f_database_name;
+ global $g_db;
+
+ # Only applies to PostgreSQL
+ if( $f_db_type != 'pgsql' ) {
+ return true;
+ }
+
+ # Build the list of "L" type columns as of schema version 51
+ $t_bool_columns = array(
+ 'bug' => array( 'sticky' ),
+ 'custom_field' => array( 'advanced', 'require_report', 'require_update', 'display_report', 'display_update', 'require_resolved', 'display_resolved', 'display_closed', 'require_closed' ),
+ 'filters' => array( 'is_public' ),
+ 'news' => array( 'announcement' ),
+ 'project' => array( 'enabled' ),
+ 'project_version' => array( 'released' ),
+ 'sponsorship' => array( 'paid' ),
+ 'user_pref' => array( 'advanced_report', 'advanced_view', 'advanced_update', 'redirect_delay', 'email_on_new', 'email_on_assigned', 'email_on_feedback', 'email_on_resolved', 'email_on_closed', 'email_on_reopened', 'email_on_bugnote', 'email_on_status', 'email_on_priority' ),
+ 'user' => array( 'enabled', 'protected' ),
+ );
+
+ # Generate SQL to check columns against schema
+ $t_where = '';
+ foreach( $t_bool_columns as $t_table_name => $t_columns ) {
+ $t_table = db_get_table( $t_table_name );
+ $t_where .= "table_name = '$t_table' AND column_name IN ( '"
+ . implode($t_columns, "', '")
+ . "' ) OR\n";
+ }
+ $sql = "SELECT table_name, column_name, data_type, column_default, is_nullable
+ FROM information_schema.columns
+ WHERE
+ table_catalog = '$f_database_name' AND
+ data_type <> 'boolean' AND
+ (\n" . rtrim( $t_where, " OR\n" ) . "\n)";
+
+ $t_result = @$g_db->Execute( $sql );
+ if( $t_result === false ) {
+ return 'Unable to check information_schema';
+ } else if( $t_result->RecordCount() == 0 ) {
+ return array();
+ }
+
+ # Some columns are not BOOLEAN type, return the list
+ return $t_result->GetArray();
+}
+
+/**
* Set the value of $g_db_log_queries as specified
* This is used by install callback functions to ensure that only the relevant
* queries are logged
2  core/user_api.php
View
@@ -1033,6 +1033,8 @@ function user_get_accessible_subprojects( $p_user_id, $p_project_id, $p_show_dis
$t_project_user_list_table = db_get_table( 'project_user_list' );
$t_project_hierarchy_table = db_get_table( 'project_hierarchy' );
+ db_param_push();
+
if( access_has_global_level( config_get( 'private_project_threshold' ), $p_user_id ) ) {
$t_enabled_clause = $p_show_disabled ? '' : 'p.enabled = ' . db_param() . ' AND';
$query = "SELECT DISTINCT p.id, p.name, ph.parent_id
2  library/adodb
@@ -1 +1 @@
-Subproject commit 1208307846b90c9d5594f3163451c5039c45bbef
+Subproject commit c1abd33cf8f4c67a98f559a0028f39d8194b21f0
5 scripts/travis_before_script.sh
View
@@ -5,6 +5,7 @@
# Global variables initialization
HOSTNAME=localhost
+PORT=80
MANTIS_DB_NAME=bugtracker
MANTIS_BOOTSTRAP=tests/bootstrap.php
@@ -82,7 +83,7 @@ else
# get path of PHP as the path is not in $PATH for sudo
myphp=$(which php)
# sudo needed for port 80
- sudo $myphp -S $HOSTNAME:80 &
+ sudo $myphp -S $HOSTNAME:$PORT &
fi
# wait until server is up
@@ -114,7 +115,7 @@ do
done
# trigger installation
-curl --data "${query_string:1}" http://$HOSTNAME/admin/install.php
+curl --data "${query_string:1}" http://$HOSTNAME:$PORT/admin/install.php
# -----------------------------------------------------------------------------

No commit comments for this range

Something went wrong with that request. Please try again.