Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Nextcloud
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Monitor
Service Desk
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
TeDomum
Nextcloud
Commits
c0bdbd9d
Commit
c0bdbd9d
authored
11 years ago
by
Jörn Friedrich Dreyer
Browse files
Options
Downloads
Patches
Plain Diff
introduce and use executeAudited in db.php
parent
d264d0a7
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
lib/db.php
+103
-47
103 additions, 47 deletions
lib/db.php
lib/template.php
+21
-0
21 additions, 0 deletions
lib/template.php
with
124 additions
and
47 deletions
lib/db.php
+
103
−
47
View file @
c0bdbd9d
...
...
@@ -23,7 +23,8 @@
class
DatabaseException
extends
Exception
{
private
$query
;
public
function
__construct
(
$message
,
$query
){
//FIXME getQuery seems to be unused, maybe use parent constructor with $message, $code and $previous
public
function
__construct
(
$message
,
$query
=
null
){
parent
::
__construct
(
$message
);
$this
->
query
=
$query
;
}
...
...
@@ -391,10 +392,63 @@ class OC_DB {
return
$result
;
}
/**
* @brief execute a prepared statement, on error write log and throw exception
* @param mixed $stmt PDOStatementWrapper | MDB2_Statement_Common ,
* an array with 'sql' and optionally 'limit' and 'offset' keys
* .. or a simple sql query string
* @param array $parameters
* @return result
* @throws DatabaseException
*/
static
public
function
executeAudited
(
$stmt
,
array
$parameters
=
null
)
{
if
(
is_string
(
$stmt
))
{
// convert to an array with 'sql'
if
(
stripos
(
$stmt
,
'LIMIT'
)
!==
false
)
{
//OFFSET requires LIMIT, se we only neet to check for LIMIT
// TODO try to convert LIMIT OFFSET notation to parameters, see fixLimitClauseForMSSQL
$message
=
'LIMIT and OFFSET are forbidden for portability reasons,'
.
' pass an array with \'limit\' and \'offset\' instead'
;
\OCP\Util
::
writeLog
(
'db'
,
$message
,
\OCP\Util
::
FATAL
);
throw
new
DatabaseException
(
$message
);
}
$stmt
=
array
(
'sql'
=>
$stmt
,
'limit'
=>
null
,
'offset'
=>
null
);
}
if
(
is_array
(
$stmt
)){
// convert to prepared statement
if
(
!
array_key_exists
(
'sql'
,
$stmt
)
)
{
$message
=
'statement array must at least contain key \'sql\''
;
\OCP\Util
::
writeLog
(
'db'
,
$message
,
\OCP\Util
::
FATAL
);
throw
new
DatabaseException
(
$message
);
}
if
(
!
array_key_exists
(
'limit'
,
$stmt
)
)
{
$stmt
[
'limit'
]
=
null
;
}
if
(
!
array_key_exists
(
'limit'
,
$stmt
)
)
{
$stmt
[
'offset'
]
=
null
;
}
$stmt
=
self
::
prepare
(
$stmt
[
'sql'
],
$stmt
[
'limit'
],
$stmt
[
'offset'
]);
}
self
::
raiseExceptionOnError
(
$stmt
,
'Could not prepare statement'
);
if
(
$stmt
instanceof
PDOStatementWrapper
||
$stmt
instanceof
MDB2_Statement_Common
)
{
$result
=
$stmt
->
execute
(
$parameters
);
self
::
raiseExceptionOnError
(
$result
,
'Could not execute statement'
);
}
else
{
if
(
is_object
(
$stmt
))
{
$message
=
'Expected a prepared statement or array got '
.
get_class
(
$stmt
);
}
else
{
$message
=
'Expected a prepared statement or array got '
.
gettype
(
$stmt
);
}
\OCP\Util
::
writeLog
(
'db'
,
$message
,
\OCP\Util
::
FATAL
);
throw
new
DatabaseException
(
$message
);
}
return
$result
;
}
/**
* @brief gets last value of autoincrement
* @param string $table The optional table name (will replace *PREFIX*) and add sequence suffix
* @return int id
* @throws DatabaseException
*
* MDB2 lastInsertID()
*
...
...
@@ -404,25 +458,27 @@ class OC_DB {
public
static
function
insertid
(
$table
=
null
)
{
self
::
connect
();
$type
=
OC_Config
::
getValue
(
"dbtype"
,
"sqlite"
);
if
(
$type
==
'pgsql'
)
{
$query
=
self
::
prepare
(
'SELECT lastval() AS id'
);
$row
=
$query
->
execute
()
->
fetchRow
();
if
(
$type
===
'pgsql'
)
{
$result
=
self
::
executeAudited
(
'SELECT lastval() AS id'
);
$row
=
$result
->
fetchRow
();
self
::
raiseExceptionOnError
(
$row
,
'fetching row for insertid failed'
);
return
$row
[
'id'
];
}
if
(
$type
==
'mssql'
)
{
}
else
if
(
$type
===
'mssql'
)
{
if
(
$table
!==
null
)
{
$prefix
=
OC_Config
::
getValue
(
"dbtableprefix"
,
"oc_"
);
$table
=
str_replace
(
'*PREFIX*'
,
$prefix
,
$table
);
}
re
turn
self
::
$connection
->
lastInsertId
(
$table
);
}
else
{
$
re
sult
=
self
::
$connection
->
lastInsertId
(
$table
);
}
else
{
if
(
$table
!==
null
)
{
$prefix
=
OC_Config
::
getValue
(
"dbtableprefix"
,
"oc_"
);
$suffix
=
OC_Config
::
getValue
(
"dbsequencesuffix"
,
"_id_seq"
);
$table
=
str_replace
(
'*PREFIX*'
,
$prefix
,
$table
)
.
$suffix
;
}
re
turn
self
::
$connection
->
lastInsertId
(
$table
);
$
re
sult
=
self
::
$connection
->
lastInsertId
(
$table
);
}
self
::
raiseExceptionOnError
(
$result
,
'insertid failed'
);
return
$result
;
}
/**
...
...
@@ -512,6 +568,8 @@ class OC_DB {
//clean up memory
unlink
(
$file2
);
self
::
raiseExceptionOnError
(
$definition
,
'Failed to parse the database definition'
);
// Die in case something went wrong
if
(
$definition
instanceof
MDB2_Schema_Error
)
{
...
...
@@ -528,11 +586,7 @@ class OC_DB {
$ret
=
self
::
$schema
->
createDatabase
(
$definition
);
// Die in case something went wrong
if
(
$ret
instanceof
MDB2_Error
)
{
OC_Template
::
printErrorPage
(
self
::
$MDB2
->
getDebugOutput
()
.
' '
.
$ret
->
getMessage
()
.
': '
.
$ret
->
getUserInfo
()
);
}
self
::
raiseExceptionOnError
(
$ret
,
'Failed to create the database structure'
);
return
true
;
}
...
...
@@ -552,13 +606,7 @@ class OC_DB {
$content
=
file_get_contents
(
$file
);
$previousSchema
=
self
::
$schema
->
getDefinitionFromDatabase
();
if
(
PEAR
::
isError
(
$previousSchema
))
{
$error
=
$previousSchema
->
getMessage
();
$detail
=
$previousSchema
->
getDebugInfo
();
$message
=
'Failed to get existing database structure for updating ('
.
$error
.
', '
.
$detail
.
')'
;
OC_Log
::
write
(
'core'
,
$message
,
OC_Log
::
FATAL
);
throw
new
Exception
(
$message
);
}
self
::
raiseExceptionOnError
(
$previousSchema
,
'Failed to get existing database structure for updating'
);
// Make changes and save them to an in-memory file
$file2
=
'static://db_scheme'
;
...
...
@@ -582,13 +630,7 @@ class OC_DB {
//clean up memory
unlink
(
$file2
);
if
(
PEAR
::
isError
(
$op
))
{
$error
=
$op
->
getMessage
();
$detail
=
$op
->
getDebugInfo
();
$message
=
'Failed to update database structure ('
.
$error
.
', '
.
$detail
.
')'
;
OC_Log
::
write
(
'core'
,
$message
,
OC_Log
::
FATAL
);
throw
new
Exception
(
$message
);
}
self
::
raiseExceptionOnError
(
$op
,
'Failed to update database structure'
);
return
true
;
}
...
...
@@ -641,15 +683,9 @@ class OC_DB {
}
$query
=
substr
(
$query
,
0
,
strlen
(
$query
)
-
5
);
try
{
$stmt
=
self
::
prepare
(
$query
);
$result
=
$stmt
->
execute
(
$inserts
);
}
catch
(
PDOException
$e
)
{
$entry
=
'DB Error: "'
.
$e
->
getMessage
()
.
'"<br />'
;
$entry
.
=
'Offending command was: '
.
$query
.
'<br />'
;
OC_Log
::
write
(
'core'
,
$entry
,
OC_Log
::
FATAL
);
error_log
(
'DB error: '
.
$entry
);
OC_Template
::
printErrorPage
(
$entry
);
$result
=
self
::
executeAudited
(
$query
,
$inserts
);
}
catch
(
DatabaseException
$e
)
{
OC_Template
::
printExceptionErrorPage
(
$e
);
}
if
((
int
)
$result
->
numRows
()
===
0
)
{
...
...
@@ -674,16 +710,12 @@ class OC_DB {
}
try
{
$result
=
self
::
prepare
(
$query
);
$result
=
self
::
executeAudited
(
$query
,
$inserts
);
}
catch
(
PDOException
$e
)
{
$entry
=
'DB Error: "'
.
$e
->
getMessage
()
.
'"<br />'
;
$entry
.
=
'Offending command was: '
.
$query
.
'<br />'
;
OC_Log
::
write
(
'core'
,
$entry
,
OC_Log
::
FATAL
);
error_log
(
'DB error: '
.
$entry
);
OC_Template
::
printErrorPage
(
$entry
);
OC_Template
::
printExceptionErrorPage
(
$e
);
}
return
$result
->
execute
(
$inserts
)
;
return
$result
;
}
/**
...
...
@@ -891,7 +923,33 @@ class OC_DB {
return
false
;
}
}
/**
* check if a result is an error, writes a log entry and throws an exception, works with MDB2 and PDOException
* @param mixed $result
* @param string message
* @return void
* @throws DatabaseException
*/
public
static
function
raiseExceptionOnError
(
$result
,
$message
=
null
)
{
if
(
self
::
isError
(
$result
))
{
if
(
$message
===
null
)
{
$message
=
self
::
getErrorMessage
(
$result
);
}
else
{
$message
.
=
', Root cause:'
.
self
::
getErrorMessage
(
$result
);
}
OC_Log
::
write
(
'db'
,
$message
,
OC_Log
::
FATAL
);
throw
new
DatabaseException
(
$message
,
getErrorCode
(
$result
));
}
}
public
static
function
getErrorCode
(
$error
)
{
if
(
self
::
$backend
==
self
::
BACKEND_MDB2
and
PEAR
::
isError
(
$error
)
)
{
$code
=
$error
->
getCode
();
}
elseif
(
self
::
$backend
==
self
::
BACKEND_PDO
and
self
::
$PDO
)
{
$code
=
self
::
$PDO
->
errorCode
();
}
return
$code
;
}
/**
* returns the error code and message as a string for logging
* works with MDB2 and PDOException
...
...
@@ -901,9 +959,7 @@ class OC_DB {
public
static
function
getErrorMessage
(
$error
)
{
if
(
self
::
$backend
==
self
::
BACKEND_MDB2
and
PEAR
::
isError
(
$error
)
)
{
$msg
=
$error
->
getCode
()
.
': '
.
$error
->
getMessage
();
if
(
defined
(
'DEBUG'
)
&&
DEBUG
)
{
$msg
.
=
'('
.
$error
->
getDebugInfo
()
.
')'
;
}
$msg
.
=
' ('
.
$error
->
getDebugInfo
()
.
')'
;
}
elseif
(
self
::
$backend
==
self
::
BACKEND_PDO
and
self
::
$PDO
)
{
$msg
=
self
::
$PDO
->
errorCode
()
.
': '
;
$errorInfo
=
self
::
$PDO
->
errorInfo
();
...
...
This diff is collapsed.
Click to expand it.
lib/template.php
+
21
−
0
View file @
c0bdbd9d
...
...
@@ -535,4 +535,25 @@ class OC_Template{
$content
->
printPage
();
die
();
}
/**
* print error page using Exception details
* @param Exception $exception
*/
public
static
function
printExceptionErrorPage
(
Exception
$exception
)
{
$error_msg
=
$exception
->
getMessage
();
if
(
$exception
->
getCode
())
{
$error_msg
=
'['
.
$exception
->
getCode
()
.
'] '
.
$error_msg
;
}
$hint
=
$exception
->
getTraceAsString
();
while
(
$exception
=
$exception
->
previous
())
{
$error_msg
.
=
'<br/>Caused by: '
;
if
(
$exception
->
getCode
())
{
$error_msg
.
=
'['
.
$exception
->
getCode
()
.
'] '
;
}
$error_msg
.
=
$exception
->
getMessage
();
};
self
::
printErrorPage
(
$error_msg
,
$hint
);
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment