Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Q
question2answer
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
outils
question2answer
Commits
769b2d38
Commit
769b2d38
authored
Jan 12, 2017
by
Scott
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Coding style (qa-db.php)
parent
b507ca2f
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
220 additions
and
175 deletions
+220
-175
qa-db.php
qa-include/qa-db.php
+220
-175
No files found.
qa-include/qa-db.php
View file @
769b2d38
...
...
@@ -20,32 +20,34 @@
More about this license: http://www.question2answer.org/license.php
*/
if
(
!
defined
(
'QA_VERSION'
))
{
// don't allow this page to be requested directly from browser
if
(
!
defined
(
'QA_VERSION'
))
{
// don't allow this page to be requested directly from browser
header
(
'Location: ../'
);
exit
;
}
}
/**
/**
* Indicates to the Q2A database layer that database connections are permitted fro this point forwards
* (before this point, some plugins may not have had a chance to override some database access functions).
*/
function
qa_db_allow_connect
()
{
function
qa_db_allow_connect
()
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
global
$qa_db_allow_connect
;
$qa_db_allow_connect
=
true
;
}
$qa_db_allow_connect
=
true
;
}
/**
/**
* Connect to the Q2A database, select the right database, optionally install the $failhandler (and call it if necessary).
* Uses mysqli as of Q2A 1.7.
* @param null $failhandler
* @return mixed|void
*/
function
qa_db_connect
(
$failhandler
=
null
)
{
function
qa_db_connect
(
$failhandler
=
null
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
global
$qa_db_connection
,
$qa_db_fail_handler
,
$qa_db_allow_connect
;
...
...
@@ -74,7 +76,7 @@
}
if
(
QA_PERSISTENT_CONN_DB
)
$host
=
'p:'
.
$host
;
$host
=
'p:'
.
$host
;
// in mysqli we connect and select database in constructor
if
(
$port
!==
null
)
...
...
@@ -95,15 +97,20 @@
qa_report_process_stage
(
'db_connected'
);
$qa_db_connection
=
$db
;
}
$qa_db_connection
=
$db
;
}
/**
/**
* If a DB error occurs, call the installed fail handler (if any) otherwise report error and exit immediately.
* @param $type
* @param int $errno
* @param string $error
* @param string $query
* @return mixed
*/
function
qa_db_fail_error
(
$type
,
$errno
=
null
,
$error
=
null
,
$query
=
null
)
{
function
qa_db_fail_error
(
$type
,
$errno
=
null
,
$error
=
null
,
$query
=
null
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
global
$qa_db_fail_handler
;
...
...
@@ -119,14 +126,16 @@
);
qa_exit
(
'error'
);
}
}
}
/**
/**
* Return the current connection to the Q2A database, connecting if necessary and $connect is true.
* @param bool $connect
* @return mixed
*/
function
qa_db_connection
(
$connect
=
true
)
{
function
qa_db_connection
(
$connect
=
true
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
global
$qa_db_connection
;
...
...
@@ -139,14 +148,14 @@
}
return
$qa_db_connection
;
}
}
/**
/**
* Disconnect from the Q2A database.
*/
function
qa_db_disconnect
()
{
function
qa_db_disconnect
()
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
global
$qa_db_connection
;
...
...
@@ -159,17 +168,19 @@
qa_fatal_error
(
'Database disconnect failed'
);
}
$qa_db_connection
=
null
;
}
$qa_db_connection
=
null
;
}
}
/**
/**
* Run the raw $query, call the global failure handler if necessary, otherwise return the result resource.
* If appropriate, also track the resources used by database queries, and the queries themselves, for performance debugging.
* @param $query
* @return mixed
*/
function
qa_db_query_raw
(
$query
)
{
function
qa_db_query_raw
(
$query
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
if
(
QA_DEBUG_PERFORMANCE
)
{
...
...
@@ -188,8 +199,7 @@
}
$qa_usage
->
logDatabaseQuery
(
$query
,
$usedtime
,
$gotrows
,
$gotcolumns
);
}
else
}
else
$result
=
qa_db_query_execute
(
$query
);
// @error_log('Question2Answer MySQL query: '.$query);
...
...
@@ -200,14 +210,16 @@
}
return
$result
;
}
}
/**
/**
* Lower-level function to execute a query, which automatically retries if there is a MySQL deadlock error.
* @param $query
* @return mixed
*/
function
qa_db_query_execute
(
$query
)
{
function
qa_db_query_execute
(
$query
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
$db
=
qa_db_connection
();
...
...
@@ -222,57 +234,63 @@
}
return
$result
;
}
}
/**
/**
* Return $string escaped for use in queries to the Q2A database (to which a connection must have been made).
* @param $string
* @return mixed
*/
function
qa_db_escape_string
(
$string
)
{
function
qa_db_escape_string
(
$string
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
$db
=
qa_db_connection
();
return
$db
->
real_escape_string
(
$string
);
}
}
/**
/**
* Return $argument escaped for MySQL. Add quotes around it if $alwaysquote is true or it's not numeric.
* If $argument is an array, return a comma-separated list of escaped elements, with or without $arraybrackets.
* @param $argument
* @param $alwaysquote
* @param bool $arraybrackets
* @return mixed|string
*/
function
qa_db_argument_to_mysql
(
$argument
,
$alwaysquote
,
$arraybrackets
=
false
)
{
function
qa_db_argument_to_mysql
(
$argument
,
$alwaysquote
,
$arraybrackets
=
false
)
{
if
(
is_array
(
$argument
))
{
$parts
=
array
();
$parts
=
array
();
foreach
(
$argument
as
$subargument
)
$parts
[]
=
qa_db_argument_to_mysql
(
$subargument
,
$alwaysquote
,
true
);
if
(
$arraybrackets
)
$result
=
'('
.
implode
(
','
,
$parts
)
.
')'
;
$result
=
'('
.
implode
(
','
,
$parts
)
.
')'
;
else
$result
=
implode
(
','
,
$parts
);
}
elseif
(
isset
(
$argument
))
{
}
elseif
(
isset
(
$argument
))
{
if
(
$alwaysquote
||
!
is_numeric
(
$argument
))
$result
=
"'"
.
qa_db_escape_string
(
$argument
)
.
"'"
;
$result
=
"'"
.
qa_db_escape_string
(
$argument
)
.
"'"
;
else
$result
=
qa_db_escape_string
(
$argument
);
}
else
}
else
$result
=
'NULL'
;
return
$result
;
}
}
/**
/**
* Return the full name (with prefix) of database table $rawname, usually if it used after a ^ symbol.
* @param $rawname
* @return string
*/
function
qa_db_add_table_prefix
(
$rawname
)
{
function
qa_db_add_table_prefix
(
$rawname
)
{
if
(
qa_to_override
(
__FUNCTION__
))
{
$args
=
func_get_args
();
return
qa_call_override
(
__FUNCTION__
,
$args
);
}
$prefix
=
QA_MYSQL_TABLE_PREFIX
;
...
...
@@ -294,28 +312,33 @@
}
}
return
$prefix
.
$rawname
;
}
return
$prefix
.
$rawname
;
}
/**
/**
* Callback function to add table prefixes, as used in qa_db_apply_sub().
* @param $matches
* @return string
*/
function
qa_db_prefix_callback
(
$matches
)
{
function
qa_db_prefix_callback
(
$matches
)
{
return
qa_db_add_table_prefix
(
$matches
[
1
]);
}
}
/**
/**
* Substitute ^, $ and # symbols in $query. ^ symbols are replaced with the table prefix set in qa-config.php.
* $ and # symbols are replaced in order by the corresponding element in $arguments (if the element is an array,
* it is converted recursively into comma-separated list). Each element in $arguments is escaped.
* $ is replaced by the argument in quotes (even if it's a number), # only adds quotes if the argument is non-numeric.
* It's important to use $ when matching a textual column since MySQL won't use indexes to compare text against numbers.
* @param $query
* @param $arguments
* @return mixed
*/
function
qa_db_apply_sub
(
$query
,
$arguments
)
{
function
qa_db_apply_sub
(
$query
,
$arguments
)
{
$query
=
preg_replace_callback
(
'/\^([A-Za-z_0-9]+)/'
,
'qa_db_prefix_callback'
,
$query
);
if
(
!
is_array
(
$arguments
))
...
...
@@ -331,14 +354,13 @@
if
(
$stringpos
===
false
||
(
$numberpos
!==
false
&&
$numberpos
<
$stringpos
))
{
$alwaysquote
=
false
;
$position
=
$numberpos
;
}
else
{
}
else
{
$alwaysquote
=
true
;
$position
=
$stringpos
;
}
if
(
!
is_numeric
(
$position
))
qa_fatal_error
(
'Insufficient parameters in query: '
.
$query
);
qa_fatal_error
(
'Insufficient parameters in query: '
.
$query
);
$value
=
qa_db_argument_to_mysql
(
$arguments
[
$argument
],
$alwaysquote
);
$query
=
substr_replace
(
$query
,
$value
,
$position
,
1
);
...
...
@@ -346,88 +368,92 @@
}
return
$query
;
}
}
/**
/**
* Run $query after substituting ^, # and $ symbols, and return the result resource (or call fail handler).
* @param $query
* @return mixed
*/
function
qa_db_query_sub
(
$query
)
// arguments for substitution retrieved using func_get_args()
{
$funcargs
=
func_get_args
();
function
qa_db_query_sub
(
$query
)
// arguments for substitution retrieved using func_get_args()
{
$funcargs
=
func_get_args
();
return
qa_db_query_raw
(
qa_db_apply_sub
(
$query
,
array_slice
(
$funcargs
,
1
)));
}
}
/**
/**
* Return the number of rows in $result. (Simple wrapper for mysqli_result::num_rows.)
* @param $result
* @return int
*/
function
qa_db_num_rows
(
$result
)
{
function
qa_db_num_rows
(
$result
)
{
if
(
$result
instanceof
mysqli_result
)
return
$result
->
num_rows
;
return
0
;
}
}
/**
/**
* Return the value of the auto-increment column for the last inserted row.
*/
function
qa_db_last_insert_id
()
{
function
qa_db_last_insert_id
()
{
$db
=
qa_db_connection
();
return
$db
->
insert_id
;
}
}
/**
/**
* Return the number of rows affected by the last query.
*/
function
qa_db_affected_rows
()
{
function
qa_db_affected_rows
()
{
$db
=
qa_db_connection
();
return
$db
->
affected_rows
;
}
}
/**
/**
* For the previous INSERT ... ON DUPLICATE KEY UPDATE query, return whether an insert operation took place.
*/
function
qa_db_insert_on_duplicate_inserted
()
{
function
qa_db_insert_on_duplicate_inserted
()
{
return
(
qa_db_affected_rows
()
==
1
);
}
}
/**
/**
* Return a random integer (as a string) for use in a BIGINT column.
* Actual limit is 18,446,744,073,709,551,615 - we aim for 18,446,743,999,999,999,999.
*/
function
qa_db_random_bigint
()
{
function
qa_db_random_bigint
()
{
return
sprintf
(
'%d%06d%06d'
,
mt_rand
(
1
,
18446743
),
mt_rand
(
0
,
999999
),
mt_rand
(
0
,
999999
));
}
}
/**
/**
* Return an array of the names of all tables in the Q2A database, converted to lower case.
* No longer used by Q2A and shouldn't be needed.
*/
function
qa_db_list_tables_lc
()
{
function
qa_db_list_tables_lc
()
{
return
array_map
(
'strtolower'
,
qa_db_list_tables
());
}
}
/**
/**
* Return an array of the names of all tables in the Q2A database.
*/
function
qa_db_list_tables
()
{
function
qa_db_list_tables
()
{
return
qa_db_read_all_values
(
qa_db_query_raw
(
'SHOW TABLES'
));
}
}
/*
...
...
@@ -476,11 +502,13 @@
*/
/**
/**
* Return the data specified by a single $selectspec - see long comment above.
* @param $selectspec
* @return array|mixed
*/
function
qa_db_single_select
(
$selectspec
)
{
function
qa_db_single_select
(
$selectspec
)
{
// check for cached results
if
(
isset
(
$selectspec
[
'caching'
]))
{
$cacheHandler
=
Q2A_Storage_CacheManager
::
getInstance
();
...
...
@@ -496,10 +524,10 @@
$query
=
'SELECT '
;
foreach
(
$selectspec
[
'columns'
]
as
$columnas
=>
$columnfrom
)
$query
.=
$columnfrom
.
(
is_int
(
$columnas
)
?
''
:
(
' AS '
.
$columnas
))
.
', '
;
$query
.=
$columnfrom
.
(
is_int
(
$columnas
)
?
''
:
(
' AS '
.
$columnas
))
.
', '
;
$results
=
qa_db_read_all_assoc
(
qa_db_query_raw
(
qa_db_apply_sub
(
substr
(
$query
,
0
,
-
2
)
.
(
strlen
(
@
$selectspec
[
'source'
])
?
(
' FROM '
.
$selectspec
[
'source'
])
:
''
),
substr
(
$query
,
0
,
-
2
)
.
(
strlen
(
@
$selectspec
[
'source'
])
?
(
' FROM '
.
$selectspec
[
'source'
])
:
''
),
@
$selectspec
[
'arguments'
])
),
@
$selectspec
[
'arraykey'
]);
// arrayvalue is applied in qa_db_post_select()
...
...
@@ -513,25 +541,27 @@
}
return
$results
;
}
}
/**
/**
* Return the data specified by each element of $selectspecs, where the keys of the
* returned array match the keys of the supplied $selectspecs array. See long comment above.
* @param array $selectspecs
* @return array
*/
function
qa_db_multi_select
(
$selectspecs
)
{
function
qa_db_multi_select
(
$selectspecs
)
{
if
(
!
count
(
$selectspecs
))
return
array
();
// Perform simple queries if the database is local or there are only 0 or 1 selectspecs
if
(
!
QA_OPTIMIZE_DISTANT_DB
||
(
count
(
$selectspecs
)
<=
1
))
{
$outresults
=
array
();
if
(
!
QA_OPTIMIZE_DISTANT_DB
||
(
count
(
$selectspecs
)
<=
1
))
{
$outresults
=
array
();
foreach
(
$selectspecs
as
$selectkey
=>
$selectspec
)
$outresults
[
$selectkey
]
=
qa_db_single_select
(
$selectspec
);
$outresults
[
$selectkey
]
=
qa_db_single_select
(
$selectspec
);
return
$outresults
;
}
...
...
@@ -539,20 +569,20 @@
// Otherwise, parse columns for each spec to deal with columns without an 'AS' specification
foreach
(
$selectspecs
as
$selectkey
=>
$selectspec
)
{
$selectspecs
[
$selectkey
][
'outcolumns'
]
=
array
();
$selectspecs
[
$selectkey
][
'autocolumn'
]
=
array
();
$selectspecs
[
$selectkey
][
'outcolumns'
]
=
array
();
$selectspecs
[
$selectkey
][
'autocolumn'
]
=
array
();
foreach
(
$selectspec
[
'columns'
]
as
$columnas
=>
$columnfrom
)
{
if
(
is_int
(
$columnas
))
{
$periodpos
=
strpos
(
$columnfrom
,
'.'
);
$columnas
=
is_numeric
(
$periodpos
)
?
substr
(
$columnfrom
,
$periodpos
+
1
)
:
$columnfrom
;
$selectspecs
[
$selectkey
][
'autocolumn'
][
$columnas
]
=
true
;
$periodpos
=
strpos
(
$columnfrom
,
'.'
);
$columnas
=
is_numeric
(
$periodpos
)
?
substr
(
$columnfrom
,
$periodpos
+
1
)
:
$columnfrom
;
$selectspecs
[
$selectkey
][
'autocolumn'
][
$columnas
]
=
true
;
}
if
(
isset
(
$selectspecs
[
$selectkey
][
'outcolumns'
][
$columnas
]))
qa_fatal_error
(
'Duplicate column name in qa_db_multi_select()'
);
$selectspecs
[
$selectkey
][
'outcolumns'
][
$columnas
]
=
$columnfrom
;
$selectspecs
[
$selectkey
][
'outcolumns'
][
$columnas
]
=
$columnfrom
;
}
if
(
isset
(
$selectspec
[
'arraykey'
]))
...
...
@@ -566,54 +596,54 @@
// Work out the full list of columns used
$outcolumns
=
array
();
$outcolumns
=
array
();
foreach
(
$selectspecs
as
$selectspec
)
$outcolumns
=
array_unique
(
array_merge
(
$outcolumns
,
array_keys
(
$selectspec
[
'outcolumns'
])));
$outcolumns
=
array_unique
(
array_merge
(
$outcolumns
,
array_keys
(
$selectspec
[
'outcolumns'
])));
// Build the query based on this full list
$query
=
''
;
$query
=
''
;
foreach
(
$selectspecs
as
$selectkey
=>
$selectspec
)
{
$subquery
=
"(SELECT '"
.
qa_db_escape_string
(
$selectkey
)
.
"'"
.
(
empty
(
$query
)
?
' AS selectkey'
:
''
);
$subquery
=
"(SELECT '"
.
qa_db_escape_string
(
$selectkey
)
.
"'"
.
(
empty
(
$query
)
?
' AS selectkey'
:
''
);
foreach
(
$outcolumns
as
$columnas
)
{
$subquery
.=
', '
.
(
isset
(
$selectspec
[
'outcolumns'
][
$columnas
])
?
$selectspec
[
'outcolumns'
][
$columnas
]
:
'NULL'
);
$subquery
.=
', '
.
(
isset
(
$selectspec
[
'outcolumns'
][
$columnas
])
?
$selectspec
[
'outcolumns'
][
$columnas
]
:
'NULL'
);
if
(
empty
(
$query
)
&&
!
isset
(
$selectspec
[
'autocolumn'
][
$columnas
]))
$subquery
.=
' AS '
.
$columnas
;
$subquery
.=
' AS '
.
$columnas
;
}
if
(
strlen
(
@
$selectspec
[
'source'
]))
$subquery
.=
' FROM '
.
$selectspec
[
'source'
];
$subquery
.=
' FROM '
.
$selectspec
[
'source'
];
$subquery
.=
')'
;
$subquery
.=
')'
;
if
(
strlen
(
$query
))
$query
.=
' UNION ALL '
;
$query
.=
' UNION ALL '
;
$query
.=
qa_db_apply_sub
(
$subquery
,
@
$selectspec
[
'arguments'
]);
$query
.=
qa_db_apply_sub
(
$subquery
,
@
$selectspec
[
'arguments'
]);
}
// Perform query and extract results
$rawresults
=
qa_db_read_all_assoc
(
qa_db_query_raw
(
$query
));
$rawresults
=
qa_db_read_all_assoc
(
qa_db_query_raw
(
$query
));
$outresults
=
array
();
$outresults
=
array
();
foreach
(
$selectspecs
as
$selectkey
=>
$selectspec
)
$outresults
[
$selectkey
]
=
array
();
$outresults
[
$selectkey
]
=
array
();
foreach
(
$rawresults
as
$rawresult
)
{
$selectkey
=
$rawresult
[
'selectkey'
];
$selectspec
=
$selectspecs
[
$selectkey
];
$selectkey
=
$rawresult
[
'selectkey'
];
$selectspec
=
$selectspecs
[
$selectkey
];
$keepresult
=
array
();
$keepresult
=
array
();
foreach
(
$selectspec
[
'outcolumns'
]
as
$columnas
=>
$columnfrom
)
$keepresult
[
$columnas
]
=
$rawresult
[
$columnas
];
$keepresult
[
$columnas
]
=
$rawresult
[
$columnas
];
if
(
isset
(
$selectspec
[
'arraykey'
]))
$outresults
[
$selectkey
][
$keepresult
[
$selectspec
[
'arraykey'
]]]
=
$keepresult
;
$outresults
[
$selectkey
][
$keepresult
[
$selectspec
[
'arraykey'
]]]
=
$keepresult
;
else
$outresults
[
$selectkey
][]
=
$keepresult
;
$outresults
[
$selectkey
][]
=
$keepresult
;
}
// Post-processing to apply various stuff include sorting request, since we can't rely on ORDER BY due to UNION
...
...
@@ -624,59 +654,65 @@
// Return results
return
$outresults
;
}
}
/**
/**
* Post-process $outresult according to $selectspec, applying 'sortasc', 'sortdesc', 'arrayvalue' and 'single'.
* @param array $outresult
* @param array $selectspec
*/
function
qa_db_post_select
(
&
$outresult
,
$selectspec
)
{
function
qa_db_post_select
(
&
$outresult
,
$selectspec
)
{
// PHP's sorting algorithm is not 'stable', so we use '_order_' element to keep stability.
// By contrast, MySQL's ORDER BY does seem to give the results in a reliable order.
if
(
isset
(
$selectspec
[
'sortasc'
]))
{
require_once
QA_INCLUDE_DIR
.
'util/sort.php'
;
require_once
QA_INCLUDE_DIR
.
'util/sort.php'
;
$index
=
0
;
$index
=
0
;
foreach
(
$outresult
as
$key
=>
$value
)
$outresult
[
$key
][
'_order_'
]
=
$index
++
;
$outresult
[
$key
][
'_order_'
]
=
$index
++
;
qa_sort_by
(
$outresult
,
$selectspec
[
'sortasc'
],
'_order_'
);
}
elseif
(
isset
(
$selectspec
[
'sortdesc'
]))
{
require_once
QA_INCLUDE_DIR
.
'util/sort.php'
;
require_once
QA_INCLUDE_DIR
.
'util/sort.php'
;
if
(
isset
(
$selectspec
[
'sortdesc_2'
]))
qa_sort_by
(
$outresult
,
$selectspec
[
'sortdesc'
],
$selectspec
[
'sortdesc_2'
]);
else
{
$index
=
count
(
$outresult
);
$index
=
count
(
$outresult
);
foreach
(
$outresult
as
$key
=>
$value
)
$outresult
[
$key
][
'_order_'
]
=
$index
--
;
$outresult
[
$key
][
'_order_'
]
=
$index
--
;
qa_sort_by
(
$outresult
,
$selectspec
[
'sortdesc'
],
'_order_'
);
}
$outresult
=
array_reverse
(
$outresult
,
true
);
$outresult
=
array_reverse
(
$outresult
,
true
);
}
if
(
isset
(
$selectspec
[
'arrayvalue'
]))
foreach
(
$outresult
as
$key
=>
$value
)
$outresult
[
$key
]
=
$value
[
$selectspec
[
'arrayvalue'
]];
$outresult
[
$key
]
=
$value
[
$selectspec
[
'arrayvalue'
]];
if
(
@
$selectspec
[
'single'
])
$outresult
=
count
(
$outresult
)
?
reset
(
$outresult
)
:
null
;
}
$outresult
=
count
(
$outresult
)
?
reset
(
$outresult
)
:
null
;
}
/**
/**
* Return the full results from the $result resource as an array. The key of each element in the returned array
* is from column $key if specified, otherwise it's integer. The value of each element in the returned array
* is from column $value if specified, otherwise it's a named array of all columns, given an array of arrays.
* @param $result
* @param string $key
* @param mixed $value
* @return array
*/
function
qa_db_read_all_assoc
(
$result
,
$key
=
null
,
$value
=
null
)
{
function
qa_db_read_all_assoc
(
$result
,
$key
=
null
,
$value
=
null
)
{
if
(
!
(
$result
instanceof
mysqli_result
))
qa_fatal_error
(
'Reading all assoc from invalid result'
);
...
...
@@ -690,15 +726,18 @@
}
return
$assocs
;
}
}
/**
/**
* Return the first row from the $result resource as an array of [column name] => [column value].
* If there's no first row, throw a fatal error unless $allowempty is true.
* @param $result
* @param bool $allowempty
* @return array|null
*/
function
qa_db_read_one_assoc
(
$result
,
$allowempty
=
false
)
{
function
qa_db_read_one_assoc
(
$result
,
$allowempty
=
false
)
{
if
(
!
(
$result
instanceof
mysqli_result
))
qa_fatal_error
(
'Reading one assoc from invalid result'
);
...
...
@@ -711,14 +750,16 @@
return
null
;
else
qa_fatal_error
(
'Reading one assoc from empty results'
);
}
}
/**
/**
* Return a numbered array containing the first (and presumably only) column from the $result resource.
* @param $result
* @return array
*/
function
qa_db_read_all_values
(
$result
)
{
function
qa_db_read_all_values
(
$result
)
{
if
(
!
(
$result
instanceof
mysqli_result
))
qa_fatal_error
(
'Reading column from invalid result'
);
...
...
@@ -728,15 +769,18 @@
$output
[]
=
$row
[
0
];
return
$output
;
}
}
/**
/**
* Return the first column of the first row (and presumably only cell) from the $result resource.
* If there's no first row, throw a fatal error unless $allowempty is true.
* @param $result
* @param bool $allowempty
* @return mixed|null
*/
function
qa_db_read_one_value
(
$result
,
$allowempty
=
false
)
{
function
qa_db_read_one_value
(
$result
,
$allowempty
=
false
)
{
if
(
!
(
$result
instanceof
mysqli_result
))
qa_fatal_error
(
'Reading one value from invalid result'
);
...
...
@@ -749,27 +793,28 @@
return
null
;
else
qa_fatal_error
(
'Reading one value from empty results'
);
}
}
/**
/**
* Suspend the updating of counts (of many different types) in the database, to save time when making a lot of changes
* if $suspend is true, otherwise reinstate it. A counter is kept to allow multiple calls.
* @param bool $suspend
*/
function
qa_suspend_update_counts
(
$suspend
=
true
)
{
function
qa_suspend_update_counts
(
$suspend
=
true
)
{
global
$qa_update_counts_suspended
;
$qa_update_counts_suspended
+=
(
$suspend
?
1
:
-
1
);
}
}
/**
/**
* Returns whether counts should currently be updated (i.e. if count updating has not been suspended).
*/
function
qa_should_update_counts
()
{
function
qa_should_update_counts
()
{
global
$qa_update_counts_suspended
;
return
(
$qa_update_counts_suspended
<=
0
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment