mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
Sql: Refactored SQL 'default app cursor', added per-thread SQL option, added secondary SQLR 'default app cursor'
git-svn-id: svn://ultimatepp.org/upp/trunk@4290 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
fa7fe19881
commit
988e51f30a
14 changed files with 913 additions and 788 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#if defined(flagMT)
|
#if defined(flagMT)
|
||||||
#define _MULTITHREADED
|
#define _MULTITHREADED
|
||||||
|
#define MULTITHREADED
|
||||||
#ifdef flagDLL
|
#ifdef flagDLL
|
||||||
#define flagUSEMALLOC
|
#define flagUSEMALLOC
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ bool MySqlSession::Open(const char *connect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MySqlSession::Close() {
|
void MySqlSession::Close() {
|
||||||
|
SessionClose();
|
||||||
if(mysql) {
|
if(mysql) {
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
mysql = NULL;
|
mysql = NULL;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PLATFORM_POSIX
|
#ifdef PLATFORM_POSIX
|
||||||
#include </usr/include/mysql/mysql.h>
|
#include <mysql/mysql.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NAMESPACE_UPP
|
NAMESPACE_UPP
|
||||||
|
|
|
||||||
|
|
@ -101,5 +101,7 @@
|
||||||
|
|
||||||
#undef UNIQUE
|
#undef UNIQUE
|
||||||
|
|
||||||
|
#undef REFERENCES
|
||||||
|
|
||||||
#undef TIMESTAMP
|
#undef TIMESTAMP
|
||||||
#undef COMMENT
|
#undef COMMENT
|
||||||
|
|
|
||||||
1133
uppsrc/ODBC/ODBC.cpp
1133
uppsrc/ODBC/ODBC.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -830,6 +830,7 @@ SqlConnection *Oracle7::CreateConnection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Oracle7::Close() {
|
void Oracle7::Close() {
|
||||||
|
SessionClose();
|
||||||
while(!clink.IsEmpty()) {
|
while(!clink.IsEmpty()) {
|
||||||
clink.GetNext()->Clear();
|
clink.GetNext()->Clear();
|
||||||
clink.GetNext()->Unlink();
|
clink.GetNext()->Unlink();
|
||||||
|
|
|
||||||
|
|
@ -1304,6 +1304,7 @@ bool Oracle8::Login(const char *name, const char *pwd, const char *db, bool use_
|
||||||
}
|
}
|
||||||
|
|
||||||
void Oracle8::Logoff() {
|
void Oracle8::Logoff() {
|
||||||
|
SessionClose();
|
||||||
LOG("Oracle8::Logoff, #" << conn_count << " connections pending");
|
LOG("Oracle8::Logoff, #" << conn_count << " connections pending");
|
||||||
while(!clink.IsEmpty()) {
|
while(!clink.IsEmpty()) {
|
||||||
clink.GetNext()->Clear();
|
clink.GetNext()->Clear();
|
||||||
|
|
|
||||||
|
|
@ -397,11 +397,7 @@ void PostgreSQLSession::Close()
|
||||||
{
|
{
|
||||||
if(!conn)
|
if(!conn)
|
||||||
return;
|
return;
|
||||||
#ifndef flagNOAPPSQL
|
SessionClose();
|
||||||
if(SQL.IsOpen() && &SQL.GetSession() == this)
|
|
||||||
SQL.Cancel();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PQfinish(conn);
|
PQfinish(conn);
|
||||||
conn = NULL;
|
conn = NULL;
|
||||||
level = 0;
|
level = 0;
|
||||||
|
|
|
||||||
113
uppsrc/Sql/Script.cpp
Normal file
113
uppsrc/Sql/Script.cpp
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
#include "Sql.h"
|
||||||
|
|
||||||
|
NAMESPACE_UPP
|
||||||
|
|
||||||
|
bool StdStatementExecutor::Execute(const String& stmt)
|
||||||
|
{
|
||||||
|
cursor.Execute(stmt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NOAPPSQL
|
||||||
|
struct SQLStatementExecutorClass : StatementExecutor {
|
||||||
|
virtual bool Execute(const String& stmt) { SQL.Execute(stmt); return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
StatementExecutor& SQLStatementExecutor() {
|
||||||
|
return Single<SQLStatementExecutorClass>();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool SqlPerformScript(SqlSession& session, Stream& script,
|
||||||
|
Gate2<int, int> progress_canceled, bool stoponerror)
|
||||||
|
{
|
||||||
|
String stmt;
|
||||||
|
int level = 0;
|
||||||
|
bool ok = true;
|
||||||
|
while(!script.IsEof()) {
|
||||||
|
int c = script.Term();
|
||||||
|
if(IsAlpha(c)) {
|
||||||
|
String id;
|
||||||
|
while(IsAlpha(script.Term())) {
|
||||||
|
c = script.Get();
|
||||||
|
stmt.Cat(c);
|
||||||
|
id.Cat(ToUpper(c));
|
||||||
|
}
|
||||||
|
if(id == "BEGIN")
|
||||||
|
level++;
|
||||||
|
if(id == "END")
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(c == '\'') {
|
||||||
|
stmt.Cat(c);
|
||||||
|
script.Get();
|
||||||
|
for(;;) {
|
||||||
|
c = script.Get();
|
||||||
|
if(c < 0) {
|
||||||
|
ok = false;
|
||||||
|
if(stoponerror)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stmt.Cat(c);
|
||||||
|
if(c == '\'')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(c == ';' && level == 0) {
|
||||||
|
Sql sql(session);
|
||||||
|
session.ClearError();
|
||||||
|
int q = 0;
|
||||||
|
while(stmt[q] == '\r' || stmt[q] == '\n')
|
||||||
|
q++;
|
||||||
|
stmt = stmt.Mid(q);
|
||||||
|
if(!sql.Execute(stmt)) {
|
||||||
|
ok = false;
|
||||||
|
if(stoponerror)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stmt.Clear();
|
||||||
|
script.Get();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(c == '(')
|
||||||
|
level++;
|
||||||
|
if(c == ')')
|
||||||
|
level--;
|
||||||
|
if(c != '\r') {
|
||||||
|
if(session.GetDialect() == ORACLE && c == '\n')
|
||||||
|
stmt.Cat('\r');
|
||||||
|
stmt.Cat(c);
|
||||||
|
}
|
||||||
|
script.Get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SqlPerformScript(SqlSession& session, const String& script,
|
||||||
|
Gate2<int, int> progress_canceled, bool stoponerror)
|
||||||
|
{
|
||||||
|
StringStream ss(script);
|
||||||
|
return SqlPerformScript(session, ss, progress_canceled, stoponerror);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NOAPPSQL
|
||||||
|
|
||||||
|
bool SqlPerformScript(Stream& script,
|
||||||
|
Gate2<int, int> progress_canceled, bool stoponerror)
|
||||||
|
{
|
||||||
|
return SqlPerformScript(SQL.GetSession(), script, progress_canceled, stoponerror);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SqlPerformScript(const String& script,
|
||||||
|
Gate2<int, int> progress_canceled, bool stoponerror)
|
||||||
|
{
|
||||||
|
return SqlPerformScript(SQL.GetSession(), script, progress_canceled, stoponerror);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
END_UPP_NAMESPACE
|
||||||
184
uppsrc/Sql/Session.cpp
Normal file
184
uppsrc/Sql/Session.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
#include "Sql.h"
|
||||||
|
|
||||||
|
NAMESPACE_UPP
|
||||||
|
|
||||||
|
SqlSession::SqlSession()
|
||||||
|
{
|
||||||
|
trace = NULL;
|
||||||
|
traceslow = INT_MAX / 4;
|
||||||
|
logerrors = false;
|
||||||
|
usrlog = false;
|
||||||
|
tracetime = false;
|
||||||
|
dialect = 255;
|
||||||
|
errorcode_number = Null;
|
||||||
|
errorclass = Sql::ERROR_UNSPECIFIED;
|
||||||
|
error_handler = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlSession::~SqlSession()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlSession::Begin() { NEVER(); }
|
||||||
|
void SqlSession::Commit() { NEVER(); }
|
||||||
|
void SqlSession::Rollback() { NEVER(); }
|
||||||
|
String SqlSession::Savepoint() { NEVER(); return Null; }
|
||||||
|
void SqlSession::RollbackTo(const String&) { NEVER(); }
|
||||||
|
bool SqlSession::IsOpen() const { return false; }
|
||||||
|
int SqlSession::GetTransactionLevel() const { return 0; }
|
||||||
|
RunScript SqlSession::GetRunScript() const { return NULL; }
|
||||||
|
SqlConnection *SqlSession::CreateConnection() { return NULL; }
|
||||||
|
Vector<String> SqlSession::EnumUsers() { return Vector<String>(); }
|
||||||
|
Vector<String> SqlSession::EnumDatabases() { return Vector<String>(); }
|
||||||
|
Vector<String> SqlSession::EnumTables(String database) { return Vector<String>(); }
|
||||||
|
Vector<String> SqlSession::EnumViews(String database) { return Vector<String>(); }
|
||||||
|
Vector<String> SqlSession::EnumSequences(String database) { return Vector<String>(); }
|
||||||
|
Vector<String> SqlSession::EnumPrimaryKey(String database, String table) { return Vector<String>(); }
|
||||||
|
Vector<String> SqlSession::EnumReservedWords() { return Vector<String>(); }
|
||||||
|
String SqlSession::EnumRowID(String database, String table) { return Null; }
|
||||||
|
|
||||||
|
Vector<SqlColumnInfo> SqlSession::EnumColumns(String database, String table)
|
||||||
|
{
|
||||||
|
Sql cursor(*this);
|
||||||
|
Vector<SqlColumnInfo> info;
|
||||||
|
SqlBool none;
|
||||||
|
none.SetFalse();
|
||||||
|
String full_name = database;
|
||||||
|
if(!IsNull(database))
|
||||||
|
full_name << '.';
|
||||||
|
full_name << table;
|
||||||
|
if(cursor.Execute(Select(SqlAll()).From(SqlSet(SqlId(full_name))).Where(none))) {
|
||||||
|
info.SetCount(cursor.GetColumns());
|
||||||
|
for(int i = 0; i < info.GetCount(); i++)
|
||||||
|
info[i] = cursor.GetColumnInfo(i);
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlSession::SetError(String error, String stmt, int code, const char *scode, Sql::ERRORCLASS clss) {
|
||||||
|
if(error_handler && (*error_handler)(error, stmt, code, scode, clss))
|
||||||
|
return;
|
||||||
|
if(GetTransactionLevel() && errorstatement.GetCount())
|
||||||
|
return;
|
||||||
|
lasterror = error;
|
||||||
|
errorstatement = stmt;
|
||||||
|
errorcode_number = code;
|
||||||
|
errorcode_string = scode;
|
||||||
|
errorclass = clss;
|
||||||
|
String err;
|
||||||
|
err << "ERROR " << error << "(" << code << "): " << stmt << '\n';
|
||||||
|
if(logerrors)
|
||||||
|
BugLog() << err;
|
||||||
|
if(GetTrace())
|
||||||
|
*GetTrace() << err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlSession::InstallErrorHandler(bool (*handler)(String error, String stmt, int code, const char *scode, Sql::ERRORCLASS clss))
|
||||||
|
{
|
||||||
|
error_handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlSession::SessionClose()
|
||||||
|
{
|
||||||
|
if(sql) {
|
||||||
|
sql->Cancel();
|
||||||
|
sql.Clear();
|
||||||
|
}
|
||||||
|
if(sqlr) {
|
||||||
|
sqlr->Cancel();
|
||||||
|
sqlr.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql& SqlSession::GetSessionSql()
|
||||||
|
{
|
||||||
|
if(!sql)
|
||||||
|
sql = new Sql(*this);
|
||||||
|
return *sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql& SqlSession::GetSessionSqlR()
|
||||||
|
{
|
||||||
|
if(!sqlr)
|
||||||
|
sqlr = new Sql(*this);
|
||||||
|
return *sqlr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlSession::ClearError()
|
||||||
|
{
|
||||||
|
lasterror.Clear();
|
||||||
|
errorstatement.Clear();
|
||||||
|
errorcode_number = Null;
|
||||||
|
errorcode_string = Null;
|
||||||
|
errorclass = Sql::ERROR_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticMutex sDefs;
|
||||||
|
static SqlSession *sGlobalSession;
|
||||||
|
static SqlSession *sGlobalSessionR;
|
||||||
|
#ifdef _MULTITHREADED
|
||||||
|
thread__ SqlSession *sThreadSession;
|
||||||
|
thread__ SqlSession *sThreadSessionR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Sql::operator=(SqlSession& s)
|
||||||
|
{
|
||||||
|
Mutex::Lock __(sDefs);
|
||||||
|
if(this == &AppCursor()) {
|
||||||
|
#ifdef _MULTITHREADED
|
||||||
|
sThreadSession = &s;
|
||||||
|
if(!sGlobalSession)
|
||||||
|
#endif
|
||||||
|
sGlobalSession = &s;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(this == &AppCursorR()) {
|
||||||
|
#ifdef _MULTITHREADED
|
||||||
|
sThreadSessionR = &s;
|
||||||
|
if(!sGlobalSessionR)
|
||||||
|
#endif
|
||||||
|
sGlobalSessionR = &s;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NEVER();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql& AppCursor()
|
||||||
|
{
|
||||||
|
#ifdef _MULTITHREADED
|
||||||
|
if(sThreadSession)
|
||||||
|
return sThreadSession->GetSessionSql();
|
||||||
|
#endif
|
||||||
|
if(sGlobalSession)
|
||||||
|
return sGlobalSession->GetSessionSql();
|
||||||
|
static Sql *empty;
|
||||||
|
ONCELOCK {
|
||||||
|
static Sql h(Sql::NULLSQL);
|
||||||
|
empty = &h;
|
||||||
|
}
|
||||||
|
return *empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql& AppCursorR()
|
||||||
|
{
|
||||||
|
#ifdef _MULTITHREADED
|
||||||
|
if(sThreadSessionR)
|
||||||
|
return sThreadSessionR->GetSessionSqlR();
|
||||||
|
#endif
|
||||||
|
if(sGlobalSessionR)
|
||||||
|
return sGlobalSessionR->GetSessionSqlR();
|
||||||
|
#ifdef _MULTITHREADED
|
||||||
|
if(sThreadSession)
|
||||||
|
return sThreadSession->GetSessionSqlR();
|
||||||
|
#endif
|
||||||
|
if(sGlobalSession)
|
||||||
|
return sGlobalSession->GetSessionSqlR();
|
||||||
|
static Sql *empty;
|
||||||
|
ONCELOCK {
|
||||||
|
static Sql h(Sql::NULLSQL);
|
||||||
|
empty = &h;
|
||||||
|
}
|
||||||
|
return *empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
END_UPP_NAMESPACE
|
||||||
|
|
@ -114,6 +114,9 @@ bool Sql::Execute() {
|
||||||
#ifndef NOAPPSQL
|
#ifndef NOAPPSQL
|
||||||
if(this == &AppCursor())
|
if(this == &AppCursor())
|
||||||
*s << "SQL* ";
|
*s << "SQL* ";
|
||||||
|
else
|
||||||
|
if(this == &AppCursorR())
|
||||||
|
*s << "SQLR* ";
|
||||||
#endif
|
#endif
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(const char *q = cn->statement; *q; q++)
|
for(const char *q = cn->statement; *q; q++)
|
||||||
|
|
@ -577,10 +580,6 @@ void Sql::RollbackTo(const String& savepoint) { GetSession().RollbackTo(save
|
||||||
|
|
||||||
bool Sql::IsOpen() { return cn && GetSession().IsOpen(); }
|
bool Sql::IsOpen() { return cn && GetSession().IsOpen(); }
|
||||||
|
|
||||||
#ifndef NOAPPSQL
|
|
||||||
GLOBAL_VAR(AppSql, AppCursor)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NOAPPSQL
|
#ifndef NOAPPSQL
|
||||||
Sql::Sql() {
|
Sql::Sql() {
|
||||||
cn = NULL;
|
cn = NULL;
|
||||||
|
|
@ -631,120 +630,17 @@ Sql::~Sql() {
|
||||||
Detach();
|
Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlSession::SqlSession()
|
|
||||||
{
|
|
||||||
trace = NULL;
|
|
||||||
traceslow = INT_MAX / 4;
|
|
||||||
logerrors = false;
|
|
||||||
usrlog = false;
|
|
||||||
tracetime = false;
|
|
||||||
dialect = 255;
|
|
||||||
errorcode_number = Null;
|
|
||||||
errorclass = Sql::ERROR_UNSPECIFIED;
|
|
||||||
error_handler = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SqlSession::~SqlSession()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
#ifndef NOAPPSQL
|
#ifndef NOAPPSQL
|
||||||
if(SQL.IsOpen() && &SQL.GetSession() == this) {
|
|
||||||
LLOG("Detaching SQL");
|
|
||||||
// SQL.Detach();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void SqlSession::Begin() { NEVER(); }
|
SqlR::SqlR()
|
||||||
void SqlSession::Commit() { NEVER(); }
|
: Sql(SQLR.GetSession()) {}
|
||||||
void SqlSession::Rollback() { NEVER(); }
|
|
||||||
String SqlSession::Savepoint() { NEVER(); return Null; }
|
|
||||||
void SqlSession::RollbackTo(const String&) { NEVER(); }
|
|
||||||
bool SqlSession::IsOpen() const { return false; }
|
|
||||||
int SqlSession::GetTransactionLevel() const { return 0; }
|
|
||||||
RunScript SqlSession::GetRunScript() const { return NULL; }
|
|
||||||
SqlConnection *SqlSession::CreateConnection() { return NULL; }
|
|
||||||
Vector<String> SqlSession::EnumUsers() { return Vector<String>(); }
|
|
||||||
Vector<String> SqlSession::EnumDatabases() { return Vector<String>(); }
|
|
||||||
Vector<String> SqlSession::EnumTables(String database) { return Vector<String>(); }
|
|
||||||
Vector<String> SqlSession::EnumViews(String database) { return Vector<String>(); }
|
|
||||||
Vector<String> SqlSession::EnumSequences(String database) { return Vector<String>(); }
|
|
||||||
Vector<String> SqlSession::EnumPrimaryKey(String database, String table) { return Vector<String>(); }
|
|
||||||
Vector<String> SqlSession::EnumReservedWords() { return Vector<String>(); }
|
|
||||||
String SqlSession::EnumRowID(String database, String table) { return Null; }
|
|
||||||
|
|
||||||
Vector<SqlColumnInfo> SqlSession::EnumColumns(String database, String table)
|
SqlR::SqlR(const char *stmt)
|
||||||
{
|
: Sql(stmt, SQLR.GetSession()) {}
|
||||||
Sql cursor(*this);
|
|
||||||
Vector<SqlColumnInfo> info;
|
|
||||||
SqlBool none;
|
|
||||||
none.SetFalse();
|
|
||||||
String full_name = database;
|
|
||||||
if(!IsNull(database))
|
|
||||||
full_name << '.';
|
|
||||||
full_name << table;
|
|
||||||
if(cursor.Execute(Select(SqlAll()).From(SqlSet(SqlId(full_name))).Where(none))) {
|
|
||||||
info.SetCount(cursor.GetColumns());
|
|
||||||
for(int i = 0; i < info.GetCount(); i++)
|
|
||||||
info[i] = cursor.GetColumnInfo(i);
|
|
||||||
}
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SqlSession::SetError(String error, String stmt, int code, const char *scode, Sql::ERRORCLASS clss) {
|
SqlR::SqlR(const SqlStatement& s)
|
||||||
if(error_handler && (*error_handler)(error, stmt, code, scode, clss))
|
: Sql(s, SQLR.GetSession()) {}
|
||||||
return;
|
|
||||||
if(GetTransactionLevel() && errorstatement.GetCount())
|
|
||||||
return;
|
|
||||||
lasterror = error;
|
|
||||||
errorstatement = stmt;
|
|
||||||
errorcode_number = code;
|
|
||||||
errorcode_string = scode;
|
|
||||||
errorclass = clss;
|
|
||||||
String err;
|
|
||||||
err << "ERROR " << error << "(" << code << "): " << stmt << '\n';
|
|
||||||
if(logerrors)
|
|
||||||
BugLog() << err;
|
|
||||||
if(GetTrace())
|
|
||||||
*GetTrace() << err;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SqlSession::InstallErrorHandler(bool (*handler)(String error, String stmt, int code, const char *scode, Sql::ERRORCLASS clss))
|
|
||||||
{
|
|
||||||
error_handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sql& SqlSession::GetSessionSql()
|
|
||||||
{
|
|
||||||
if(!sql)
|
|
||||||
sql = new Sql(*this);
|
|
||||||
return *sql;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SqlSession::ClearError()
|
|
||||||
{
|
|
||||||
lasterror.Clear();
|
|
||||||
errorstatement.Clear();
|
|
||||||
errorcode_number = Null;
|
|
||||||
errorcode_string = Null;
|
|
||||||
errorclass = Sql::ERROR_UNSPECIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StdStatementExecutor::Execute(const String& stmt)
|
|
||||||
{
|
|
||||||
cursor.Execute(stmt);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NOAPPSQL
|
|
||||||
struct SQLStatementExecutorClass : StatementExecutor {
|
|
||||||
virtual bool Execute(const String& stmt) { SQL.Execute(stmt); return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
StatementExecutor& SQLStatementExecutor() {
|
|
||||||
return Single<SQLStatementExecutorClass>();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
END_UPP_NAMESPACE
|
END_UPP_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ file
|
||||||
SqlStatement.cpp optimize_speed,
|
SqlStatement.cpp optimize_speed,
|
||||||
Sqls.h,
|
Sqls.h,
|
||||||
Sql.cpp,
|
Sql.cpp,
|
||||||
|
Session.cpp,
|
||||||
|
Script.cpp,
|
||||||
MassInsert.cpp,
|
MassInsert.cpp,
|
||||||
Schema readonly separator,
|
Schema readonly separator,
|
||||||
SqlSchema.h,
|
SqlSchema.h,
|
||||||
|
|
|
||||||
|
|
@ -419,94 +419,6 @@ Value SqlStatement::Fetch() const {
|
||||||
return Fetch(SQL);
|
return Fetch(SQL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SqlPerformScript(SqlSession& session, Stream& script,
|
|
||||||
Gate2<int, int> progress_canceled, bool stoponerror)
|
|
||||||
{
|
|
||||||
String stmt;
|
|
||||||
int level = 0;
|
|
||||||
bool ok = true;
|
|
||||||
while(!script.IsEof()) {
|
|
||||||
int c = script.Term();
|
|
||||||
if(IsAlpha(c)) {
|
|
||||||
String id;
|
|
||||||
while(IsAlpha(script.Term())) {
|
|
||||||
c = script.Get();
|
|
||||||
stmt.Cat(c);
|
|
||||||
id.Cat(ToUpper(c));
|
|
||||||
}
|
|
||||||
if(id == "BEGIN")
|
|
||||||
level++;
|
|
||||||
if(id == "END")
|
|
||||||
level--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(c == '\'') {
|
|
||||||
stmt.Cat(c);
|
|
||||||
script.Get();
|
|
||||||
for(;;) {
|
|
||||||
c = script.Get();
|
|
||||||
if(c < 0) {
|
|
||||||
ok = false;
|
|
||||||
if(stoponerror)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stmt.Cat(c);
|
|
||||||
if(c == '\'')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(c == ';' && level == 0) {
|
|
||||||
Sql sql(session);
|
|
||||||
session.ClearError();
|
|
||||||
int q = 0;
|
|
||||||
while(stmt[q] == '\r' || stmt[q] == '\n')
|
|
||||||
q++;
|
|
||||||
stmt = stmt.Mid(q);
|
|
||||||
if(!sql.Execute(stmt)) {
|
|
||||||
ok = false;
|
|
||||||
if(stoponerror)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
stmt.Clear();
|
|
||||||
script.Get();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(c == '(')
|
|
||||||
level++;
|
|
||||||
if(c == ')')
|
|
||||||
level--;
|
|
||||||
if(c != '\r') {
|
|
||||||
if(session.GetDialect() == ORACLE && c == '\n')
|
|
||||||
stmt.Cat('\r');
|
|
||||||
stmt.Cat(c);
|
|
||||||
}
|
|
||||||
script.Get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SqlPerformScript(Stream& script,
|
|
||||||
Gate2<int, int> progress_canceled, bool stoponerror)
|
|
||||||
{
|
|
||||||
return SqlPerformScript(SQL.GetSession(), script, progress_canceled, stoponerror);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SqlPerformScript(SqlSession& session, const String& script,
|
|
||||||
Gate2<int, int> progress_canceled, bool stoponerror)
|
|
||||||
{
|
|
||||||
StringStream ss(script);
|
|
||||||
return SqlPerformScript(session, ss, progress_canceled, stoponerror);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SqlPerformScript(const String& script,
|
|
||||||
Gate2<int, int> progress_canceled, bool stoponerror)
|
|
||||||
{
|
|
||||||
return SqlPerformScript(SQL.GetSession(), script, progress_canceled, stoponerror);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
END_UPP_NAMESPACE
|
END_UPP_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,8 @@ class Sql {
|
||||||
Vector<Value> param;
|
Vector<Value> param;
|
||||||
|
|
||||||
friend class SqlSession;
|
friend class SqlSession;
|
||||||
friend struct AppSql;
|
friend Sql& AppCursor();
|
||||||
|
friend Sql& AppCursorR();
|
||||||
|
|
||||||
Value Select0(const String& what);
|
Value Select0(const String& what);
|
||||||
void Assign(SqlSource& src);
|
void Assign(SqlSource& src);
|
||||||
|
|
@ -235,26 +236,18 @@ public:
|
||||||
Sql(const SqlStatement& s, SqlSource& session);
|
Sql(const SqlStatement& s, SqlSource& session);
|
||||||
Sql(SqlConnection *connection);
|
Sql(SqlConnection *connection);
|
||||||
~Sql();
|
~Sql();
|
||||||
|
|
||||||
|
void operator=(SqlSession& s); // this only works with SQL and SQLR...
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef NOAPPSQL
|
#ifndef NOAPPSQL
|
||||||
|
struct SqlR : Sql {
|
||||||
struct AppSql : Sql {
|
SqlR();
|
||||||
void operator=(SqlSource& s) { Assign(s); }
|
SqlR(const char *stmt);
|
||||||
void Detach() { Sql::Detach(); }
|
SqlR(const SqlStatement& s);
|
||||||
AppSql() : Sql(NULLSQL) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AppSql& AppCursor();
|
|
||||||
//$-
|
|
||||||
#define SQL AppCursor()
|
|
||||||
//$+
|
|
||||||
// Assist++ cheat:
|
|
||||||
//$ AppSql SQL;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct StatementExecutor {
|
struct StatementExecutor {
|
||||||
virtual bool Execute(const String& stmt) = 0;
|
virtual bool Execute(const String& stmt) = 0;
|
||||||
virtual ~StatementExecutor() {}
|
virtual ~StatementExecutor() {}
|
||||||
|
|
@ -262,6 +255,9 @@ struct StatementExecutor {
|
||||||
|
|
||||||
typedef bool (*RunScript)(const String& text, StatementExecutor& executor, Gate2<int, int> progress_canceled);
|
typedef bool (*RunScript)(const String& text, StatementExecutor& executor, Gate2<int, int> progress_canceled);
|
||||||
|
|
||||||
|
class AppSql;
|
||||||
|
class AppSqlR;
|
||||||
|
|
||||||
class SqlSession : public SqlSource {
|
class SqlSession : public SqlSource {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -301,6 +297,9 @@ protected:
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
One<Sql> sql;
|
One<Sql> sql;
|
||||||
|
One<Sql> sqlr;
|
||||||
|
|
||||||
|
void SessionClose();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void Begin();
|
virtual void Begin();
|
||||||
|
|
@ -359,6 +358,7 @@ public:
|
||||||
String GetUser() { return Sql(*this).GetUser(); }
|
String GetUser() { return Sql(*this).GetUser(); }
|
||||||
|
|
||||||
Sql& GetSessionSql();
|
Sql& GetSessionSql();
|
||||||
|
Sql& GetSessionSqlR();
|
||||||
|
|
||||||
operator bool() const { return IsOpen(); }
|
operator bool() const { return IsOpen(); }
|
||||||
|
|
||||||
|
|
@ -374,6 +374,21 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NOAPPSQL
|
||||||
|
|
||||||
|
Sql& AppCursor();
|
||||||
|
Sql& AppCursorR();
|
||||||
|
|
||||||
|
//$-
|
||||||
|
#define SQL AppCursor()
|
||||||
|
#define SQLR AppCursorR()
|
||||||
|
//$+
|
||||||
|
// Assist++ cheat:
|
||||||
|
//$ Sql SQL;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class OciConnection;
|
class OciConnection;
|
||||||
|
|
||||||
bool SqlPerformScript(SqlSession& session, Stream& script,
|
bool SqlPerformScript(SqlSession& session, Stream& script,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue