ultimatepp/uppsrc/Sql/Sqls.h
cxl 24664f8e30 Sql: Sql::InsertNoNulls
git-svn-id: svn://ultimatepp.org/upp/trunk@1725 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2009-11-27 11:05:07 +00:00

388 lines
13 KiB
C++

bool SqlToBool(const String& s);
bool SqlToBool(const Value& v);
const String& BoolToSql(bool b);
class SqlSession;
class SqlExc : public Exc {
public:
#ifndef NOAPPSQL
SqlExc();
#endif
SqlExc(const SqlSession& session);
SqlExc(const Sql& sql);
SqlExc(const String& desc) : Exc(desc) {}
SqlExc(const char *desc) : Exc(desc) {}
void SetSessionError(const SqlSession& session);
};
enum { SQLRAW_V = 34 };
class SqlRaw : public String, AssignValueTypeNo<SqlRaw, SQLRAW_V> {
public:
operator Value() const { return RawValue<SqlRaw>(*this); }
SqlRaw(const Value& q)
: String(IsString(q) ? String(q) : String(RawValue<SqlRaw>::Extract(q))) {}
SqlRaw(const String& s) : String(s) {}
SqlRaw() {}
};
struct SqlColumnInfo : Moveable<SqlColumnInfo> {
String name;
int type;
int width;
int precision; //number of total digits in numeric types
int scale; //number of digits after comma in numeric types
bool nullable; //true - column can hold null values
};
class SqlConnection {
protected:
friend class Sql;
friend class SqlSession;
virtual void SetParam(int i, const Value& r) = 0;
virtual bool Execute() = 0;
virtual int GetRowsProcessed() const;
virtual Value GetInsertedId() const;
virtual bool Fetch() = 0;
virtual void GetColumn(int i, Ref r) const = 0;
virtual void Cancel() = 0;
virtual SqlSession& GetSession() const = 0;
virtual String GetUser() const;
virtual String ToString() const = 0;
SqlConnection();
virtual ~SqlConnection();
int starttime;
String statement;
Vector<SqlColumnInfo> info;
int fetchrows;
int longsize;
bool parse;
};
#define E__ColVal(I) const char *c##I, const Value& v##I
#define E__IdVal(I) SqlId c##I, const Value& v##I
class SqlSource {
protected:
virtual SqlConnection *CreateConnection() = 0;
virtual ~SqlSource() {}
friend class Sql;
};
class Sql {
protected:
SqlConnection *cn;
friend class SqlSession;
Value Select0(const String& what);
void Assign(SqlSource& src);
void Detach();
enum _NULLSQL { NULLSQL };
Sql(_NULLSQL) { cn = NULL; }
public:
String Compile(const SqlStatement& s);
void Clear();
void SetParam(int i, const Value& val);
void SetStatement(const String& s);
void SetStatement(const SqlStatement& s) { SetStatement(Compile(s)); }
bool Execute();
void ExecuteX();
bool Run() { return Execute(); }
void RunX() { ExecuteX(); }
bool Execute(const String& s);
void ExecuteX(const String& s);
bool Execute(const SqlStatement& s) { return Execute(Compile(s)); }
void ExecuteX(const SqlStatement& s) { ExecuteX(Compile(s)); }
//$-
#define E__Run(I) bool Run(__List##I(E__Value));
__Expand(E__Run)
//$ bool Run(const Value& v1 [, const Value& v2 ...]);
#define E__RunX(I) void RunX(__List##I(E__Value));
__Expand(E__RunX)
#define E__Execute(I) bool Execute(const String& s, __List##I(E__Value));
__Expand(E__Execute)
#define E__ExecuteX(I) void ExecuteX(const String& s, __List##I(E__Value));
__Expand(E__ExecuteX)
bool Fetch();
#define E__Fetch(I) bool Fetch(__List##I(E__Ref));
__Expand(E__Fetch)
//$+
bool Fetch(Vector<Value>& row);
bool Fetch(Fields fields);
int GetRowsProcessed() const { return cn->GetRowsProcessed(); }
int GetColumns() const;
void GetColumn(int i, Ref r) const;
Value operator[](int i) const;
Value operator[](SqlId colid) const;
const SqlColumnInfo& GetColumnInfo(int i) const { return cn->info[i]; }
Vector<Value> GetRow() const;
operator Vector<Value>() const { return GetRow(); }
void Get(Fields fields);
void SetFetchRows(int nrows) { cn->fetchrows = nrows; }
void SetLongSize(int lsz) { cn->longsize = lsz; }
void Cancel() { cn->Cancel(); }
Value Select(const String& what);
#define E__Select(I) Value Select(const String& what, __List##I(E__Value));
__Expand(E__Select)
#define E__Insert(I) bool Insert(const char *tb, const char *c0, const Value& v0, __List##I(E__ColVal));
__Expand(E__Insert)
#define E__InsertId(I) bool Insert(SqlId tb, SqlId c0, const Value& v0, __List##I(E__IdVal));
__Expand(E__InsertId)
#define E__Update(I) bool Update(const char *tb, const char *k, const Value& kv, __List##I(E__ColVal));
__Expand(E__Update)
#define E__UpdateId(I) bool Update(SqlId tb, SqlId k, const Value& kv, __List##I(E__IdVal));
__Expand(E__UpdateId)
bool Insert(Fields nf);
bool Insert(Fields nf, const char *table);
bool Insert(Fields nf, SqlId table);
bool InsertNoKey(Fields nf, const char *table);
bool InsertNoKey(Fields nf);
bool InsertNoKey(Fields nf, SqlId table);
bool InsertNoNulls(Fields nf, const char *table);
bool InsertNoNulls(Fields nf);
bool InsertNoNulls(Fields nf, SqlId table);
bool Update(Fields nf);
bool Update(Fields nf, const char *table);
bool Update(Fields nf, SqlId table);
bool Delete(const char *table, const char *key, const Value& keyval);
bool Delete(SqlId table, SqlId key, const Value& keyval);
String ToString() const { return cn->ToString(); }
bool operator*(const SqlStatement& q) { return Execute(q); }
Sql& operator&(const SqlStatement& q) { ExecuteX(q); return *this; }
Value operator%(const SqlStatement& q) { return Select0(Compile(q)); }
SqlSession& GetSession() const { return cn->GetSession(); }
int GetDialect() const;
Value GetInsertedId() const { return cn->GetInsertedId(); }
String GetUser() const { return cn->GetUser(); }
enum ERRORCLASS {
ERROR_UNSPECIFIED,
CONNECTION_BROKEN,
};
void SetError(String error, String stmt, int code = 0, const char *scode = NULL, ERRORCLASS clss = ERROR_UNSPECIFIED);
String GetLastError() const;
String GetErrorStatement() const;
int GetErrorCode() const;
String GetErrorCodeString() const;
ERRORCLASS GetErrorClass() const;
void ClearError();
void Begin();
void Commit();
void Rollback();
int GetTransactionLevel();
String Savepoint();
void RollbackTo(const String& savepoint);
bool IsOpen();
bool WasError() const;
Sql(SqlSource&);
#ifndef NOAPPSQL
Sql();
Sql(const char *stmt);
Sql(const SqlStatement& s);
#endif
Sql(const char *stmt, SqlSource& session);
Sql(const SqlStatement& s, SqlSource& session);
Sql(SqlConnection *connection);
~Sql();
};
#ifndef NOAPPSQL
struct AppSql : Sql {
void operator=(SqlSource& s) { Assign(s); }
void Detach() { Sql::Detach(); }
AppSql() : Sql(NULLSQL) {}
};
AppSql& AppCursor();
//$-
#define SQL AppCursor()
//$+
// Assist++ cheat:
//$ AppSql SQL;
#endif
struct StatementExecutor {
virtual bool Execute(const String& stmt) = 0;
virtual ~StatementExecutor() {}
};
typedef bool (*RunScript)(const String& text, StatementExecutor& executor, Gate2<int, int> progress_canceled);
class SqlSession : public SqlSource {
public:
enum {
START_FETCHING,
END_FETCHING,
END_FETCHING_MANY,
START_EXECUTING,
END_EXECUTING,
EXECUTING_ERROR,
CONNECTION_ERROR,
BEFORE_EXECUTING,
AFTER_EXECUTING
};
protected:
virtual SqlConnection *CreateConnection();
friend class Sql;
Stream *trace;
bool logerrors;
bool tracetime;
bool usrlog;
int traceslow;
int dialect;
int exectime;
String statement;
String lasterror;
String errorstatement;
int errorcode_number;
String errorcode_string;
Sql::ERRORCLASS errorclass;
int status;
public:
virtual void Begin();
virtual void Commit();
virtual void Rollback();
virtual int GetTransactionLevel() const;
virtual String Savepoint();
virtual void RollbackTo(const String& savepoint);
virtual bool IsOpen() const;
virtual RunScript GetRunScript() const;
virtual Vector<String> EnumUsers();
virtual Vector<String> EnumDatabases();
virtual Vector<String> EnumTables(String database);
virtual Vector<String> EnumViews(String database);
virtual Vector<String> EnumSequences(String database);
virtual Vector<SqlColumnInfo> EnumColumns(String database, String table);
virtual Vector<String> EnumPrimaryKey(String database, String table);
virtual String EnumRowID(String database, String table);
virtual Vector<String> EnumReservedWords();
SqlSession& Dialect(int q) { dialect = q; return *this; }
int GetDialect() const { ASSERT(dialect != 255); return dialect; }
void SetTrace(Stream& s = VppLog()) { trace = &s; }
Stream *GetTrace() const { return trace; }
void KillTrace() { trace = NULL; }
void TraceTime(bool b = true) { tracetime = b; }
bool IsTraceTime() const { return tracetime; }
SqlSession& LogErrors(bool b = true) { logerrors = true; return *this; }
SqlSession& UsrLog(bool b = true) { usrlog = true; return *this; }
SqlSession& TraceSlow(int ms = 5000) { traceslow = ms; return *this; }
bool WasError() const { return !GetLastError().IsEmpty(); }
void SetError(String error, String stmt, int code = 0, const char * scode = NULL, Sql::ERRORCLASS clss = Sql::ERROR_UNSPECIFIED);
String GetLastError() const { return lasterror; }
String GetErrorStatement() const { return errorstatement; }
int GetErrorCode() const { return errorcode_number; }
String GetErrorCodeString() const { return errorcode_string; }
Sql::ERRORCLASS GetErrorClass() const { return errorclass; }
void ClearError();
String GetStatement() const { return statement; }
void SetStatement(const String& s) { statement = s; }
void SetTime(int t) { exectime = t; }
int GetTime() const { return exectime; }
String GetUser() { return Sql(*this).GetUser(); }
operator bool() const { return IsOpen(); }
SqlSession();
virtual ~SqlSession();
int GetStatus() { return status; }
void SetStatus(int s) { status = s; WhenDatabaseActivity(*this); }
bool operator == (int s) const { return status == s; }
bool operator != (int s) const { return status != s; }
Callback1<const SqlSession&> WhenDatabaseActivity;
};
class OciConnection;
bool SqlPerformScript(SqlSession& session, Stream& script,
Gate2<int, int> progress_canceled = false, bool stoponerror = false);
bool SqlPerformScript(Stream& script,
Gate2<int, int> progress_canceled = false, bool stoponerror = false);
bool SqlPerformScript(SqlSession& session, const String& script,
Gate2<int, int> progress_canceled = false, bool stoponerror = false);
bool SqlPerformScript(const String& script,
Gate2<int, int> progress_canceled = false, bool stoponerror = false);
struct StdStatementExecutor : StatementExecutor {
StdStatementExecutor(SqlSession& session) : cursor(session) {}
virtual bool Execute(const String& stmt);
Sql cursor;
};
#ifndef NOAPPSQL
StatementExecutor& SQLStatementExecutor();
#endif
#ifdef BackwardCompatibility
typedef Sql QSql;
typedef SqlSession QSession;
#endif