8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 22:03:03 +01:00

Implemented CORE-4317: Make ISQL use new object API with 32-bit length for object sizes (messages, SQL statements, etc.)

Implementation also includes changes in GPRE, but this utility is not complete - only commands, used in ISQL,
are working in code generator for new API.
New interface IUtl is added - it performs tasks, related with database objects (attachment, transaction, etc.),
but not requiring routing in YValve, i.e. client only tasks.
This commit is contained in:
alexpeshkoff 2014-01-15 13:02:08 +00:00
parent 7b8dc14b57
commit 949defe5e6
34 changed files with 6499 additions and 2195 deletions

View File

@ -62,7 +62,7 @@ WCXXFLAGS:= $(WFLAGS) $(THR_FLAGS) $(RTTI_FLAG) $(CXXFLAGS) $(GLOB_OPTIONS)
GPRE_FLAGS= -m -z -n
JRD_GPRE_FLAGS = -n -z -gds_cxx -ids
DSQL_GPRE_FLAGS = -m -z -n
ISQL_GPRE_FLAGS = -m -z -n -ocxx
.SUFFIXES: .c .e .epp .cpp
@ -74,11 +74,8 @@ DSQL_GPRE_FLAGS = -m -z -n
$(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp
$(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
$(OBJ)/dsql/%.cpp: $(SRC_ROOT)/dsql/%.epp
$(GPRE_CURRENT) $(DSQL_GPRE_FLAGS) $< $@
$(OBJ)/yvalve/%.cpp: $(SRC_ROOT)/yvalve/%.epp
$(GPRE_CURRENT) $(DSQL_GPRE_FLAGS) $< $@
$(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp
$(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
$(OBJ)/%.cpp: $(SRC_ROOT)/%.epp
$(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@

View File

@ -24,4 +24,4 @@ WARN_FLAGS=-Wall -Wno-switch -Wno-parentheses -Wno-unknown-pragmas -Wno-unused-v
PROD_FLAGS=$(COMMON_FLAGS) $(OPTIMIZE_FLAGS)
#DEV_FLAGS=-DUSE_VALGRIND $(COMMON_FLAGS) $(WARN_FLAGS)
DEV_FLAGS=$(COMMON_FLAGS) $(WARN_FLAGS)
DEV_FLAGS=$(COMMON_FLAGS) $(WARN_FLAGS) -fmax-errors=8

View File

@ -92,6 +92,7 @@ private:
};
// With template magic, we make the fields strongly-typed.
template <>
bool Message::checkType<SLONG>(unsigned t, unsigned sz)
{
@ -104,6 +105,12 @@ bool Message::checkType<ISC_QUAD>(unsigned t, unsigned sz)
return (t == SQL_BLOB || t == SQL_QUAD) && sz == sizeof(ISC_QUAD);
}
template <>
bool Message::checkType<ISC_INT64>(unsigned t, unsigned sz)
{
return t == SQL_INT64 && sz == sizeof(ISC_INT64);
}
template <>
bool Message::checkType<FB_BOOLEAN>(unsigned t, unsigned sz)
{
@ -111,7 +118,6 @@ bool Message::checkType<FB_BOOLEAN>(unsigned t, unsigned sz)
}
// With template magic, we make the fields strongly-typed.
template <typename T>
class Field
{

View File

@ -81,7 +81,7 @@ public:
}
}
virtual void FB_CARG setSubType(IStatus* status, unsigned index, unsigned subType)
virtual void FB_CARG setSubType(IStatus* status, unsigned index, int subType)
{
try
{
@ -162,6 +162,22 @@ public:
}
}
virtual void FB_CARG remove(IStatus* status, unsigned index)
{
try
{
MutexLockGuard g(mtx, FB_FUNCTION);
indexError(index, "remove");
msgMetadata->items.remove(index);
}
catch (const Exception& ex)
{
ex.stuffException(status);
}
}
virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index)
{
try

View File

@ -79,7 +79,7 @@ public:
string owner;
string alias;
unsigned type;
unsigned subType;
int subType;
unsigned length;
int scale;
unsigned charSet;
@ -164,7 +164,7 @@ public:
return false;
}
virtual unsigned FB_CARG getSubType(IStatus* status, unsigned index) const
virtual int FB_CARG getSubType(IStatus* status, unsigned index) const
{
if (index < items.getCount())
return items[index].subType;

View File

@ -250,6 +250,16 @@ public:
};
// Misc utl access
class UtlInterfacePtr : public AccessAutoInterface<IUtl>
{
public:
UtlInterfacePtr()
: AccessAutoInterface<IUtl>(getMasterInterface()->getUtlInterface())
{ }
};
// When process exits, dynamically loaded modules (for us plugin modules)
// are unloaded first. As the result all global variables in plugin are already destroyed
// when yvalve is starting fb_shutdown(). This causes almost unavoidable segfault.

View File

@ -70,7 +70,7 @@ static const size_t MAX_TRIES = 256;
// we need a class here only to return memory on shutdown and avoid
// false memory leak reports
static Firebird::InitInstance<ZeroBuffer> zeros;
static InitInstance<ZeroBuffer> zeros;
//
// TempFile::getTempPath
@ -126,6 +126,32 @@ PathName TempFile::create(const PathName& prefix, const PathName& directory)
return filename;
}
//
// TempFile::create
//
// Creates a temporary file and returns its name
// In error case store exception in status arg
//
PathName TempFile::create(IStatus* status, const PathName& prefix, const PathName& directory)
{
PathName filename;
try {
TempFile file(*getDefaultMemoryPool(), prefix, directory, false);
filename = file.getName();
}
catch (const Exception& ex)
{
if (status)
{
ex.stuffException(status);
}
}
return filename;
}
//
// TempFile::init
//

View File

@ -29,6 +29,8 @@
namespace Firebird {
class IStatus;
class TempFile : public File
{
public:
@ -66,6 +68,7 @@ public:
static PathName getTempPath();
static PathName create(const PathName& prefix, const PathName& directory = "");
static PathName create(IStatus* status, const PathName& prefix, const PathName& directory = "");
private:
void init(const PathName&, const PathName&);

View File

@ -765,6 +765,12 @@ public:
{
return -1;
}
virtual IUtl* FB_CARG getUtlInterface()
{
fb_assert(false);
return NULL;
}
};

View File

@ -468,6 +468,18 @@ int main(int argc, char* argv[])
gpreGlob.database_name = "gds_database";
break;
case IN_SW_GPRE_OCXX:
gen_routine = OBJ_CXX_action;
gpreGlob.sw_language = lang_cxx;
gpreGlob.ident_pattern = "fb_%d";
gpreGlob.long_ident_pattern = "fb_%ld";
gpreGlob.utility_name = "fbUtility";
gpreGlob.count_name = "fbCount";
gpreGlob.slack_name = "fbSlack";
gpreGlob.transaction_name = "fbTrans";
gpreGlob.database_name = "fbDatabase";
break;
case IN_SW_GPRE_D:
// allocate database block and link to db chain

View File

@ -74,6 +74,7 @@ enum gpre_cmd_switch
IN_SW_GPRE_D_FLOAT, // use blr_d_float for doubles
IN_SW_GPRE_CXX, // source is C++
IN_SW_GPRE_SCXX, // source is C++ with Saber extension
IN_SW_GPRE_OCXX, // c++ with object API
IN_SW_GPRE_SQLDA, // use old or new SQLDA
IN_SW_GPRE_USER, // default username to use when attaching database
IN_SW_GPRE_PASSWORD, // default password to use in attaching database
@ -167,6 +168,7 @@ const static Switches::in_sw_tab_t gpre_in_sw_table[] =
{IN_SW_GPRE_M , 0, "MANUAL" , 0, 0, 0, false, 0, 0, "\t\tdo not automatically ATTACH to a database"},
{IN_SW_GPRE_N , 0, "NO_LINES" , 0, 0, 0, false, 0, 0, "\tdo not generate C debug lines"},
{IN_SW_GPRE_O , 0, "OUTPUT" , 0, 0, 0, false, 0, 0, "\t\tsend output to standard out"},
{IN_SW_GPRE_OCXX , 0, "OCXX" , 0, 0, 0, false, 0, 0, "\t\textended C++ program with objects API"},
#ifdef GPRE_PASCAL
{IN_SW_GPRE_P , 0, "PASCAL" , 0, 0, 0, false, 0, 0, "\t\textended PASCAL program"},
#endif

View File

@ -38,6 +38,7 @@ void FTN_fini();
void FTN_print_buffer(TEXT*);
void INT_action(const act*, int);
void INT_CXX_action(const act*, int);
void OBJ_CXX_action(const act*, int);
void PAS_action(const act*, int);
//int PLI_action(ACT, int);
void RMC_action(const act*, int);

3975
src/gpre/obj_cxx.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -87,6 +87,7 @@ public:
#define FB_STATUS_VERSION (FB_DISPOSABLE_VERSION + 5)
class IProvider;
class IUtl;
class IPluginManager;
class ITimerControl;
class IAttachment;
@ -122,8 +123,9 @@ public:
virtual IMetadataBuilder* FB_CARG getMetadataBuilder(IStatus* status, unsigned fieldCount) = 0;
virtual Firebird::IDebug* FB_CARG getDebug() = 0;
virtual int FB_CARG serverMode(int mode) = 0;
virtual IUtl* FB_CARG getUtlInterface() = 0;
};
#define FB_MASTER_VERSION (FB_VERSIONED_VERSION + 13)
#define FB_MASTER_VERSION (FB_VERSIONED_VERSION + 14)
} // namespace Firebird

View File

@ -1,6 +1,6 @@
/*
* PROGRAM: Firebird basic API
* MODULE: YValvefirebird/Interface.h
* MODULE: firebird/Provider.h
* DESCRIPTION: Interfaces, used by yValve
*
* The contents of this file are subject to the Initial
@ -100,7 +100,7 @@ public:
virtual const char* FB_CARG getAlias(IStatus* status, unsigned index) const = 0;
virtual unsigned FB_CARG getType(IStatus* status, unsigned index) const = 0;
virtual FB_BOOLEAN FB_CARG isNullable(IStatus* status, unsigned index) const = 0;
virtual unsigned FB_CARG getSubType(IStatus* status, unsigned index) const = 0;
virtual int FB_CARG getSubType(IStatus* status, unsigned index) const = 0;
virtual unsigned FB_CARG getLength(IStatus* status, unsigned index) const = 0;
virtual int FB_CARG getScale(IStatus* status, unsigned index) const = 0;
virtual unsigned FB_CARG getCharSet(IStatus* status, unsigned index) const = 0;
@ -116,17 +116,18 @@ class IMetadataBuilder : public IRefCounted
{
public:
virtual void FB_CARG setType(IStatus* status, unsigned index, unsigned type) = 0;
virtual void FB_CARG setSubType(IStatus* status, unsigned index, unsigned subType) = 0;
virtual void FB_CARG setSubType(IStatus* status, unsigned index, int subType) = 0;
virtual void FB_CARG setLength(IStatus* status, unsigned index, unsigned length) = 0;
virtual void FB_CARG setCharSet(IStatus* status, unsigned index, unsigned charSet) = 0;
virtual void FB_CARG setScale(IStatus* status, unsigned index, unsigned scale) = 0;
virtual void FB_CARG truncate(IStatus* status, unsigned count) = 0;
virtual void FB_CARG moveNameToIndex(IStatus* status, const char* name, unsigned index) = 0;
virtual void FB_CARG remove(IStatus* status, unsigned index) = 0;
virtual IMessageMetadata* FB_CARG getMetadata(IStatus* status) = 0;
};
#define FB_METADATA_BUILDER_VERSION (FB_REFCOUNTED_VERSION + 8)
#define FB_METADATA_BUILDER_VERSION (FB_REFCOUNTED_VERSION + 9)
class IResultSet : public IRefCounted
{

View File

@ -0,0 +1,67 @@
/*
* PROGRAM: Firebird basic API
* MODULE: firebird/Utl.h
* DESCRIPTION: Misc calls
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Alex Peshkov
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2013 Alex Peshkov <peshkoff at mail.ru>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*
*/
#ifndef FB_UTL_INTERFACE
#define FB_UTL_INTERFACE
#include "./Interface.h"
namespace Firebird {
class IVersionCallback : public IVersioned
{
public:
virtual void FB_CARG callback(const char* text) = 0;
};
#define FB_VERSION_CALLBACK_VERSION (FB_VERSIONED_VERSION + 1)
class IAttachment;
class ITransaction;
class IUtl : public IVersioned
{
public:
virtual void FB_CARG version(IStatus* status, IAttachment* att,
IVersionCallback* callback) = 0;
virtual void FB_CARG loadBlob(IStatus* status, ISC_QUAD* blobId,
IAttachment* att, ITransaction* tra, const char* file, FB_BOOLEAN txt) = 0;
virtual void FB_CARG dumpBlob(IStatus* status, ISC_QUAD* blobId,
IAttachment* att, ITransaction* tra, const char* file, FB_BOOLEAN txt) = 0;
virtual FB_BOOLEAN FB_CARG editBlob(IStatus* status, ISC_QUAD* blobId,
IAttachment* att, ITransaction* tra, const char* tempFile = NULL) = 0;
virtual void FB_CARG getPerfCounters(IStatus* status, IAttachment* att,
const char* countersSet, ISC_INT64* counters) = 0;
virtual IAttachment* FB_CARG executeCreateDatabase(Firebird::IStatus* status,
unsigned stmtLength, const char* creatDBstatement, unsigned dialect,
FB_BOOLEAN* stmtIsCreateDb = NULL) = 0;
};
#define FB_UTL_VERSION (FB_VERSIONED_VERSION + 6)
} // namespace Firebird
#endif // FB_UTL_INTERFACE

View File

@ -59,6 +59,7 @@
#include "../jrd/ods.h"
#include "../common/utils_proto.h"
#include "../jrd/constants.h"
//#include "../common/classes/ImplementHelper.h"
using MsgFormat::SafeArg;
@ -123,11 +124,9 @@ int EXTRACT_ddl(LegacyTables flag, const SCHAR* tabname)
if (!DB)
{
if (isc_attach_database(gds_status, 0, isqlGlob.global_Db_name, &DB, 0, NULL))
{
ISQL_errmsg(gds_status);
DB = fbProvider->attachDatabase(fbStatus, isqlGlob.global_Db_name, 0, NULL);
if (ISQL_errmsg(fbStatus))
return FINI_ERROR;
}
did_attach = true;
// Make it read owner name to display grantor correctly
@ -153,13 +152,11 @@ int EXTRACT_ddl(LegacyTables flag, const SCHAR* tabname)
isqlGlob.printf(NEWLINE);
bool did_start = false;
if (!gds_trans)
if (!fbTrans)
{
if (isc_start_transaction(gds_status, &gds_trans, 1, &DB, 0, NULL))
{
ISQL_errmsg(gds_status);
fbTrans = DB->startTransaction(fbStatus, 0, NULL);
if (ISQL_errmsg(fbStatus))
return FINI_ERROR;
}
did_start = true;
}
@ -201,20 +198,19 @@ int EXTRACT_ddl(LegacyTables flag, const SCHAR* tabname)
SHOW_comments(false); // Let's make this an option later.
}
if (gds_trans && did_start)
if (isc_commit_transaction(gds_status, &gds_trans))
{
ISQL_errmsg(gds_status);
if (fbTrans && did_start)
{
fbTrans->commit(fbStatus);
if (ISQL_errmsg(fbStatus))
return FINI_ERROR;
}
fbTrans = NULL;
}
if (DB && did_attach)
{
if (isc_detach_database(gds_status, &DB))
{
ISQL_errmsg(gds_status);
DB->detach(fbStatus);
if (ISQL_errmsg(fbStatus))
return FINI_ERROR;
}
DB = 0;
}
@ -383,7 +379,7 @@ int EXTRACT_list_table(const SCHAR* relation_name,
{
isqlGlob.printf("COMPUTED BY ");
if (!FLD.RDB$COMPUTED_SOURCE.NULL)
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$COMPUTED_SOURCE, true, gds_trans);
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$COMPUTED_SOURCE, true, fbTrans);
}
else if (!(fb_utils::implicit_domain(FLD.RDB$FIELD_NAME) && FLD.RDB$SYSTEM_FLAG != 1))
{
@ -488,7 +484,7 @@ int EXTRACT_list_table(const SCHAR* relation_name,
}
END_FOR
ON_ERROR
ISQL_errmsg(isc_status);
ISQL_errmsg(fbStatus);
return ps_ERR;
END_ERROR
}
@ -521,7 +517,7 @@ int EXTRACT_list_table(const SCHAR* relation_name,
}
END_FOR
ON_ERROR
ISQL_errmsg (gds_status);
ISQL_errmsg (fbStatus);
return FINI_ERROR;
END_ERROR;
@ -539,7 +535,7 @@ int EXTRACT_list_table(const SCHAR* relation_name,
}
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return FINI_ERROR;
END_ERROR;
@ -631,7 +627,7 @@ static bool extract_rel_constraints(const char* relation_name)
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return false;
END_ERROR;
@ -839,7 +835,7 @@ static void get_procedure_args(const char* proc_name)
}
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1058,7 +1054,7 @@ static void get_function_args_ods12(const char* func_name, USHORT out_arg)
}
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1159,7 +1155,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR;
}
@ -1190,7 +1186,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR;
@ -1216,7 +1212,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR;
@ -1235,7 +1231,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
first = false;
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR
@ -1253,7 +1249,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
first = false;
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR
@ -1270,7 +1266,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
first = false;
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR
@ -1287,7 +1283,7 @@ static processing_state list_all_grants2(bool show_role_list, const SCHAR* termi
first = false;
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return OBJECT_NOT_FOUND;
END_ERROR
}
@ -1400,7 +1396,7 @@ static void list_all_procs()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1433,9 +1429,9 @@ static void list_all_procs()
END_FOR
ON_ERROR
IUTILS_msg_get(GEN_ERR, msg, SafeArg() << isc_sqlcode(gds_status));
IUTILS_msg_get(GEN_ERR, msg, SafeArg() << isc_sqlcode(fbStatus->get()));
STDERROUT(msg); // Statement failed, SQLCODE = %d\n\n
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1480,7 +1476,7 @@ static void list_all_tables(LegacyTables flag, SSHORT default_char_set_id)
EXTRACT_list_table (REL.RDB$RELATION_NAME, NULL, false, default_char_set_id);
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
ROLLBACK;
return;
END_ERROR;
@ -1549,7 +1545,7 @@ static void list_all_triggers()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1609,7 +1605,7 @@ static void list_all_triggers()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1676,7 +1672,7 @@ static void list_check()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -1726,7 +1722,7 @@ static void list_charsets()
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1810,7 +1806,7 @@ static void list_collations()
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -1862,7 +1858,7 @@ static void list_create_db()
* the page size in a comment with the extracted db name
*
**************************************/
static const SCHAR page_items[] =
static const UCHAR page_items[] =
{
isc_info_page_size,
isc_info_end
@ -1896,7 +1892,7 @@ static void list_create_db()
fb_utils::exact_name(DBP.RDB$CHARACTER_SET_NAME));
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -2000,7 +1996,7 @@ static void list_create_db()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -2104,7 +2100,7 @@ static void list_domain_table(const SCHAR* table_name, SSHORT default_char_set_i
if (!FLD.RDB$VALIDATION_SOURCE.NULL)
{
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE, false, gds_trans);
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE, false, fbTrans);
}
if (FLD.RDB$NULL_FLAG == 1)
isqlGlob.printf(" NOT NULL");
@ -2128,7 +2124,7 @@ static void list_domain_table(const SCHAR* table_name, SSHORT default_char_set_i
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2243,7 +2239,7 @@ static void list_domains(SSHORT default_char_set_id)
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2275,12 +2271,12 @@ static void listDomainConstraints()
isqlGlob.printf("ALTER DOMAIN %s ADD CONSTRAINT", FLD.RDB$FIELD_NAME);
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE, false, gds_trans);
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$VALIDATION_SOURCE, false, fbTrans);
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2325,7 +2321,7 @@ static void list_exceptions()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2379,7 +2375,7 @@ static void list_filters()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -2474,7 +2470,7 @@ static void list_foreign()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2578,7 +2574,7 @@ static void list_functions_legacy()
END_FOR
ON_ERROR
ISQL_errmsg (gds_status);
ISQL_errmsg (fbStatus);
return;
END_ERROR;
@ -2664,7 +2660,7 @@ static void list_functions_legacy()
END_FOR
ON_ERROR
ISQL_errmsg (gds_status);
ISQL_errmsg (fbStatus);
return;
END_ERROR;
@ -2684,7 +2680,7 @@ static void list_functions_legacy()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2729,7 +2725,7 @@ static void list_functions_ods12()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -2763,9 +2759,9 @@ static void list_functions_ods12()
END_FOR
ON_ERROR
IUTILS_msg_get(GEN_ERR, msg, SafeArg() << isc_sqlcode(gds_status));
IUTILS_msg_get(GEN_ERR, msg, SafeArg() << isc_sqlcode(fbStatus->get()));
STDERROUT(msg); // Statement failed, SQLCODE = %d\n\n
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -2818,7 +2814,7 @@ static void list_generators()
}
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -2895,7 +2891,7 @@ static void list_indexes()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}
@ -2954,7 +2950,7 @@ static void list_package_bodies()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -3017,7 +3013,7 @@ static void list_package_headers()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
@ -3084,7 +3080,7 @@ static void list_views()
END_FOR
ON_ERROR
ISQL_errmsg (gds_status);
ISQL_errmsg (fbStatus);
return;
END_ERROR;
@ -3097,7 +3093,7 @@ static void list_views()
END_FOR
ON_ERROR
ISQL_errmsg(gds_status);
ISQL_errmsg(fbStatus);
return;
END_ERROR;
}

File diff suppressed because it is too large Load Diff

View File

@ -94,12 +94,12 @@ enum LegacyTables
ALL_objects
};
const size_t WORDLENGTH = 32;
const size_t WORDLENGTH = 32;
// The worst case of a quoted identifier is 31 * 2 => 62 + 2 DQUOTES + TERM => 65.
const size_t QUOTEDLENGTH = 65;
const size_t QUOTEDLENGTH = 65;
static const char* const DEFTERM = ";";
static const char* const DEFCHARSET = "NONE";
const int NULL_DISP_LEN = 6;
const unsigned NULL_DISP_LEN = 6;
// Error codes
@ -265,6 +265,9 @@ const int NO_GRANT_ON_CS = 177; // There is no privilege granted on character
const int NO_GRANT_ON_COLL = 178; // There is no privilege granted on collation @1 in this database
const int NO_GRANT_ON_PKG = 179; // There is no privilege granted on package @1 in this database
const int NO_GRANT_ON_FUN = 180; // There is no privilege granted on function @1 in this database
const int REPORT_NEW1 = 181; // Current memory = !\nDelta memory = !\nMax memory = !\nElapsed time= ~ sec\n
const int REPORT_NEW2 = 182; // Cpu = ~ sec\n (skipped on windows)
const int REPORT_NEW3 = 183; // Buffers = !\nReads = !\nWrites = !\nFetches = !\n
// Initialize types
@ -407,4 +410,33 @@ const char BLANK = '\040';
const char DBL_QUOTE = '\042';
const char SINGLE_QUOTE = '\'';
struct IsqlVar
{
const char* field;
const char* relation;
const char* owner;
const char* alias;
int subType, scale;
unsigned type, length, charSet;
bool nullable;
short* nullInd;
union TypeMix
{
ISC_TIMESTAMP* asDateTime;
ISC_TIME* asTime;
ISC_DATE* asDate;
SSHORT* asSmallint;
SLONG* asInteger;
SINT64* asBigint;
float* asFloat;
double* asDouble;
FB_BOOLEAN* asBoolean;
ISC_QUAD* blobid;
vary* asVary;
char* asChar;
void* setPtr;
};
TypeMix value;
};
#endif // ISQL_ISQL_H

View File

@ -24,6 +24,10 @@
#ifndef ISQL_ISQL_PROTO_H
#define ISQL_ISQL_PROTO_H
#include <firebird/Provider.h>
struct IsqlVar;
void ISQL_array_dimensions(const TEXT*);
//void ISQL_build_table_list(void**, FILE*, FILE*, FILE*);
//void ISQL_build_view_list(void**, FILE*, FILE*, FILE*);
@ -35,7 +39,7 @@ void ISQL_array_dimensions(const TEXT*);
// SCHAR*, FILE*, FILE*, FILE*);
bool ISQL_dbcheck();
void ISQL_disconnect_database(bool);
void ISQL_errmsg(const ISC_STATUS*);
bool ISQL_errmsg(Firebird::IStatus*);
void ISQL_warning(ISC_STATUS*);
void ISQL_exit_db();
// CVC: Not found.
@ -55,12 +59,13 @@ bool ISQL_is_domain(const TEXT*);
#endif
int ISQL_main(int, char**);
bool ISQL_printNumericType(const char* fieldName, const int fieldType, const int fieldScale);
void ISQL_print_validation(FILE*, ISC_QUAD*, bool, FB_API_HANDLE);
void ISQL_print_validation(FILE*, ISC_QUAD*, bool, Firebird::ITransaction*);
//void ISQL_query_database(SSHORT*, FILE*, FILE*, FILE*);
//void ISQL_reset_settings();
void ISQL_ri_action_print(const TEXT*, const TEXT*, bool);
//int ISQL_sql_statement(TEXT*, FILE*, FILE*, FILE*);
//void ISQL_win_err(const char*);
processing_state ISQL_print_item_blob(FILE*, const XSQLVAR*, FB_API_HANDLE, int subtype);
processing_state ISQL_print_item_blob(FILE*, const IsqlVar*, Firebird::ITransaction*, int subtype);
processing_state ISQL_fill_var(IsqlVar*, Firebird::IMessageMetadata*, unsigned, UCHAR*);
#endif // ISQL_ISQL_PROTO_H

File diff suppressed because it is too large Load Diff

View File

@ -25,9 +25,10 @@
#define ISQL_SHOW_PROTO_H
#include "../common/classes/fb_string.h"
#include <firebird/Provider.h>
void SHOW_comments(bool force);
bool SHOW_dbb_parameters (FB_API_HANDLE, SCHAR*, const SCHAR*, USHORT, bool, const char*);
bool SHOW_dbb_parameters (Firebird::IAttachment*, SCHAR*, const UCHAR*, unsigned, bool, const char*);
processing_state SHOW_grants (const SCHAR*, const SCHAR*, USHORT);
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, USHORT, const TEXT*, bool);
void SHOW_grant_roles (const SCHAR*, bool*);

View File

@ -13,7 +13,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
('2012-02-18 20:00:00', 'SQLERR', 13, 1033)
('1996-11-07 13:38:42', 'SQLWARN', 14, 613)
('2006-09-10 03:04:31', 'JRD_BUGCHK', 15, 307)
('2013-08-21 23:00:00', 'ISQL', 17, 181)
('2014-01-13 15:41:16', 'ISQL', 17, 184)
('2010-07-10 10:50:30', 'GSEC', 18, 105)
('2012-05-25 19:59:42', 'GSTAT', 21, 56)
('2013-12-19 17:31:31', 'FBSVCMGR', 22, 58)

View File

@ -2936,6 +2936,17 @@ Fetches = !f', NULL, NULL);
('NO_GRANT_ON_COLL', 'SHOW_metadata', 'show.e', NULL, 17, 178, NULL, 'There is no privilege granted on collation @1 in this database', NULL, NULL);
('NO_GRANT_ON_PKG', 'SHOW_metadata', 'show.e', NULL, 17, 179, NULL, 'There is no privilege granted on package @1 in this database', NULL, NULL);
('NO_GRANT_ON_FUN', 'SHOW_metadata', 'show.e', NULL, 17, 180, NULL, 'There is no privilege granted on function @1 in this database', NULL, NULL);
('REPORT_NEW1', 'print_performance', 'isql.epp', 'Each of these 4 items is followed by a newline (''\n'').', 17, 181, NULL, 'Current memory = !
Delta memory = !
Max memory = !
Elapsed time= ~ sec
', NULL, NULL);
('REPORT_NEW2', 'print_performance', 'isql.epp', 'Each of these 5 items is followed by a newline (''\n'').', 17, 182, NULL, 'Cpu = ~ sec
', NULL, NULL);
('REPORT_NEW3', 'print_performance', 'isql.epp', 'Each of these 5 items is followed by a newline (''\n'').', 17, 183, NULL, 'Buffers = !
Reads = !
Writes = !
Fetches = !', NULL, NULL);
-- GSEC
('GsecMsg1', 'get_line', 'gsec.e', NULL, 18, 1, NULL, 'GSEC>', NULL, NULL);
('GsecMsg2', 'printhelp', 'gsec.e', 'This message is used in the Help display. It should be the same as number 1 (but in lower case).', 18, 2, NULL, 'gsec', NULL, NULL);

View File

@ -107,7 +107,7 @@ void BlrFromMessage::buildBlr(IMessageMetadata* metadata)
checkStatus(&st);
unsigned charSet = metadata->getCharSet(&st, i);
checkStatus(&st);
unsigned subType = metadata->getSubType(&st, i);
int subType = metadata->getSubType(&st, i);
checkStatus(&st);
switch (dtype)

View File

@ -45,6 +45,7 @@
#include "../common/ThreadStart.h"
#include "../common/utils_proto.h"
#include "../jrd/ibase.h"
#include "../yvalve/utl_proto.h"
using namespace Firebird;
@ -667,6 +668,21 @@ Mutex& pauseTimer()
} // namespace Why
//
// Utl (misc calls)
//
namespace Why {
Firebird::IUtl* FB_CARG MasterImplementation::getUtlInterface()
{
extern UtlInterface utlInterface; // Implemented in utl.cpp
return &utlInterface;
}
} // namespace Why
//
// get master
//

View File

@ -74,6 +74,7 @@ namespace Why
Firebird::IMetadataBuilder* FB_CARG getMetadataBuilder(Firebird::IStatus* status, unsigned fieldCount);
Firebird::IDebug* FB_CARG getDebug();
int FB_CARG serverMode(int mode);
Firebird::IUtl* FB_CARG getUtlInterface();
};
void shutdownTimers();

View File

@ -34,7 +34,9 @@
#include "../yvalve/perf.h"
#include "../yvalve/gds_proto.h"
#include "../yvalve/perf_proto.h"
#include "../yvalve/utl_proto.h"
#include "../common/gdsassert.h"
#include "../common/classes/fb_string.h"
#if defined(TIME_WITH_SYS_TIME)
#include <sys/time.h>
@ -49,8 +51,29 @@
#include <sys/timeb.h>
#endif
template <typename T>
static SINT64 get_parameter(const T** ptr)
{
/**************************************
*
* g e t _ p a r a m e t e r
*
**************************************
*
* Functional description
* Get a parameter (length is encoded), convert to internal form,
* and return.
*
**************************************/
SSHORT l = *(*ptr)++;
l += (*(*ptr)++) << 8;
const SINT64 parameter = isc_portable_integer(reinterpret_cast<const ISC_UCHAR*>(*ptr), l);
*ptr += l;
return parameter;
}
static SINT64 get_parameter(const SCHAR**);
#ifndef HAVE_TIMES
static void times(struct tms*);
#endif
@ -334,28 +357,6 @@ static void perf_report(const P* before, const P* after, SCHAR* buffer, SSHORT*
}
static SINT64 get_parameter(const SCHAR** ptr)
{
/**************************************
*
* g e t _ p a r a m e t e r
*
**************************************
*
* Functional description
* Get a parameter (length is encoded), convert to internal form,
* and return.
*
**************************************/
SSHORT l = *(*ptr)++;
l += (*(*ptr)++) << 8;
const SINT64 parameter = isc_portable_integer(reinterpret_cast<const ISC_UCHAR*>(*ptr), l);
*ptr += l;
return parameter;
}
#ifndef HAVE_TIMES
static void times(struct tms* buffer)
{
@ -408,3 +409,175 @@ void API_ROUTINE perf64_report(const PERF64* before, const PERF64* after, SCHAR*
{
perf_report<PERF64>(before, after, buffer, buf_len);
}
namespace {
static const unsigned CNT_DB_INFO = 1;
static const unsigned CNT_TIMER = 2;
enum CntTimer {CNT_TIME_REAL, CNT_TIME_USER, CNT_TIME_SYSTEM};
struct KnownCounters
{
const char* name;
unsigned type;
unsigned code;
};
#define TOTAL_COUNTERS 11
// we use case-insensitive names, here they are written with capital letters for human readability
KnownCounters knownCounters[TOTAL_COUNTERS] = {
{"RealTime", CNT_TIMER, CNT_TIME_REAL},
{"UserTime", CNT_TIMER, CNT_TIME_USER},
{"SystemTime", CNT_TIMER, CNT_TIME_SYSTEM},
{"Fetches", CNT_DB_INFO, isc_info_fetches},
{"Marks", CNT_DB_INFO, isc_info_marks},
{"Reads", CNT_DB_INFO, isc_info_reads},
{"Writes", CNT_DB_INFO, isc_info_writes},
{"CurrentMemory", CNT_DB_INFO, isc_info_current_memory},
{"MaxMemory", CNT_DB_INFO, isc_info_max_memory},
{"Buffers", CNT_DB_INFO, isc_info_num_buffers},
{"PageSize", CNT_DB_INFO, isc_info_page_size}
};
} // anonymous namespace
void FB_CARG Why::UtlInterface::getPerfCounters(Firebird::IStatus* status, Firebird::IAttachment* att,
const char* countersSet, ISC_INT64* counters)
{
try
{
// Parse countersSet
unsigned cntLink[TOTAL_COUNTERS];
memset(cntLink, 0xFF, sizeof cntLink);
Firebird::string dupSet(countersSet);
char* set = dupSet.begin();
char* save = NULL;
const char* delim = " \t,;";
unsigned typeMask = 0;
unsigned n = 0;
UCHAR info[TOTAL_COUNTERS]; // will never use all, but do not care about few bytes
UCHAR* pinfo = info;
for (char* nm = strtok_r(set, delim, &save); nm; nm = strtok_r(NULL, delim, &save))
{
Firebird::NoCaseString name(nm);
for (unsigned i = 0; i < TOTAL_COUNTERS; ++i)
{
if (name == knownCounters[i].name)
{
if (cntLink[i] != ~0u)
{
(Firebird::Arg::Gds(isc_random) << "Duplicated name").raise(); //report name & position
}
cntLink[i] = n++;
typeMask |= knownCounters[i].type;
if (knownCounters[i].type == CNT_DB_INFO)
{
*pinfo++ = knownCounters[i].code;
}
goto found;
}
}
(Firebird::Arg::Gds(isc_random) << "Unknown name").raise(); //report name & position
found: ;
}
// Force reset counters
memset(counters, 0, n * sizeof(ISC_INT64));
// Fill time counters
if (typeMask & CNT_TIMER)
{
struct tms tus;
clock_t tr = times(&tus);
for (unsigned i = 0; i < TOTAL_COUNTERS; ++i)
{
if (cntLink[i] == ~0u)
continue;
if (knownCounters[i].type == CNT_TIMER)
{
clock_t v = 0;
switch(knownCounters[i].code)
{
case CNT_TIME_REAL:
v = tr;
break;
case CNT_TIME_USER:
v = tus.tms_utime;
break;
case CNT_TIME_SYSTEM:
v = tus.tms_stime;
break;
default:
fb_assert(false);
break;
}
counters[cntLink[i]] = v;
}
}
}
// Fill DB counters
if (typeMask & CNT_DB_INFO)
{
UCHAR buffer[BUFFER_LARGE];
att->getInfo(status, pinfo - info, info, sizeof(buffer), buffer);
if (!status->isSuccess())
{
return;
}
const UCHAR* p = buffer;
while (true)
{
SINT64 v = 0;
UCHAR ipb = *p++;
switch (ipb)
{
case isc_info_reads:
case isc_info_writes:
case isc_info_marks:
case isc_info_fetches:
case isc_info_num_buffers:
case isc_info_page_size:
case isc_info_current_memory:
case isc_info_max_memory:
v = get_parameter(&p);
break;
case isc_info_end:
goto parsed;
case isc_info_error:
{
const SINT64 temp = isc_portable_integer(p, 2);
fb_assert(temp <= MAX_SSHORT);
p += temp + 2;
continue;
}
default:
(Firebird::Arg::Gds(isc_random) << "Unknown info code").raise(); //report char code
}
for (unsigned i = 0; i < TOTAL_COUNTERS; ++i)
{
if (knownCounters[i].type == CNT_DB_INFO && knownCounters[i].code == ipb)
{
if (cntLink[i] != ~0u)
{
counters[cntLink[i]] = v;
}
break;
}
}
}
parsed: ;
}
}
catch (const Firebird::Exception& ex)
{
ex.stuffException(status);
}
}

View File

@ -24,7 +24,15 @@
#ifndef DSQL_PREPA_PROTO_H
#define DSQL_PREPA_PROTO_H
bool PREPARSE_execute(ISC_STATUS*, FB_API_HANDLE*, FB_API_HANDLE*, USHORT, const SCHAR*,
bool*, USHORT);
namespace Firebird {
class IStatus;
}
namespace Why {
class YAttachment;
}
bool PREPARSE_execute(Firebird::IStatus*, Why::YAttachment**,
USHORT, const SCHAR*, bool*, USHORT);
#endif // DSQL_PREPA_PROTO_H

View File

@ -25,14 +25,18 @@
#include "firebird.h"
#include <stdlib.h>
#include <string.h>
#include "../jrd/ibase.h"
//#include "../jrd/ibase.h"
#include "../dsql/chars.h"
#include "../dsql/sqlda.h"
//#include "../dsql/sqlda.h"
#include "../yvalve/prepa_proto.h"
#include "../yvalve/gds_proto.h"
#include "../yvalve/YObjects.h"
#include "../common/classes/ClumpletWriter.h"
//#include "../common/classes/ImplementHelper.h"
#include "../common/StatusArg.h"
#include <firebird/Provider.h>
enum pp_vals {
PP_CREATE = 0,
PP_DATABASE = 1,
@ -50,9 +54,9 @@ enum pp_vals {
const size_t MAX_TOKEN_SIZE = 1024;
static void generate_error(ISC_STATUS*, const Firebird::string&, SSHORT, SSHORT);
static void generate_error(Firebird::IStatus*, const Firebird::string&, SSHORT, SSHORT);
static SSHORT get_next_token(const SCHAR**, const SCHAR*, Firebird::string&);
static SSHORT get_token(ISC_STATUS*, SSHORT, bool, const SCHAR**, const SCHAR* const,
static SSHORT get_token(Firebird::IStatus*, SSHORT, bool, const SCHAR**, const SCHAR* const,
Firebird::string&);
struct pp_table
@ -102,17 +106,15 @@ using namespace Firebird;
@brief
@param user_status
@param db_handle
@param trans_handle
@param status
@param ptrAtt
@param stmt_length
@param stmt
@param stmt_eaten
@param dialect
**/
bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
FB_API_HANDLE*, // trans_handle,
bool PREPARSE_execute(IStatus* status, Why::YAttachment** ptrAtt,
USHORT stmt_length, const SCHAR* stmt, bool* stmt_eaten, USHORT dialect)
{
// no use creating separate pool for a couple of strings
@ -130,13 +132,13 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
const char* const stmt_end = stmt + stmt_length;
string token;
if (get_token(user_status, SYMBOL, false, &stmt, stmt_end, token) ||
if (get_token(status, SYMBOL, false, &stmt, stmt_end, token) ||
token.length() != pp_symbols[PP_CREATE].length || token != pp_symbols[PP_CREATE].symbol)
{
return false;
}
if (get_token(user_status, SYMBOL, false, &stmt, stmt_end, token) ||
if (get_token(status, SYMBOL, false, &stmt, stmt_end, token) ||
(token.length() != pp_symbols[PP_DATABASE].length &&
token.length() != pp_symbols[PP_SCHEMA].length) ||
(token != pp_symbols[PP_DATABASE].symbol && token != pp_symbols[PP_SCHEMA].symbol))
@ -144,7 +146,7 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
return false;
}
if (get_token(user_status, STRING, false, &stmt, stmt_end, token))
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
return true;
}
@ -182,8 +184,8 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
{
case PP_PAGE_SIZE:
case PP_PAGESIZE:
if (get_token(user_status, '=', true, &stmt, stmt_end, token) ||
get_token(user_status, NUMERIC, false, &stmt, stmt_end, token))
if (get_token(status, '=', true, &stmt, stmt_end, token) ||
get_token(status, NUMERIC, false, &stmt, stmt_end, token))
{
get_out = true;
break;
@ -194,7 +196,7 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
break;
case PP_USER:
if (get_token(user_status, STRING, false, &stmt, stmt_end, token))
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
@ -205,7 +207,7 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
break;
case PP_PASSWORD:
if (get_token(user_status, STRING, false, &stmt, stmt_end, token))
if (get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
@ -216,10 +218,10 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
break;
case PP_SET:
if (get_token(user_status, SYMBOL, false, &stmt, stmt_end, token) ||
if (get_token(status, SYMBOL, false, &stmt, stmt_end, token) ||
token.length() != pp_symbols[PP_NAMES].length ||
token != pp_symbols[PP_NAMES].symbol ||
get_token(user_status, STRING, false, &stmt, stmt_end, token))
get_token(status, STRING, false, &stmt, stmt_end, token))
{
get_out = true;
break;
@ -232,8 +234,8 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
case PP_LENGTH:
// Skip a token for value
if (get_token(user_status, '=', true, &stmt, stmt_end, token) ||
get_token(user_status, NUMERIC, false, &stmt, stmt_end, token))
if (get_token(status, '=', true, &stmt, stmt_end, token) ||
get_token(status, NUMERIC, false, &stmt, stmt_end, token))
{
get_out = true;
break;
@ -256,13 +258,13 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
} while (matched);
isc_create_database(user_status, 0, file_name.c_str(), db_handle,
dpb.getBufferLength(), reinterpret_cast<const ISC_SCHAR*>(dpb.getBuffer()),
0);
RefPtr<Why::Dispatcher> dispatcher(new Why::Dispatcher);
*ptrAtt = dispatcher->createDatabase(status, file_name.c_str(),
dpb.getBufferLength(), dpb.getBuffer());
}
catch (const Exception& ex)
{
ex.stuff_exception(user_status);
ex.stuffException(status);
return true;
}
@ -276,27 +278,28 @@ bool PREPARSE_execute(ISC_STATUS* user_status, FB_API_HANDLE* db_handle,
@brief
@param user_status
@param status
@param token
@param error
@param result
**/
static void generate_error(ISC_STATUS* user_status, const string& token, SSHORT error, SSHORT result)
static void generate_error(IStatus* status, const string& token, SSHORT error, SSHORT result)
{
string err_string;
user_status[0] = isc_arg_gds;
user_status[1] = isc_sqlerr;
user_status[2] = isc_arg_number;
user_status[3] = -104;
user_status[4] = isc_arg_gds;
ISC_STATUS_ARRAY temp_status;
temp_status[0] = isc_arg_gds;
temp_status[1] = isc_sqlerr;
temp_status[2] = isc_arg_number;
temp_status[3] = -104;
temp_status[4] = isc_arg_gds;
switch (error)
{
case UNEXPECTED_END_OF_COMMAND:
user_status[5] = isc_command_end_err;
user_status[6] = isc_arg_end;
temp_status[5] = isc_command_end_err;
temp_status[6] = isc_arg_end;
break;
case UNEXPECTED_TOKEN:
@ -309,15 +312,17 @@ static void generate_error(ISC_STATUS* user_status, const string& token, SSHORT
}
else
err_string = token;
user_status[5] = isc_token_err;
user_status[6] = isc_arg_gds;
user_status[7] = isc_random;
user_status[8] = isc_arg_string;
user_status[9] = (ISC_STATUS)(err_string.c_str());
user_status[10] = isc_arg_end;
Firebird::makePermanentVector(user_status);
temp_status[5] = isc_token_err;
temp_status[6] = isc_arg_gds;
temp_status[7] = isc_random;
temp_status[8] = isc_arg_string;
temp_status[9] = (ISC_STATUS)(err_string.c_str());
temp_status[10] = isc_arg_end;
Firebird::makePermanentVector(temp_status);
break;
}
status->set(temp_status);
}
@ -470,7 +475,7 @@ static SSHORT get_next_token(const SCHAR** stmt, const SCHAR* stmt_end, string&
@param token
**/
static SSHORT get_token(ISC_STATUS* status,
static SSHORT get_token(IStatus* status,
SSHORT token_type,
bool optional,
const SCHAR** stmt,

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,11 @@
#ifndef JRD_UTL_PROTO_H
#define JRD_UTL_PROTO_H
#include <firebird/Utl.h>
#include "fb_types.h"
#include "../yvalve/YObjects.h"
#include "../common/classes/ImplementHelper.h"
#ifdef __cplusplus
extern "C" {
@ -78,5 +82,29 @@ namespace Firebird
}
void setLogin(Firebird::ClumpletWriter& dpb, bool spbFlag);
namespace Why
{
class UtlInterface : public Firebird::AutoIface<Firebird::IUtl, FB_UTL_VERSION>
{
// IUtl implementation
public:
void FB_CARG version(Firebird::IStatus* status, Firebird::IAttachment* att,
Firebird::IVersionCallback* callback);
void FB_CARG loadBlob(Firebird::IStatus* status, ISC_QUAD* blobId, Firebird::IAttachment* att,
Firebird::ITransaction* tra, const char* file, FB_BOOLEAN txt);
void FB_CARG dumpBlob(Firebird::IStatus* status, ISC_QUAD* blobId, Firebird::IAttachment* att,
Firebird::ITransaction* tra, const char* file, FB_BOOLEAN txt);
FB_BOOLEAN FB_CARG editBlob(Firebird::IStatus* status, ISC_QUAD* blobId,
Firebird::IAttachment* att, Firebird::ITransaction* tra, const char* tempFile = NULL);
void FB_CARG getPerfCounters(Firebird::IStatus* status, Firebird::IAttachment* att,
const char* countersSet, ISC_INT64* counters); // in perf.cpp
virtual YAttachment* FB_CARG executeCreateDatabase(Firebird::IStatus* status,
unsigned stmtLength, const char* creatDBstatement, unsigned dialect,
FB_BOOLEAN* stmtIsCreateDb = NULL);
};
}
#endif // JRD_UTL_PROTO_H

View File

@ -62,7 +62,7 @@
#include "../common/classes/GetPlugins.h"
#include "../common/classes/fb_tls.h"
#include "../common/classes/InternalMessageBuffer.h"
#include "../yvalve/prepa_proto.h"
//#include "../yvalve/prepa_proto.h"
#include "../yvalve/utl_proto.h"
#include "../yvalve/why_proto.h"
#include "../yvalve/MasterImplementation.h"
@ -85,7 +85,7 @@ using namespace Why;
static void badHandle(ISC_STATUS code);
static bool isNetworkError(const IStatus* status);
static void nullCheck(const FB_API_HANDLE* ptr, ISC_STATUS code);
static void saveErrorString(ISC_STATUS* status);
//static void saveErrorString(ISC_STATUS* status);
static void error804(ISC_STATUS err);
static void sqldaDescribeParameters(XSQLDA* sqlda, const IMessageMetadata* parameters);
static void sqldaMove(const XSQLDA* sqlda, Array<UCHAR>& message, bool binding);
@ -103,6 +103,7 @@ static const USHORT DESCRIBE_BUFFER_SIZE = 1024; // size of buffer used in isc_d
namespace Why {
class StatusVector;
extern UtlInterface utlInterface;
};
namespace {
@ -909,6 +910,7 @@ static void nullCheck(const FB_API_HANDLE* ptr, ISC_STATUS code)
// This is need because there are cases where the memory allocated for strings in the status vector
// is freed prior to surfacing them to the user. This is an attempt to save off 1 string to surface
// to the user. Any other strings will be set to a standard <Unknown> string.
/*
static void saveErrorString(ISC_STATUS* status)
{
const int MAXERRORSTRINGLENGTH = 250;
@ -974,7 +976,7 @@ static void saveErrorString(ISC_STATUS* status)
}
}
}
*/
// Raises a DSQL -804 error message.
static void error804(ISC_STATUS err)
{
@ -1357,6 +1359,43 @@ ISC_STATUS API_ROUTINE fb_database_crypt_callback(ISC_STATUS* userStatus, ICrypt
//-------------------------------------
Firebird::IAttachment* handleToIAttachment(Firebird::IStatus* status, FB_API_HANDLE* handle)
{
try
{
RefPtr<YAttachment> attachment(translateHandle(attachments, handle));
attachment->addRef();
return attachment;
}
catch (const Exception& e)
{
e.stuffException(status);
}
return NULL;
}
Firebird::ITransaction* handleToITransaction(Firebird::IStatus* status, FB_API_HANDLE* handle)
{
try
{
RefPtr<YTransaction> transaction(translateHandle(transactions, handle));
transaction->addRef();
return transaction;
}
catch (const Exception& e)
{
e.stuffException(status);
}
return NULL;
}
//-------------------------------------
// Attach a database through the first subsystem that recognizes it.
ISC_STATUS API_ROUTINE isc_attach_database(ISC_STATUS* userStatus, SSHORT fileLength,
const TEXT* filename, FB_API_HANDLE* publicHandle, SSHORT dpbLength, const SCHAR* dpb)
@ -2151,69 +2190,13 @@ ISC_STATUS API_ROUTINE isc_dsql_exec_immed2_m(ISC_STATUS* userStatus, FB_API_HAN
{
StatusVector status(userStatus);
bool stmtEaten;
FB_BOOLEAN stmtIsCrDb = FB_FALSE;
YAttachment* att = utlInterface.executeCreateDatabase(&status, stmtLength, sqlStmt, dialect, &stmtIsCrDb);
if (PREPARSE_execute(status, dbHandle, traHandle, stmtLength, sqlStmt, &stmtEaten, dialect))
if (stmtIsCrDb)
{
if (status[1])
return status[1];
ISC_STATUS_ARRAY tempStatus;
FB_API_HANDLE crdbTransHandle = 0;
if (isc_start_transaction(status, &crdbTransHandle, 1, dbHandle, 0, 0))
{
saveErrorString(status);
isc_drop_database(tempStatus, dbHandle);
*dbHandle = 0;
return status[1];
}
bool v3Error = false;
if (!stmtEaten)
{
// Check if against < 4.0 database.
const SCHAR ch = isc_info_base_level;
SCHAR buffer[16];
if (!isc_database_info(status, dbHandle, 1, &ch, sizeof(buffer), buffer))
{
if (buffer[0] != isc_info_base_level || buffer[4] > 3)
{
isc_dsql_exec_immed3_m(status, dbHandle, &crdbTransHandle,
stmtLength, sqlStmt, dialect,
inBlrLength, inBlr, inMsgType, inMsgLength, inMsg,
outBlrLength, outBlr, outMsgType, outMsgLength, outMsg);
}
else
v3Error = true;
}
}
if (status[1])
{
isc_rollback_transaction(tempStatus, &crdbTransHandle);
saveErrorString(status);
isc_drop_database(tempStatus, dbHandle);
*dbHandle = 0;
return status[1];
}
if (isc_commit_transaction(status, &crdbTransHandle))
{
isc_rollback_transaction(tempStatus, &crdbTransHandle);
saveErrorString(status);
isc_drop_database(tempStatus, dbHandle);
*dbHandle = 0;
return status[1];
}
if (v3Error)
{
Arg::Gds(isc_srvr_version_too_old).copyTo(status);
return status[1];
}
if (status.isSuccess())
*dbHandle = att->getHandle();
return status[1];
}

View File

@ -27,6 +27,9 @@
namespace Firebird
{
class ICryptKeyCallback;
class IStatus;
class IAttachment;
class ITransaction;
}
extern "C" {
@ -263,4 +266,7 @@ ISC_STATUS API_ROUTINE gds__transaction_cleanup(ISC_STATUS*, FB_API_HANDLE*,
} /* extern "C"*/
Firebird::IAttachment* handleToIAttachment(Firebird::IStatus*, FB_API_HANDLE*);
Firebird::ITransaction* handleToITransaction(Firebird::IStatus*, FB_API_HANDLE*);
#endif // JRD_WHY_PROTO_H