2004-03-28 11:10:30 +02:00
|
|
|
/*
|
2001-05-23 15:26:42 +02:00
|
|
|
* PROGRAM: JRD Access Method
|
2003-09-25 13:49:12 +02:00
|
|
|
* MODULE: utl.cpp
|
2001-05-23 15:26:42 +02:00
|
|
|
* DESCRIPTION: User callable routines
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase 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.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, 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 Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
2002-02-16 03:21:35 +01:00
|
|
|
*
|
2002-07-01 17:07:18 +02:00
|
|
|
* 2001.06.14 Claudio Valderrama: isc_set_path() will append slash if missing,
|
|
|
|
* so ISC_PATH environment variable won't fail for this cause.
|
2002-02-16 03:50:01 +01:00
|
|
|
* 2002.02.15 Sean Leyne - Code Cleanup is required of obsolete "EPSON", "XENIX" ports
|
2002-02-16 05:36:05 +01:00
|
|
|
* 2002.02.15 Sean Leyne - Code Cleanup, removed obsolete "Apollo" port
|
2002-02-23 11:27:40 +01:00
|
|
|
* 23-Feb-2002 Dmitry Yemanov - Events wildcarding
|
2002-02-16 03:21:35 +01:00
|
|
|
*
|
2002-10-28 05:42:54 +01:00
|
|
|
* 2002.10.27 Sean Leyne - Completed removal of obsolete "DG_X86" port
|
2002-10-28 05:57:07 +01:00
|
|
|
* 2002.10.27 Sean Leyne - Code Cleanup, removed obsolete "UNIXWARE" port
|
2002-10-28 06:19:52 +01:00
|
|
|
* 2002.10.27 Sean Leyne - Code Cleanup, removed obsolete "Ultrix" port
|
|
|
|
* 2002.10.27 Sean Leyne - Code Cleanup, removed obsolete "Ultrix/MIPS" port
|
2002-10-28 05:42:54 +01:00
|
|
|
*
|
2002-10-29 03:59:57 +01:00
|
|
|
* 2002.10.28 Sean Leyne - Code cleanup, removed obsolete "MPEXL" port
|
|
|
|
*
|
2002-10-30 07:40:58 +01:00
|
|
|
* 2002.10.29 Sean Leyne - Removed obsolete "Netware" port
|
|
|
|
*
|
2002-10-31 06:06:02 +01:00
|
|
|
* 2002.10.30 Sean Leyne - Removed support for obsolete "PC_PLATFORM" define
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2001-07-29 19:42:23 +02:00
|
|
|
#include "firebird.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <limits.h>
|
2004-04-29 00:43:34 +02:00
|
|
|
#include <stdio.h>
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2003-01-19 15:30:53 +01:00
|
|
|
#include "../jrd/license.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <stdarg.h>
|
2010-10-13 12:39:52 +02:00
|
|
|
#include "../common/gdsassert.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2014-07-24 08:41:38 +02:00
|
|
|
#include "../yvalve/msg.h"
|
2003-03-11 11:34:43 +01:00
|
|
|
#include "../jrd/event.h"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../yvalve/gds_proto.h"
|
|
|
|
#include "../yvalve/utl_proto.h"
|
2014-09-29 19:24:30 +02:00
|
|
|
#include "../yvalve/YObjects.h"
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
#include "../yvalve/why_proto.h"
|
|
|
|
#include "../yvalve/prepa_proto.h"
|
2004-03-28 11:10:30 +02:00
|
|
|
#include "../jrd/constants.h"
|
2015-07-26 20:25:15 +02:00
|
|
|
#include "../jrd/build_no.h"
|
2004-12-09 20:19:47 +01:00
|
|
|
#include "../common/classes/ClumpletWriter.h"
|
2004-12-23 07:28:41 +01:00
|
|
|
#include "../common/utils_proto.h"
|
2005-05-12 20:28:04 +02:00
|
|
|
#include "../common/classes/MetaName.h"
|
2006-06-30 21:09:24 +02:00
|
|
|
#include "../common/classes/TempFile.h"
|
2009-11-13 19:29:06 +01:00
|
|
|
#include "../common/classes/DbImplementation.h"
|
2010-10-12 10:02:57 +02:00
|
|
|
#include "../common/ThreadStart.h"
|
2012-03-15 16:05:31 +01:00
|
|
|
#include "../common/isc_f_proto.h"
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
#include "../common/StatusHolder.h"
|
|
|
|
#include "../common/classes/ImplementHelper.h"
|
2015-03-27 15:36:30 +01:00
|
|
|
#include "../common/classes/fb_tls.h"
|
2014-12-17 15:31:02 +01:00
|
|
|
#include "../common/os/os_utils.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 07:46:06 +02:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#if defined(WIN_NT)
|
2003-11-16 13:23:24 +01:00
|
|
|
#include <io.h> // mktemp, unlink ..
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <process.h>
|
2009-02-08 12:38:00 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_FILE_H
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <sys/file.h>
|
|
|
|
#endif
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
|
|
|
|
using namespace Firebird;
|
|
|
|
|
2015-03-27 18:51:19 +01:00
|
|
|
IAttachment* handleToIAttachment(CheckStatusWrapper*, FB_API_HANDLE*);
|
|
|
|
ITransaction* handleToITransaction(CheckStatusWrapper*, FB_API_HANDLE*);
|
2014-09-29 13:03:47 +02:00
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
// Bug 7119 - BLOB_load will open external file for read in BINARY mode.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#ifdef WIN_NT
|
2009-08-19 16:12:04 +02:00
|
|
|
static const char* const FOPEN_READ_TYPE = "rb";
|
|
|
|
static const char* const FOPEN_WRITE_TYPE = "wb";
|
|
|
|
static const char* const FOPEN_READ_TYPE_TEXT = "rt";
|
|
|
|
static const char* const FOPEN_WRITE_TYPE_TEXT = "wt";
|
2004-05-05 23:55:13 +02:00
|
|
|
#else
|
2009-08-19 16:12:04 +02:00
|
|
|
static const char* const FOPEN_READ_TYPE = "r";
|
|
|
|
static const char* const FOPEN_WRITE_TYPE = "w";
|
|
|
|
static const char* const FOPEN_READ_TYPE_TEXT = FOPEN_READ_TYPE;
|
|
|
|
static const char* const FOPEN_WRITE_TYPE_TEXT = FOPEN_WRITE_TYPE;
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define LOWER7(c) ( (c >= 'A' && c<= 'Z') ? c + 'a' - 'A': c )
|
|
|
|
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Blob stream stuff
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 23:43:56 +02:00
|
|
|
const int BSTR_input = 0;
|
|
|
|
const int BSTR_output = 1;
|
|
|
|
const int BSTR_alloc = 2;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
static void get_ods_version(CheckStatusWrapper*, IAttachment*, USHORT*, USHORT*);
|
2003-10-29 11:53:47 +01:00
|
|
|
static void isc_expand_dpb_internal(const UCHAR** dpb, SSHORT* dpb_size, ...);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Blob info stuff
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-01-20 09:33:59 +01:00
|
|
|
static const char blob_items[] =
|
2008-12-22 10:00:05 +01:00
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_info_blob_max_segment, isc_info_blob_num_segments,
|
|
|
|
isc_info_blob_total_length
|
2001-05-23 15:26:42 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// gds__version stuff
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
static const unsigned char info[] =
|
2009-11-13 19:29:06 +01:00
|
|
|
{ isc_info_firebird_version, isc_info_implementation, fb_info_implementation, isc_info_end };
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
static const unsigned char ods_info[] =
|
2002-07-01 17:07:18 +02:00
|
|
|
{ isc_info_ods_version, isc_info_ods_minor_version, isc_info_end };
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
static const TEXT* const impl_class[] =
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
NULL, // 0
|
|
|
|
"access method", // 1
|
|
|
|
"Y-valve", // 2
|
|
|
|
"remote interface", // 3
|
|
|
|
"remote server", // 4
|
|
|
|
NULL, // 5
|
|
|
|
NULL, // 6
|
|
|
|
"pipe interface", // 7
|
|
|
|
"pipe server", // 8
|
|
|
|
"central interface", // 9
|
|
|
|
"central server", // 10
|
|
|
|
"gateway", // 11
|
|
|
|
"classic server", // 12
|
|
|
|
"super server" // 13
|
2002-07-01 17:07:18 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
class VersionCallback : public AutoIface<IVersionCallbackImpl<VersionCallback, CheckStatusWrapper> >
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
VersionCallback(FPTR_VERSION_CALLBACK routine, void* user)
|
|
|
|
: func(routine), arg(user)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
// IVersionCallback implementation
|
2015-01-12 01:21:38 +01:00
|
|
|
void callback(CheckStatusWrapper*, const char* text)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
|
|
|
func(arg, text);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
FPTR_VERSION_CALLBACK func;
|
|
|
|
void* arg;
|
|
|
|
};
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
void load(CheckStatusWrapper* status, ISC_QUAD* blobId, IAttachment* att, ITransaction* tra, FILE* file)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l o a d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Load a blob from a file.
|
|
|
|
*
|
|
|
|
**************************************/
|
2015-03-20 19:02:30 +01:00
|
|
|
LocalStatus ls;
|
|
|
|
CheckStatusWrapper temp(&ls);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
|
|
|
|
// Open the blob. If it failed, what the hell -- just return failure
|
2014-10-25 20:39:45 +02:00
|
|
|
IBlob* blob = att->createBlob(status, tra, blobId, 0, NULL);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Copy data from file to blob. Make up boundaries at end of line.
|
|
|
|
TEXT buffer[512];
|
|
|
|
TEXT* p = buffer;
|
|
|
|
const TEXT* const buffer_end = buffer + sizeof(buffer);
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
const SSHORT c = fgetc(file);
|
|
|
|
if (feof(file))
|
|
|
|
break;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
*p++ = static_cast<TEXT>(c);
|
2014-01-17 16:05:19 +01:00
|
|
|
|
|
|
|
if (c != '\n' && p < buffer_end)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
continue;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
const SSHORT l = p - buffer;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
blob->putSegment(status, l, buffer);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
|
|
|
blob->close(&temp);
|
|
|
|
return;
|
|
|
|
}
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
p = buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SSHORT l = p - buffer;
|
|
|
|
if (l != 0)
|
|
|
|
blob->putSegment(status, l, buffer);
|
|
|
|
|
|
|
|
blob->close(&temp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
void dump(CheckStatusWrapper* status, ISC_QUAD* blobId, IAttachment* att, ITransaction* tra, FILE* file)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* d u m p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Dump a blob into a file.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
// Open the blob. If it failed, what the hell -- just return failure
|
|
|
|
|
2014-10-25 20:39:45 +02:00
|
|
|
IBlob* blob = att->openBlob(status, tra, blobId, 0, NULL);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Copy data from blob to scratch file
|
|
|
|
|
|
|
|
SCHAR buffer[256];
|
|
|
|
const SSHORT short_length = sizeof(buffer);
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
{
|
2014-08-27 11:24:30 +02:00
|
|
|
unsigned l = 0;
|
2014-09-07 21:37:00 +02:00
|
|
|
switch (blob->getSegment(status, short_length, buffer, &l))
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2015-02-18 16:01:17 +01:00
|
|
|
case Firebird::IStatus::RESULT_ERROR:
|
|
|
|
case Firebird::IStatus::RESULT_NO_DATA:
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l)
|
|
|
|
FB_UNUSED(fwrite(buffer, 1, l, file));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close the blob
|
|
|
|
|
2015-03-20 19:02:30 +01:00
|
|
|
LocalStatus ls;
|
|
|
|
CheckStatusWrapper temp(&ls);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
blob->close(&temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
FB_BOOLEAN edit(CheckStatusWrapper* status, ISC_QUAD* blob_id, IAttachment* att, ITransaction* tra,
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
int type, const char* field_name)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* e d i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Open a blob, dump it to a file, allow the user to edit the
|
|
|
|
* window, and dump the data back into a blob. If the user
|
|
|
|
* bails out, return FALSE, otherwise return TRUE.
|
|
|
|
*
|
|
|
|
* If the field name coming in is too big, truncate it.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
#if (defined WIN_NT)
|
|
|
|
TEXT buffer[9];
|
|
|
|
#else
|
|
|
|
TEXT buffer[25];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const TEXT* q = field_name;
|
|
|
|
if (!q)
|
|
|
|
q = "gds_edit";
|
|
|
|
|
|
|
|
TEXT* p;
|
|
|
|
for (p = buffer; *q && p < buffer + sizeof(buffer) - 1; q++)
|
|
|
|
{
|
|
|
|
if (*q == '$')
|
|
|
|
*p++ = '_';
|
|
|
|
else
|
|
|
|
*p++ = LOWER7(*q);
|
|
|
|
}
|
|
|
|
*p = 0;
|
|
|
|
|
|
|
|
// Moved this out of #ifndef mpexl to get mktemp/mkstemp to work for Linux
|
|
|
|
// This has been done in the inprise tree some days ago.
|
|
|
|
// Would have saved me a lot of time, if I had seen this earlier :-(
|
|
|
|
// FSG 15.Oct.2000
|
|
|
|
PathName tmpf = TempFile::create(status, buffer);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FALSE;
|
|
|
|
|
2014-12-17 15:31:02 +01:00
|
|
|
FILE* file = os_utils::fopen(tmpf.c_str(), FOPEN_WRITE_TYPE_TEXT);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
if (!file)
|
|
|
|
{
|
|
|
|
unlink(tmpf.c_str());
|
|
|
|
system_error::raise("fopen");
|
|
|
|
}
|
|
|
|
|
|
|
|
dump(status, blob_id, att, tra, file);
|
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2014-08-27 11:24:30 +02:00
|
|
|
isc_print_status(status->getErrors());
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
fclose(file);
|
|
|
|
unlink(tmpf.c_str());
|
|
|
|
return FB_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(file);
|
|
|
|
|
|
|
|
if (gds__edit(tmpf.c_str(), type))
|
|
|
|
{
|
|
|
|
|
2014-12-17 15:31:02 +01:00
|
|
|
if (!(file = os_utils::fopen(tmpf.c_str(), FOPEN_READ_TYPE_TEXT)))
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
|
|
|
unlink(tmpf.c_str());
|
|
|
|
system_error::raise("fopen");
|
|
|
|
}
|
|
|
|
|
|
|
|
load(status, blob_id, att, tra, file);
|
|
|
|
|
|
|
|
fclose(file);
|
2015-02-18 16:01:17 +01:00
|
|
|
return status->getState() & IStatus::STATE_ERRORS ? FB_FALSE : FB_TRUE;
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unlink(tmpf.c_str());
|
|
|
|
return FB_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
|
|
|
namespace Why {
|
|
|
|
|
2015-01-14 15:38:26 +01:00
|
|
|
UtilInterface utilInterface;
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
|
2015-01-14 15:21:22 +01:00
|
|
|
void UtilInterface::dumpBlob(CheckStatusWrapper* status, ISC_QUAD* blobId,
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
IAttachment* att, ITransaction* tra, const char* file_name, FB_BOOLEAN txt)
|
|
|
|
{
|
2014-12-17 15:31:02 +01:00
|
|
|
FILE* file = os_utils::fopen(file_name, txt ? FOPEN_WRITE_TYPE_TEXT : FOPEN_WRITE_TYPE);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (!file)
|
|
|
|
system_error::raise("fopen");
|
|
|
|
|
2014-06-17 14:45:14 +02:00
|
|
|
if (!att)
|
|
|
|
Arg::Gds(isc_bad_db_handle).raise();
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
dump(status, blobId, att, tra, file);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
2014-01-17 16:05:19 +01:00
|
|
|
|
|
|
|
if (file)
|
|
|
|
fclose(file);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
|
|
|
|
2015-01-14 15:21:22 +01:00
|
|
|
void UtilInterface::loadBlob(CheckStatusWrapper* status, ISC_QUAD* blobId,
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
IAttachment* att, ITransaction* tra, const char* file_name, FB_BOOLEAN txt)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* l o a d B l o b
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Load a blob with the contents of a file.
|
|
|
|
*
|
|
|
|
**************************************/
|
2014-12-17 15:31:02 +01:00
|
|
|
FILE* file = os_utils::fopen(file_name, txt ? FOPEN_READ_TYPE_TEXT : FOPEN_READ_TYPE);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (!file)
|
|
|
|
system_error::raise("fopen");
|
|
|
|
|
2014-06-17 14:45:14 +02:00
|
|
|
if (!att)
|
|
|
|
Arg::Gds(isc_bad_db_handle).raise();
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
load(status, blobId, att, tra, file);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
2014-01-17 16:05:19 +01:00
|
|
|
|
|
|
|
if (file)
|
|
|
|
fclose(file);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
|
|
|
|
2015-01-14 15:21:22 +01:00
|
|
|
void UtilInterface::getFbVersion(CheckStatusWrapper* status, IAttachment* att,
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
IVersionCallback* callback)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ v e r s i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Obtain and print information about a database.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
try
|
|
|
|
{
|
2014-06-17 14:45:14 +02:00
|
|
|
if (!att)
|
|
|
|
Arg::Gds(isc_bad_db_handle).raise();
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
UCharBuffer buffer;
|
|
|
|
USHORT buf_len = 256;
|
|
|
|
UCHAR* buf = buffer.getBuffer(buf_len);
|
|
|
|
|
|
|
|
const TEXT* versions = 0;
|
|
|
|
const TEXT* implementations = 0;
|
|
|
|
const UCHAR* dbis = NULL;
|
|
|
|
bool redo;
|
2014-01-17 16:05:19 +01:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
att->getInfo(status, sizeof(info), info, buf_len, buf);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
const UCHAR* p = buf;
|
|
|
|
redo = false;
|
|
|
|
|
|
|
|
while (!redo && *p != isc_info_end && p < buf + buf_len)
|
|
|
|
{
|
|
|
|
const UCHAR item = *p++;
|
|
|
|
const USHORT len = static_cast<USHORT>(gds__vax_integer(p, 2));
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
p += 2;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
switch (item)
|
|
|
|
{
|
|
|
|
case isc_info_firebird_version:
|
|
|
|
versions = (TEXT*) p;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_implementation:
|
|
|
|
implementations = (TEXT*) p;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case fb_info_implementation:
|
|
|
|
dbis = p;
|
|
|
|
if (dbis[0] * 6 + 1 > len)
|
|
|
|
{
|
|
|
|
// fb_info_implementation value appears incorrect
|
|
|
|
dbis = NULL;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_error:
|
|
|
|
// old server does not understand fb_info_implementation
|
|
|
|
break;
|
|
|
|
|
|
|
|
case isc_info_truncated:
|
|
|
|
redo = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
(Arg::Gds(isc_random) << "Invalid info item").raise();
|
|
|
|
}
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
p += len;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Our buffer wasn't large enough to hold all the information,
|
|
|
|
// make a larger one and try again.
|
|
|
|
if (redo)
|
|
|
|
{
|
|
|
|
buf_len += 1024;
|
|
|
|
buf = buffer.getBuffer(buf_len);
|
|
|
|
}
|
|
|
|
} while (redo);
|
|
|
|
|
|
|
|
UCHAR count = MIN(*versions, *implementations);
|
|
|
|
++versions;
|
|
|
|
++implementations;
|
|
|
|
|
|
|
|
UCHAR diCount = 0;
|
|
|
|
if (dbis)
|
|
|
|
diCount = *dbis++;
|
|
|
|
|
|
|
|
string s;
|
|
|
|
|
|
|
|
UCHAR diCurrent = 0;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
for (UCHAR level = 0; level < count; ++level)
|
|
|
|
{
|
|
|
|
const USHORT implementation_nr = *implementations++;
|
|
|
|
const USHORT impl_class_nr = *implementations++;
|
|
|
|
const int l = *versions++; // it was UCHAR
|
|
|
|
const TEXT* implementation_string;
|
|
|
|
string dbi_string;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
if (dbis && dbis[diCurrent * 6 + 5] == level)
|
|
|
|
{
|
|
|
|
dbi_string = DbImplementation::pick(&dbis[diCurrent * 6]).implementation();
|
|
|
|
implementation_string = dbi_string.c_str();
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
if (++diCurrent >= diCount)
|
|
|
|
dbis = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dbi_string = DbImplementation::fromBackwardCompatibleByte(implementation_nr).implementation();
|
|
|
|
implementation_string = dbi_string.nullStr();
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
if (!implementation_string)
|
|
|
|
implementation_string = "**unknown**";
|
|
|
|
}
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
const TEXT* class_string;
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
if (impl_class_nr >= FB_NELEM(impl_class) || !(class_string = impl_class[impl_class_nr]))
|
|
|
|
class_string = "**unknown**";
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
s.printf("%s (%s), version \"%.*s\"", implementation_string, class_string, l, versions);
|
|
|
|
|
2014-07-02 14:57:12 +02:00
|
|
|
callback->callback(status, s.c_str());
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
2014-07-02 14:57:12 +02:00
|
|
|
return;
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
versions += l;
|
|
|
|
}
|
|
|
|
|
|
|
|
USHORT ods_version, ods_minor_version;
|
|
|
|
get_ods_version(status, att, &ods_version, &ods_minor_version);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
s.printf("on disk structure version %d.%d", ods_version, ods_minor_version);
|
2014-07-02 14:57:12 +02:00
|
|
|
callback->callback(status, s.c_str());
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-14 15:21:22 +01:00
|
|
|
YAttachment* UtilInterface::executeCreateDatabase(
|
2015-01-12 01:21:38 +01:00
|
|
|
Firebird::CheckStatusWrapper* status, unsigned stmtLength, const char* creatDBstatement,
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
unsigned dialect, FB_BOOLEAN* stmtIsCreateDb)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
bool stmtEaten;
|
|
|
|
YAttachment* att = NULL;
|
|
|
|
|
|
|
|
if (stmtIsCreateDb)
|
|
|
|
*stmtIsCreateDb = FB_FALSE;
|
|
|
|
|
|
|
|
if (!PREPARSE_execute(status, &att, stmtLength, creatDBstatement, &stmtEaten, dialect))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (stmtIsCreateDb)
|
|
|
|
*stmtIsCreateDb = FB_TRUE;
|
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
LocalStatus tempStatus;
|
2015-01-12 01:21:38 +01:00
|
|
|
CheckStatusWrapper tempCheckStatusWrapper(&tempStatus);
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
ITransaction* crdbTrans = att->startTransaction(status, 0, NULL);
|
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2015-01-12 01:21:38 +01:00
|
|
|
att->dropDatabase(&tempCheckStatusWrapper);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool v3Error = false;
|
|
|
|
|
|
|
|
if (!stmtEaten)
|
|
|
|
{
|
|
|
|
att->execute(status, crdbTrans, stmtLength, creatDBstatement, dialect, NULL, NULL, NULL, NULL);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2015-01-12 01:21:38 +01:00
|
|
|
crdbTrans->rollback(&tempCheckStatusWrapper);
|
|
|
|
att->dropDatabase(&tempCheckStatusWrapper);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
crdbTrans->commit(status);
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2015-01-12 01:21:38 +01:00
|
|
|
crdbTrans->rollback(&tempCheckStatusWrapper);
|
|
|
|
att->dropDatabase(&tempCheckStatusWrapper);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return att;
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
2014-01-17 16:05:19 +01:00
|
|
|
return NULL;
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-15 15:55:27 +01:00
|
|
|
void UtilInterface::decodeDate(ISC_DATE date, unsigned* year, unsigned* month, unsigned* day)
|
|
|
|
{
|
|
|
|
tm times;
|
|
|
|
isc_decode_sql_date(&date, ×);
|
|
|
|
|
|
|
|
if (year)
|
|
|
|
*year = times.tm_year + 1900;
|
|
|
|
if (month)
|
|
|
|
*month = times.tm_mon + 1;
|
|
|
|
if (day)
|
|
|
|
*day = times.tm_mday;
|
|
|
|
}
|
|
|
|
|
|
|
|
void UtilInterface::decodeTime(ISC_TIME time,
|
|
|
|
unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions)
|
|
|
|
{
|
|
|
|
tm times;
|
|
|
|
isc_decode_sql_time(&time, ×);
|
|
|
|
|
|
|
|
if (hours)
|
|
|
|
*hours = times.tm_hour;
|
|
|
|
if (minutes)
|
|
|
|
*minutes = times.tm_min;
|
|
|
|
if (seconds)
|
|
|
|
*seconds = times.tm_sec;
|
|
|
|
if (fractions)
|
|
|
|
*fractions = time % ISC_TIME_SECONDS_PRECISION;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_DATE UtilInterface::encodeDate(unsigned year, unsigned month, unsigned day)
|
|
|
|
{
|
|
|
|
tm times;
|
|
|
|
times.tm_year = year - 1900;
|
|
|
|
times.tm_mon = month - 1;
|
|
|
|
times.tm_mday = day;
|
|
|
|
|
|
|
|
ISC_DATE date;
|
|
|
|
isc_encode_sql_date(×, &date);
|
|
|
|
|
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_TIME UtilInterface::encodeTime(unsigned hours, unsigned minutes, unsigned seconds,
|
|
|
|
unsigned fractions)
|
|
|
|
{
|
|
|
|
tm times;
|
|
|
|
times.tm_hour = hours;
|
|
|
|
times.tm_min = minutes;
|
|
|
|
times.tm_sec = seconds;
|
|
|
|
|
|
|
|
ISC_TIME time;
|
|
|
|
isc_encode_sql_time(×, &time);
|
|
|
|
time += fractions;
|
|
|
|
|
|
|
|
return time;
|
|
|
|
}
|
|
|
|
|
2015-03-18 03:03:25 +01:00
|
|
|
unsigned UtilInterface::formatStatus(char* buffer, unsigned bufferSize, IStatus* status)
|
|
|
|
{
|
|
|
|
unsigned state = status->getState();
|
|
|
|
unsigned states[] = {IStatus::STATE_ERRORS, IStatus::STATE_WARNINGS};
|
|
|
|
const ISC_STATUS* vectors[] = {status->getErrors(), status->getWarnings()};
|
|
|
|
string s;
|
|
|
|
|
|
|
|
for (int i = 0; i < 2; ++i)
|
|
|
|
{
|
|
|
|
if (state & states[i])
|
|
|
|
{
|
|
|
|
const ISC_STATUS* vector = vectors[i];
|
|
|
|
SLONG n;
|
|
|
|
|
|
|
|
while ((n = fb_interpret(buffer, bufferSize, &vector)) != 0)
|
|
|
|
{
|
|
|
|
if (!s.empty())
|
|
|
|
s += "\n-";
|
|
|
|
|
|
|
|
s += string(buffer, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned ret = MIN((unsigned) s.length(), bufferSize);
|
|
|
|
|
2015-11-05 17:06:06 +01:00
|
|
|
memcpy(buffer, s.c_str(), ret);
|
|
|
|
if (ret < bufferSize)
|
|
|
|
buffer[ret] = 0;
|
2015-03-18 03:03:25 +01:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-07-26 20:25:15 +02:00
|
|
|
unsigned UtilInterface::getClientVersion()
|
|
|
|
{
|
|
|
|
int fv[] = { FILE_VER_NUMBER };
|
|
|
|
return fv[0] * 0x100 + fv[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
// End-user proxy for ClumpletReader & Writer
|
|
|
|
class XpbBuilder FB_FINAL : public DisposeIface<IXpbBuilderImpl<XpbBuilder, CheckStatusWrapper> >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
XpbBuilder(unsigned kind, const unsigned char* buf, unsigned len)
|
|
|
|
: pb(NULL), strVal(getPool())
|
|
|
|
{
|
|
|
|
ClumpletReader::Kind k;
|
|
|
|
const ClumpletReader::KindList* kl = NULL;
|
|
|
|
|
|
|
|
switch(kind)
|
|
|
|
{
|
|
|
|
case DPB:
|
|
|
|
kl = ClumpletReader::dpbList;
|
|
|
|
break;
|
|
|
|
case SPB_ATTACH:
|
|
|
|
kl = ClumpletReader::spbList;
|
|
|
|
break;
|
|
|
|
case SPB_START:
|
|
|
|
k = ClumpletReader::SpbStart;
|
|
|
|
break;
|
|
|
|
case TPB:
|
|
|
|
k = ClumpletReader::Tpb;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fatal_exception::raiseFmt("Wrong parameters block kind %d, should be from %d to %d", kind, DPB, TPB);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!buf)
|
|
|
|
{
|
|
|
|
if (kl)
|
2015-10-12 16:26:00 +02:00
|
|
|
pb = FB_NEW_POOL(getPool()) ClumpletWriter(getPool(), kl, MAX_DPB_SIZE);
|
2015-07-26 20:25:15 +02:00
|
|
|
else
|
2015-10-12 16:26:00 +02:00
|
|
|
pb = FB_NEW_POOL(getPool()) ClumpletWriter(getPool(), k, MAX_DPB_SIZE);
|
2015-07-26 20:25:15 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (kl)
|
2015-10-12 16:26:00 +02:00
|
|
|
pb = FB_NEW_POOL(getPool()) ClumpletWriter(getPool(), kl, MAX_DPB_SIZE, buf, len);
|
2015-07-26 20:25:15 +02:00
|
|
|
else
|
2015-10-12 16:26:00 +02:00
|
|
|
pb = FB_NEW_POOL(getPool()) ClumpletWriter(getPool(), k, MAX_DPB_SIZE, buf, len);
|
2015-07-26 20:25:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~XpbBuilder()
|
|
|
|
{
|
|
|
|
delete pb;
|
|
|
|
}
|
|
|
|
|
|
|
|
// IXpbBuilder implementation
|
|
|
|
void clear(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->clear();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeCurrent(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->deleteClumplet();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insertInt(CheckStatusWrapper* status, unsigned char tag, int value)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->insertInt(tag, value);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insertBigInt(CheckStatusWrapper* status, unsigned char tag, ISC_INT64 value)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->insertBigInt(tag, value);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insertBytes(CheckStatusWrapper* status, unsigned char tag, const void* bytes, unsigned length)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->insertBytes(tag, bytes, length);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insertString(CheckStatusWrapper* status, unsigned char tag, const char* str)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->insertString(tag, str, strlen(str));
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void insertTag(CheckStatusWrapper* status, unsigned char tag)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->insertTag(tag);
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FB_BOOLEAN isEof(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->isEof() ? FB_TRUE : FB_FALSE;
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return FB_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveNext(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->moveNext();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void rewind(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->rewind();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FB_BOOLEAN findFirst(CheckStatusWrapper* status, unsigned char tag)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
nextTag = tag;
|
|
|
|
return pb->find(nextTag) ? FB_TRUE : FB_FALSE;
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return FB_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FB_BOOLEAN findNext(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->next(nextTag) ? FB_TRUE : FB_FALSE;
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return FB_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char getTag(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getClumpTag();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getLength(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getClumpLength();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int getInt(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getInt();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ISC_INT64 getBigInt(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getBigInt();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* getString(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pb->getString(strVal);
|
|
|
|
return strVal.c_str();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned char* getBytes(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getBytes();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getBufferLength(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getBufferLength();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned char* getBuffer(CheckStatusWrapper* status)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return pb->getBuffer();
|
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void dispose()
|
|
|
|
{
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-08-02 17:51:01 +02:00
|
|
|
ClumpletWriter* pb;
|
2015-07-26 20:25:15 +02:00
|
|
|
unsigned char nextTag;
|
|
|
|
string strVal;
|
|
|
|
};
|
|
|
|
|
|
|
|
IXpbBuilder* UtilInterface::getXpbBuilder(CheckStatusWrapper* status,
|
|
|
|
unsigned kind, const unsigned char* buf, unsigned len)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2015-10-12 16:26:00 +02:00
|
|
|
return FB_NEW XpbBuilder(kind, buf, len);
|
2015-07-26 20:25:15 +02:00
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
|
|
|
ex.stuffException(status);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
} // namespace Why
|
|
|
|
|
|
|
|
|
2008-04-18 08:00:48 +02:00
|
|
|
#if (defined SOLARIS ) || (defined __cplusplus)
|
2004-06-04 16:36:45 +02:00
|
|
|
extern "C" {
|
|
|
|
#endif
|
2009-08-19 16:12:04 +02:00
|
|
|
// Avoid C++ linkage API functions
|
2004-06-04 16:36:45 +02:00
|
|
|
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
int API_ROUTINE gds__blob_size(FB_API_HANDLE* b, SLONG* size, SLONG* seg_count, SLONG* max_seg)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2002-02-16 03:21:35 +01:00
|
|
|
* g d s _ $ b l o b _ s i z e
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Get the size, number of segments, and max
|
2009-06-07 11:49:58 +02:00
|
|
|
* segment length of a blob. Return TRUE
|
2001-05-23 15:26:42 +02:00
|
|
|
* if it happens to succeed.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2003-11-28 07:48:34 +01:00
|
|
|
SCHAR buffer[64];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
if (isc_blob_info(status_vector, b, sizeof(blob_items), blob_items, sizeof(buffer), buffer))
|
2003-11-28 07:48:34 +01:00
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_print_status(status_vector);
|
2001-05-23 15:26:42 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-04-05 11:13:10 +02:00
|
|
|
const UCHAR* p = reinterpret_cast<UCHAR*>(buffer);
|
|
|
|
UCHAR item;
|
|
|
|
while ((item = *p++) != isc_info_end)
|
|
|
|
{
|
|
|
|
const USHORT l = gds__vax_integer(p, 2);
|
2001-05-23 15:26:42 +02:00
|
|
|
p += 2;
|
2007-04-05 11:13:10 +02:00
|
|
|
const SLONG n = gds__vax_integer(p, l);
|
2001-05-23 15:26:42 +02:00
|
|
|
p += l;
|
2009-01-20 09:33:59 +01:00
|
|
|
switch (item)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_info_blob_max_segment:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (max_seg)
|
|
|
|
*max_seg = n;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_info_blob_num_segments:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (seg_count)
|
|
|
|
*seg_count = n;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_info_blob_total_length:
|
2001-05-23 15:26:42 +02:00
|
|
|
if (size)
|
|
|
|
*size = n;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// 17 May 2001 - isc_expand_dpb is DEPRECATED
|
2003-10-29 11:53:47 +01:00
|
|
|
void API_ROUTINE_VARARG isc_expand_dpb(SCHAR** dpb, SSHORT* dpb_size, ...)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s c _ e x p a n d _ d p b
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Extend a database parameter block dynamically
|
2002-02-16 03:21:35 +01:00
|
|
|
* to include runtime info. Generated
|
|
|
|
* by gpre to provide host variable support for
|
2001-05-23 15:26:42 +02:00
|
|
|
* READY statement options.
|
|
|
|
* This expects the list of variable args
|
|
|
|
* to be zero terminated.
|
|
|
|
*
|
|
|
|
* Note: dpb_size is signed short only for compatibility
|
|
|
|
* with other calls (isc_attach_database) that take a dpb length.
|
|
|
|
*
|
|
|
|
* TMN: Note: According to Ann Harrison:
|
|
|
|
* That routine should be deprecated. It doesn't do what it
|
|
|
|
* should, and does do things it shouldn't, and is harder to
|
|
|
|
* use than the natural alternative.
|
|
|
|
*
|
|
|
|
**************************************/
|
2009-06-09 02:56:58 +02:00
|
|
|
SSHORT length;
|
|
|
|
UCHAR* p = NULL;
|
2003-10-29 11:53:47 +01:00
|
|
|
const char* q;
|
2001-05-24 16:54:26 +02:00
|
|
|
va_list args;
|
2009-06-09 02:56:58 +02:00
|
|
|
USHORT type;
|
2003-10-29 11:53:47 +01:00
|
|
|
UCHAR* new_dpb;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// calculate length of database parameter block, setting initial length to include version
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
SSHORT new_dpb_length;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!*dpb || !(new_dpb_length = *dpb_size))
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
new_dpb_length = 1;
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(args, dpb_size);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
while (type = va_arg(args, int))
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
|
|
|
case isc_dpb_password:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_sql_role_name:
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_lc_messages:
|
|
|
|
case isc_dpb_lc_ctype:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_reserved:
|
2003-10-29 11:53:47 +01:00
|
|
|
q = va_arg(args, char*);
|
|
|
|
if (q)
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2014-07-17 20:48:46 +02:00
|
|
|
length = static_cast<SSHORT>(strlen(q));
|
2001-05-23 15:26:42 +02:00
|
|
|
new_dpb_length += 2 + length;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-08-28 15:16:03 +02:00
|
|
|
va_arg(args, int);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2004-09-25 12:28:09 +02:00
|
|
|
va_end(args);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
// if items have been added, allocate space
|
|
|
|
// for the new dpb and copy the old one over
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-05-24 16:54:26 +02:00
|
|
|
if (new_dpb_length > *dpb_size)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// Note: gds__free done by GPRE generated code
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
new_dpb = (UCHAR*) gds__alloc((SLONG)(sizeof(UCHAR) * new_dpb_length));
|
2009-06-08 14:14:58 +02:00
|
|
|
p = new_dpb;
|
2009-08-20 08:25:45 +02:00
|
|
|
// FREE: done by client process in GPRE generated code
|
2001-05-24 16:54:26 +02:00
|
|
|
if (!new_dpb)
|
2009-08-20 08:25:45 +02:00
|
|
|
{
|
|
|
|
// NOMEM: don't trash existing dpb
|
2001-05-23 15:26:42 +02:00
|
|
|
DEV_REPORT("isc_extend_dpb: out of memory");
|
2009-08-20 08:25:45 +02:00
|
|
|
return; // NOMEM: not really handled
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
q = *dpb;
|
|
|
|
for (length = *dpb_size; length; length--)
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
*p++ = *q++;
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
}
|
2001-05-24 16:54:26 +02:00
|
|
|
else
|
|
|
|
{
|
2008-06-13 13:28:34 +02:00
|
|
|
// CVC: Notice this case is new_dpb_length <= *dpb_size, but since
|
|
|
|
// we have new_dpb_length = MAX(*dpb_size, 1) our case is reduced
|
|
|
|
// to new_dpb_length == *dpb_size. Therefore, this code is a waste
|
|
|
|
// of time, since the function didn't find any param to add and thus,
|
2003-10-29 11:53:47 +01:00
|
|
|
// the loop below won't find anything worth adding either.
|
2008-06-13 13:28:34 +02:00
|
|
|
// Notice, too that the original input dpb is used, yet the pointer "p"
|
|
|
|
// is positioned exactly at the end, so if something was added at the
|
2003-10-29 11:53:47 +01:00
|
|
|
// tail, it would be a memory failure, unless the caller lies and is
|
|
|
|
// always passing a dpb bigger than *dpb_size.
|
|
|
|
new_dpb = reinterpret_cast<UCHAR*>(*dpb);
|
2009-06-08 14:14:58 +02:00
|
|
|
p = new_dpb + *dpb_size;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!*dpb_size)
|
2003-11-08 17:40:17 +01:00
|
|
|
*p++ = isc_dpb_version1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
// copy in the new runtime items
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(args, dpb_size);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
while (type = va_arg(args, int))
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
|
|
|
case isc_dpb_password:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_sql_role_name:
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_lc_messages:
|
|
|
|
case isc_dpb_lc_ctype:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_reserved:
|
2003-10-29 11:53:47 +01:00
|
|
|
q = va_arg(args, char*);
|
|
|
|
if (q)
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2014-07-17 20:48:46 +02:00
|
|
|
length = static_cast<SSHORT>(strlen(q));
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(type <= CHAR_MAX);
|
2009-06-08 14:14:58 +02:00
|
|
|
*p++ = (UCHAR) type;
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(length <= CHAR_MAX);
|
2009-06-08 14:14:58 +02:00
|
|
|
*p++ = (UCHAR) length;
|
2001-05-23 15:26:42 +02:00
|
|
|
while (length--)
|
|
|
|
*p++ = *q++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2003-08-28 15:16:03 +02:00
|
|
|
va_arg(args, int);
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2004-09-25 12:28:09 +02:00
|
|
|
va_end(args);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-06-08 14:14:58 +02:00
|
|
|
*dpb_size = p - new_dpb;
|
2003-10-29 11:53:47 +01:00
|
|
|
*dpb = reinterpret_cast<SCHAR*>(new_dpb);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-05-24 16:54:26 +02:00
|
|
|
int API_ROUTINE isc_modify_dpb(SCHAR** dpb,
|
|
|
|
SSHORT* dpb_size,
|
|
|
|
USHORT type,
|
2003-10-29 11:53:47 +01:00
|
|
|
const SCHAR* str,
|
2001-05-24 16:54:26 +02:00
|
|
|
SSHORT str_len)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2003-09-15 13:14:47 +02:00
|
|
|
* i s c _ m o d i f y _ d p b
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
2006-09-15 09:24:53 +02:00
|
|
|
* CVC: This is exactly the same logic as isc_expand_dpb, but for one param.
|
2003-10-29 11:53:47 +01:00
|
|
|
* However, the difference is that when presented with a dpb type it that's
|
|
|
|
* unknown, it returns FB_FAILURE immediately. In contrast, isc_expand_dpb
|
|
|
|
* doesn't complain and instead treats those as integers and tries to skip
|
|
|
|
* them, hoping to sync in the next iteration.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Extend a database parameter block dynamically
|
2002-02-16 03:21:35 +01:00
|
|
|
* to include runtime info. Generated
|
|
|
|
* by gpre to provide host variable support for
|
2001-05-23 15:26:42 +02:00
|
|
|
* READY statement options.
|
2002-02-16 03:21:35 +01:00
|
|
|
* This expects one arg at a time.
|
2001-05-23 15:26:42 +02:00
|
|
|
* the length of the string is passed by the caller and hence
|
|
|
|
* is not expected to be null terminated.
|
|
|
|
* this call is a variation of isc_expand_dpb without a variable
|
|
|
|
* arg parameters.
|
|
|
|
* Instead, this function is called recursively
|
|
|
|
* Alternatively, this can have a parameter list with all possible
|
|
|
|
* parameters either nulled or with proper value and type.
|
|
|
|
*
|
|
|
|
* **** This can be modified to be so at a later date, making sure
|
2002-02-16 03:21:35 +01:00
|
|
|
* **** all callers follow the same convention
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
* Note: dpb_size is signed short only for compatibility
|
|
|
|
* with other calls (isc_attach_database) that take a dpb length.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// calculate length of database parameter block, setting initial length to include version
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
SSHORT new_dpb_length;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!*dpb || !(new_dpb_length = *dpb_size))
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
new_dpb_length = 1;
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-05-24 16:54:26 +02:00
|
|
|
switch (type)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
|
|
|
case isc_dpb_password:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_sql_role_name:
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_lc_messages:
|
|
|
|
case isc_dpb_lc_ctype:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_reserved:
|
|
|
|
new_dpb_length += 2 + str_len;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
// if items have been added, allocate space
|
|
|
|
// for the new dpb and copy the old one over
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
UCHAR* new_dpb;
|
2001-05-24 16:54:26 +02:00
|
|
|
if (new_dpb_length > *dpb_size)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// Note: gds__free done by GPRE generated code
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
new_dpb = (UCHAR*) gds__alloc((SLONG)(sizeof(UCHAR) * new_dpb_length));
|
2001-05-24 16:54:26 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// FREE: done by client process in GPRE generated code
|
2001-05-24 16:54:26 +02:00
|
|
|
if (!new_dpb)
|
2009-08-20 08:25:45 +02:00
|
|
|
{
|
|
|
|
// NOMEM: don't trash existing dpb
|
2001-05-23 15:26:42 +02:00
|
|
|
DEV_REPORT("isc_extend_dpb: out of memory");
|
2009-08-20 08:25:45 +02:00
|
|
|
return FB_FAILURE; // NOMEM: not really handled
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2008-10-21 21:32:50 +02:00
|
|
|
memcpy(new_dpb, *dpb, *dpb_size);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2001-05-24 16:54:26 +02:00
|
|
|
else
|
2003-10-29 11:53:47 +01:00
|
|
|
new_dpb = reinterpret_cast<UCHAR*>(*dpb);
|
2008-03-10 09:31:35 +01:00
|
|
|
|
|
|
|
UCHAR* p = new_dpb + *dpb_size;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!*dpb_size)
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
*p++ = isc_dpb_version1;
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
// copy in the new runtime items
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-05-24 16:54:26 +02:00
|
|
|
switch (type)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
|
|
|
case isc_dpb_password:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_sql_role_name:
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_lc_messages:
|
|
|
|
case isc_dpb_lc_ctype:
|
2001-05-23 15:26:42 +02:00
|
|
|
case isc_dpb_reserved:
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2008-06-13 13:28:34 +02:00
|
|
|
const UCHAR* q = reinterpret_cast<const UCHAR*>(str);
|
2003-10-29 11:53:47 +01:00
|
|
|
if (q)
|
2001-05-24 16:54:26 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
SSHORT length = str_len;
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(type <= MAX_UCHAR);
|
2003-10-29 11:53:47 +01:00
|
|
|
*p++ = (UCHAR) type;
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(length <= MAX_UCHAR);
|
2003-10-29 11:53:47 +01:00
|
|
|
*p++ = (UCHAR) length;
|
|
|
|
while (length--)
|
|
|
|
{
|
|
|
|
*p++ = *q++;
|
|
|
|
}
|
2001-05-24 16:54:26 +02:00
|
|
|
}
|
2003-10-29 11:53:47 +01:00
|
|
|
break;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
*dpb_size = p - new_dpb;
|
2009-08-20 08:25:45 +02:00
|
|
|
*dpb = (SCHAR*) new_dpb;
|
2001-05-24 16:54:26 +02:00
|
|
|
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_SUCCESS;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-07 09:57:46 +02:00
|
|
|
#if defined(UNIX) || defined(WIN_NT)
|
2009-04-26 12:24:44 +02:00
|
|
|
int API_ROUTINE gds__edit(const TEXT* file_name, USHORT /*type*/)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ e d i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Edit a file.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
string editor;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
#ifndef WIN_NT
|
2006-01-14 05:48:59 +01:00
|
|
|
if (!fb_utils::readenv("VISUAL", editor) && !fb_utils::readenv("EDITOR", editor))
|
2001-05-23 15:26:42 +02:00
|
|
|
editor = "vi";
|
|
|
|
#else
|
2006-01-14 05:48:59 +01:00
|
|
|
if (!fb_utils::readenv("EDITOR", editor))
|
2001-05-24 16:54:26 +02:00
|
|
|
editor = "Notepad";
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
struct stat before;
|
2004-05-07 09:57:46 +02:00
|
|
|
stat(file_name, &before);
|
2004-12-23 07:28:41 +01:00
|
|
|
// The path of the editor + the path of the file + quotes + one space.
|
|
|
|
// We aren't using quotes around the editor for now.
|
|
|
|
TEXT buffer[MAXPATHLEN * 2 + 5];
|
2006-01-14 05:48:59 +01:00
|
|
|
fb_utils::snprintf(buffer, sizeof(buffer), "%s \"%s\"", editor.c_str(), file_name);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2013-11-19 14:19:11 +01:00
|
|
|
FB_UNUSED(system(buffer));
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
struct stat after;
|
2004-05-07 09:57:46 +02:00
|
|
|
stat(file_name, &after);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
return (before.st_mtime != after.st_mtime || before.st_size != after.st_size);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
SLONG API_ROUTINE gds__event_block(UCHAR** event_buffer, UCHAR** result_buffer, USHORT count, ...)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2003-11-16 02:44:51 +01:00
|
|
|
* g d s _ $ e v e n t _ b l o c k
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-11-16 02:44:51 +01:00
|
|
|
* Create an initialized event parameter block from a
|
|
|
|
* variable number of input arguments.
|
|
|
|
* Return the size of the block.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
2003-11-16 02:44:51 +01:00
|
|
|
* Return 0 as the size if the event parameter block cannot be
|
|
|
|
* created for any reason.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2009-08-20 08:25:45 +02:00
|
|
|
UCHAR* p;
|
|
|
|
SCHAR* q;
|
2001-05-23 15:26:42 +02:00
|
|
|
SLONG length;
|
2003-11-11 13:19:20 +01:00
|
|
|
va_list ptr;
|
2003-11-16 02:44:51 +01:00
|
|
|
USHORT i;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(ptr, count);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
// calculate length of event parameter block,
|
|
|
|
// setting initial length to include version
|
|
|
|
// and counts for each argument
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
length = 1;
|
2003-09-13 01:37:06 +02:00
|
|
|
i = count;
|
2009-08-19 16:12:04 +02:00
|
|
|
while (i--)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
q = va_arg(ptr, SCHAR*);
|
2014-07-17 20:48:46 +02:00
|
|
|
length += static_cast<SLONG>(strlen(q)) + 5;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
p = *event_buffer = (UCHAR*) gds__alloc((SLONG) (sizeof(UCHAR) * length));
|
|
|
|
// FREE: unknown
|
|
|
|
if (!*event_buffer) // NOMEM:
|
2001-05-23 15:26:42 +02:00
|
|
|
return 0;
|
2009-08-20 08:25:45 +02:00
|
|
|
*result_buffer = (UCHAR*) gds__alloc((SLONG) (sizeof(UCHAR) * length));
|
|
|
|
// FREE: unknown
|
2009-08-19 16:12:04 +02:00
|
|
|
if (!*result_buffer)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// NOMEM:
|
2001-05-23 15:26:42 +02:00
|
|
|
gds__free(*event_buffer);
|
|
|
|
*event_buffer = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_GDS_ALLOC
|
2009-08-20 08:25:45 +02:00
|
|
|
// I can't find anywhere these items are freed
|
|
|
|
// 1994-October-25 David Schnepper
|
|
|
|
gds_alloc_flag_unfreed((void*) *event_buffer);
|
|
|
|
gds_alloc_flag_unfreed((void*) *result_buffer);
|
|
|
|
#endif // DEBUG_GDS_ALLOC
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// initialize the block with event names and counts
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-03-11 11:34:43 +01:00
|
|
|
*p++ = EPB_version1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-24 01:28:06 +02:00
|
|
|
va_start(ptr, count);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-13 01:37:06 +02:00
|
|
|
i = count;
|
2009-08-19 16:12:04 +02:00
|
|
|
while (i--)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
q = va_arg(ptr, SCHAR*);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Strip trailing blanks from string
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
const SCHAR* end = q + strlen(q);
|
|
|
|
while (--end >= q && *end == ' ')
|
|
|
|
; // empty loop
|
2001-05-23 15:26:42 +02:00
|
|
|
*p++ = end - q + 1;
|
|
|
|
while (q <= end)
|
|
|
|
*p++ = *q++;
|
|
|
|
*p++ = 0;
|
|
|
|
*p++ = 0;
|
|
|
|
*p++ = 0;
|
|
|
|
*p++ = 0;
|
|
|
|
}
|
|
|
|
|
2003-11-16 02:44:51 +01:00
|
|
|
return p - *event_buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
USHORT API_ROUTINE gds__event_block_a(SCHAR** event_buffer,
|
|
|
|
SCHAR** result_buffer,
|
2003-11-16 02:44:51 +01:00
|
|
|
SSHORT count,
|
2009-08-19 16:12:04 +02:00
|
|
|
SCHAR** name_buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2008-04-18 08:00:48 +02:00
|
|
|
* g d s _ $ e v e n t _ b l o c k _ a
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Create an initialized event parameter block from a
|
|
|
|
* vector of input arguments. (Ada needs this)
|
|
|
|
* Assume all strings are 31 characters long.
|
|
|
|
* Return the size of the block.
|
|
|
|
*
|
|
|
|
**************************************/
|
2009-05-02 16:56:43 +02:00
|
|
|
const int MAX_NAME_LENGTH = 31;
|
2008-06-13 13:28:34 +02:00
|
|
|
// calculate length of event parameter block,
|
|
|
|
// setting initial length to include version
|
|
|
|
// and counts for each argument
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
USHORT i = count;
|
2004-12-23 07:28:41 +01:00
|
|
|
const SCHAR* const* nb = name_buffer;
|
2003-11-28 07:48:34 +01:00
|
|
|
SLONG length = 0;
|
2009-08-19 16:12:04 +02:00
|
|
|
while (i--)
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
const SCHAR* q = *nb++;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Strip trailing blanks from string
|
2009-05-02 16:56:43 +02:00
|
|
|
const SCHAR* end = q + MAX_NAME_LENGTH;
|
2003-11-28 07:48:34 +01:00
|
|
|
while (--end >= q && *end == ' '); // null body
|
2001-05-23 15:26:42 +02:00
|
|
|
length += end - q + 1 + 5;
|
|
|
|
}
|
|
|
|
|
2003-09-13 01:37:06 +02:00
|
|
|
i = count;
|
2009-08-20 08:25:45 +02:00
|
|
|
SCHAR* p = *event_buffer = (SCHAR*) gds__alloc((SLONG) (sizeof(SCHAR) * length));
|
|
|
|
// FREE: unknown
|
|
|
|
if (!*event_buffer) // NOMEM:
|
2001-05-23 15:26:42 +02:00
|
|
|
return 0;
|
2009-08-20 08:25:45 +02:00
|
|
|
*result_buffer = (SCHAR*) gds__alloc((SLONG) (sizeof(SCHAR) * length));
|
|
|
|
// FREE: unknown
|
2009-08-19 16:12:04 +02:00
|
|
|
if (!*result_buffer)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// NOMEM:
|
2001-05-23 15:26:42 +02:00
|
|
|
gds__free(*event_buffer);
|
|
|
|
*event_buffer = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_GDS_ALLOC
|
2009-08-20 08:25:45 +02:00
|
|
|
// I can't find anywhere these items are freed
|
|
|
|
// 1994-October-25 David Schnepper
|
|
|
|
gds_alloc_flag_unfreed((void*) *event_buffer);
|
|
|
|
gds_alloc_flag_unfreed((void*) *result_buffer);
|
|
|
|
#endif // DEBUG_GDS_ALLOC
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-03-11 11:34:43 +01:00
|
|
|
*p++ = EPB_version1;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
nb = name_buffer;
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
while (i--)
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
const SCHAR* q = *nb++;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Strip trailing blanks from string
|
2009-05-02 16:56:43 +02:00
|
|
|
const SCHAR* end = q + MAX_NAME_LENGTH;
|
2008-12-25 07:09:37 +01:00
|
|
|
while (--end >= q && *end == ' ')
|
|
|
|
; // null body
|
2001-05-23 15:26:42 +02:00
|
|
|
*p++ = end - q + 1;
|
|
|
|
while (q <= end)
|
|
|
|
*p++ = *q++;
|
|
|
|
*p++ = 0;
|
|
|
|
*p++ = 0;
|
|
|
|
*p++ = 0;
|
|
|
|
*p++ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (p - *event_buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
void API_ROUTINE gds__event_block_s(SCHAR** event_buffer,
|
|
|
|
SCHAR** result_buffer,
|
2003-11-16 02:44:51 +01:00
|
|
|
SSHORT count,
|
2009-08-19 16:12:04 +02:00
|
|
|
SCHAR** name_buffer,
|
|
|
|
SSHORT* return_count)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
2003-11-16 02:44:51 +01:00
|
|
|
* g d s _ $ e v e n t _ b l o c k _ s
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* THIS IS THE COBOL VERSION of gds__event_block_a for Cobols
|
|
|
|
* that don't permit return values.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
*return_count = gds__event_block_a(event_buffer, result_buffer, count, name_buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
void API_ROUTINE isc_event_counts(ULONG* result_vector,
|
|
|
|
SSHORT buffer_length,
|
|
|
|
UCHAR* event_buffer,
|
|
|
|
const UCHAR* result_buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ e v e n t _ c o u n t s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Get the delta between two events in an event
|
|
|
|
* parameter block. Used to update gds_events
|
|
|
|
* for GPRE support of events.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-28 07:48:34 +01:00
|
|
|
ULONG* vec = result_vector;
|
2006-03-10 09:23:40 +01:00
|
|
|
const UCHAR* p = event_buffer;
|
2004-08-04 08:27:54 +02:00
|
|
|
const UCHAR* q = result_buffer;
|
2003-11-28 07:48:34 +01:00
|
|
|
USHORT length = buffer_length;
|
2006-02-23 06:08:26 +01:00
|
|
|
const UCHAR* const end = p + length;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-06-13 13:28:34 +02:00
|
|
|
// analyze the event blocks, getting the delta for each event
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
p++;
|
|
|
|
q++;
|
2009-08-19 16:12:04 +02:00
|
|
|
while (p < end)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// skip over the event name
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
const USHORT i = (USHORT)* p++;
|
2001-05-23 15:26:42 +02:00
|
|
|
p += i;
|
|
|
|
q += i + 1;
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// get the change in count
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-02-23 06:08:26 +01:00
|
|
|
const ULONG initial_count = gds__vax_integer(p, sizeof(SLONG));
|
2001-05-23 15:26:42 +02:00
|
|
|
p += sizeof(SLONG);
|
2006-02-23 06:08:26 +01:00
|
|
|
const ULONG new_count = gds__vax_integer(q, sizeof(SLONG));
|
2001-05-23 15:26:42 +02:00
|
|
|
q += sizeof(SLONG);
|
|
|
|
*vec++ = new_count - initial_count;
|
|
|
|
}
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// copy over the result to the initial block to prepare
|
|
|
|
// for the next call to gds__event_wait
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2006-02-23 06:08:26 +01:00
|
|
|
memcpy(event_buffer, result_buffer, length);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
void API_ROUTINE isc_get_client_version(SCHAR* buffer)
|
2003-01-19 15:30:53 +01:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ g e t _ c l i e n t _ v e r s i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
if (buffer)
|
2007-01-26 23:17:30 +01:00
|
|
|
strcpy(buffer, ISC_VERSION);
|
2003-01-19 15:30:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-09 16:38:31 +01:00
|
|
|
int API_ROUTINE isc_get_client_major_version()
|
2003-01-19 15:30:53 +01:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ g e t _ c l i e n t _ m a j o r _ v e r s i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2007-01-26 23:17:30 +01:00
|
|
|
return atoi(ISC_MAJOR_VER);
|
2003-01-19 15:30:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-09 16:38:31 +01:00
|
|
|
int API_ROUTINE isc_get_client_minor_version()
|
2003-01-19 15:30:53 +01:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ g e t _ c l i e n t _ m i n o r _ v e r s i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2007-01-26 23:17:30 +01:00
|
|
|
return atoi(ISC_MINOR_VER);
|
2003-01-19 15:30:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-26 12:24:44 +02:00
|
|
|
void API_ROUTINE gds__map_blobs(int* /*handle1*/, int* /*handle2*/)
|
2008-03-08 19:48:37 +01:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ m a p _ b l o b s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Deprecated API function.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-26 12:24:44 +02:00
|
|
|
void API_ROUTINE isc_set_debug(int /*value*/)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* G D S _ S E T _ D E B U G
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2014-07-17 20:48:46 +02:00
|
|
|
* Deprecated API function.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
void API_ROUTINE isc_set_login(const UCHAR** dpb, SSHORT* dpb_size)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s c _ s e t _ l o g i n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Pickup any ISC_USER and ISC_PASSWORD
|
|
|
|
* environment variables, and stuff them
|
|
|
|
* into the dpb (if there is no user name
|
|
|
|
* or password already referenced).
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// look for the environment variables
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
string username, password;
|
2008-05-19 15:58:37 +02:00
|
|
|
if (!fb_utils::readenv(ISC_USER, username) && !fb_utils::readenv(ISC_PASSWORD, password))
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// figure out whether the username or password have already been specified
|
2008-04-18 08:00:48 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
bool user_seen = false, password_seen = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
if (*dpb && *dpb_size)
|
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const UCHAR* p = *dpb;
|
2008-01-16 11:17:51 +01:00
|
|
|
for (const UCHAR* const end_dpb = p + *dpb_size; p < end_dpb;)
|
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const int item = *p++;
|
2008-01-16 11:17:51 +01:00
|
|
|
switch (item)
|
|
|
|
{
|
|
|
|
case isc_dpb_version1:
|
2001-05-23 15:26:42 +02:00
|
|
|
continue;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
2003-10-29 11:53:47 +01:00
|
|
|
user_seen = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_password:
|
|
|
|
case isc_dpb_password_enc:
|
2003-10-29 11:53:47 +01:00
|
|
|
password_seen = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// get the length and increment past the parameter.
|
2003-10-29 11:53:47 +01:00
|
|
|
const USHORT l = *p++;
|
2001-05-23 15:26:42 +02:00
|
|
|
p += l;
|
|
|
|
}
|
2003-10-29 11:53:47 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-04-18 08:00:48 +02:00
|
|
|
if (username.length() && !user_seen)
|
2006-01-14 05:48:59 +01:00
|
|
|
{
|
|
|
|
if (password.length() && !password_seen)
|
2009-01-20 09:33:59 +01:00
|
|
|
isc_expand_dpb_internal(dpb, dpb_size, isc_dpb_user_name, username.c_str(),
|
2008-12-25 07:09:37 +01:00
|
|
|
isc_dpb_password, password.c_str(), 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
2008-12-25 07:09:37 +01:00
|
|
|
isc_expand_dpb_internal(dpb, dpb_size, isc_dpb_user_name, username.c_str(), 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2006-01-14 05:48:59 +01:00
|
|
|
else if (password.length() && !password_seen)
|
2008-12-25 07:09:37 +01:00
|
|
|
isc_expand_dpb_internal(dpb, dpb_size, isc_dpb_password, password.c_str(), 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
void API_ROUTINE isc_set_single_user(const UCHAR** dpb, SSHORT* dpb_size, const TEXT* single_user)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/****************************************
|
|
|
|
*
|
|
|
|
* i s c _ s e t _ s i n g l e _ u s e r
|
|
|
|
*
|
|
|
|
****************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Stuff the single_user flag into the dpb
|
|
|
|
* if the flag doesn't already exist in the dpb.
|
|
|
|
*
|
|
|
|
****************************************/
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Discover if single user access has already been specified
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
bool single_user_seen = false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-20 03:32:24 +02:00
|
|
|
if (*dpb && *dpb_size)
|
2009-08-19 16:12:04 +02:00
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const UCHAR* p = *dpb;
|
2008-01-16 11:17:51 +01:00
|
|
|
for (const UCHAR* const end_dpb = p + *dpb_size; p < end_dpb;)
|
|
|
|
{
|
2003-10-29 11:53:47 +01:00
|
|
|
const int item = *p++;
|
2008-01-16 11:17:51 +01:00
|
|
|
switch (item)
|
|
|
|
{
|
|
|
|
case isc_dpb_version1:
|
2001-05-23 15:26:42 +02:00
|
|
|
continue;
|
|
|
|
case isc_dpb_reserved:
|
2003-10-29 11:53:47 +01:00
|
|
|
single_user_seen = true;
|
2001-05-23 15:26:42 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// Get the length and increment past the parameter.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
const USHORT l = *p++;
|
2001-05-23 15:26:42 +02:00
|
|
|
p += l;
|
|
|
|
|
|
|
|
}
|
2003-10-29 11:53:47 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!single_user_seen)
|
2008-12-25 07:09:37 +01:00
|
|
|
isc_expand_dpb_internal(dpb, dpb_size, isc_dpb_reserved, single_user, 0);
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
|
2009-04-26 12:24:44 +02:00
|
|
|
static void print_version(void*, const char* version)
|
2004-01-28 08:50:41 +01:00
|
|
|
{
|
2004-04-29 00:43:34 +02:00
|
|
|
printf("\t%s\n", version);
|
2004-01-21 08:18:30 +01:00
|
|
|
}
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
int API_ROUTINE isc_version(FB_API_HANDLE* handle, FPTR_VERSION_CALLBACK routine, void* user_arg)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ $ v e r s i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Obtain and print information about a database.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-01-21 08:18:30 +01:00
|
|
|
if (!routine)
|
|
|
|
routine = print_version;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-03-20 19:02:30 +01:00
|
|
|
LocalStatus ls;
|
|
|
|
CheckStatusWrapper st(&ls);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
RefPtr<IAttachment> att(REF_NO_INCR, handleToIAttachment(&st, handle));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & IStatus::STATE_ERRORS)
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
VersionCallback callback(routine, user_arg);
|
2015-01-14 15:21:22 +01:00
|
|
|
UtilInterfacePtr()->getFbVersion(&st, att, &callback);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
return st.getState() & IStatus::STATE_ERRORS ? FB_FAILURE : FB_SUCCESS;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-15 15:04:06 +01:00
|
|
|
void API_ROUTINE isc_format_implementation(USHORT impl_nr,
|
2008-12-25 07:09:37 +01:00
|
|
|
USHORT ibuflen, TEXT* ibuf,
|
2009-01-20 09:33:59 +01:00
|
|
|
USHORT impl_class_nr,
|
2008-12-25 07:09:37 +01:00
|
|
|
USHORT cbuflen, TEXT* cbuf)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s c _ f o r m a t _ i m p l e m e n t a t i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Convert the implementation and class codes to strings
|
|
|
|
* by looking up their values in the internal tables.
|
|
|
|
*
|
|
|
|
**************************************/
|
2009-08-19 16:12:04 +02:00
|
|
|
if (ibuflen > 0)
|
|
|
|
{
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
string imp =
|
|
|
|
DbImplementation::fromBackwardCompatibleByte(impl_nr).implementation();
|
2009-11-13 19:29:06 +01:00
|
|
|
imp.copyTo(ibuf, ibuflen);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
if (cbuflen > 0)
|
|
|
|
{
|
2004-02-02 12:02:12 +01:00
|
|
|
if (impl_class_nr >= FB_NELEM(impl_class) || !(impl_class[impl_class_nr]))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
strncpy(cbuf, "**unknown**", cbuflen - 1);
|
2004-12-23 07:42:33 +01:00
|
|
|
cbuf[MIN(11, cbuflen - 1)] = '\0';
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-08-19 16:12:04 +02:00
|
|
|
else
|
|
|
|
{
|
2004-02-02 12:02:12 +01:00
|
|
|
strncpy(cbuf, impl_class[impl_class_nr], cbuflen - 1);
|
2014-07-17 20:48:46 +02:00
|
|
|
const int len = static_cast<int>(strlen(impl_class[impl_class_nr]));
|
2004-12-23 07:42:33 +01:00
|
|
|
cbuf[MIN(len, cbuflen - 1)] = '\0';
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-18 20:33:25 +01:00
|
|
|
uintptr_t API_ROUTINE isc_baddress(SCHAR* object)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s c _ b a d d r e s s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Return the address of whatever is passed in
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2006-11-18 20:33:25 +01:00
|
|
|
return (uintptr_t) object;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-18 20:33:25 +01:00
|
|
|
void API_ROUTINE isc_baddress_s(const SCHAR* object, uintptr_t* address)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s c _ b a d d r e s s _ s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-11-28 07:48:34 +01:00
|
|
|
* Copy the address of whatever is passed in to the 2nd param.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2006-11-18 20:33:25 +01:00
|
|
|
*address = (uintptr_t) object;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
int API_ROUTINE BLOB_close(FB_BLOB_STREAM blobStream)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ c l o s e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Close a blob stream.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
if (!blobStream->bstr_blob)
|
2001-05-23 15:26:42 +02:00
|
|
|
return FALSE;
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
if (blobStream->bstr_mode & BSTR_output)
|
2009-08-19 16:12:04 +02:00
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
const USHORT l = (blobStream->bstr_ptr - blobStream->bstr_buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (l > 0)
|
2008-01-16 11:17:51 +01:00
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
if (isc_put_segment(status_vector, &blobStream->bstr_blob, l, blobStream->bstr_buffer))
|
2003-09-15 13:14:47 +02:00
|
|
|
{
|
2003-09-13 01:37:06 +02:00
|
|
|
return FALSE;
|
2003-09-15 13:14:47 +02:00
|
|
|
}
|
2008-01-16 11:17:51 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
isc_close_blob(status_vector, &blobStream->bstr_blob);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
if (blobStream->bstr_mode & BSTR_alloc)
|
|
|
|
gds__free(blobStream->bstr_buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
gds__free(blobStream);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
int API_ROUTINE blob__display(SLONG blob_id[2],
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE* database,
|
|
|
|
FB_API_HANDLE* transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const TEXT* field_name, const SSHORT* name_length)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* b l o b _ $ d i s p l a y
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* PASCAL callable version of EDIT_blob.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
const MetaName temp(field_name, *name_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
return BLOB_display(reinterpret_cast<ISC_QUAD*>(blob_id), *database, *transaction, temp.c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
int API_ROUTINE BLOB_display(ISC_QUAD* blob_id,
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE database,
|
2008-04-18 08:00:48 +02:00
|
|
|
FB_API_HANDLE transaction,
|
2009-04-26 12:24:44 +02:00
|
|
|
const TEXT* /*field_name*/)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ d i s p l a y
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
* Open a blob, dump it to stdout
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
LocalStatus st;
|
2015-01-12 01:21:38 +01:00
|
|
|
CheckStatusWrapper statusWrapper(&st);
|
|
|
|
|
|
|
|
RefPtr<IAttachment> att(REF_NO_INCR, handleToIAttachment(&statusWrapper, &database));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
2015-01-12 01:21:38 +01:00
|
|
|
RefPtr<ITransaction> tra(REF_NO_INCR, handleToITransaction(&statusWrapper, &transaction));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2015-01-12 01:21:38 +01:00
|
|
|
dump(&statusWrapper, blob_id, att, tra, stdout);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
2015-03-27 18:51:19 +01:00
|
|
|
ex.stuffException(&statusWrapper);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-03-27 18:51:19 +01:00
|
|
|
if (statusWrapper.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2015-03-27 18:51:19 +01:00
|
|
|
isc_print_status(statusWrapper.getErrors());
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
}
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_SUCCESS;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
int API_ROUTINE blob__dump(SLONG blob_id[2],
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE* database,
|
|
|
|
FB_API_HANDLE* transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const TEXT* file_name, const SSHORT* name_length)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* b l o b _ $ d u m p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Translate a pascal callable dump
|
|
|
|
* into an internal dump call.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-28 07:48:34 +01:00
|
|
|
// CVC: The old logic passed garbage to BLOB_dump if !*name_length
|
|
|
|
TEXT temp[129];
|
|
|
|
USHORT l = *name_length;
|
2009-08-19 16:12:04 +02:00
|
|
|
if (l != 0)
|
|
|
|
{
|
2008-04-18 08:00:48 +02:00
|
|
|
if (l >= sizeof(temp))
|
2004-03-28 11:10:30 +02:00
|
|
|
l = sizeof(temp) - 1;
|
2008-04-18 08:00:48 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
memcpy(temp, file_name, l);
|
|
|
|
}
|
|
|
|
temp[l] = 0;
|
|
|
|
|
|
|
|
return BLOB_dump(reinterpret_cast<ISC_QUAD*>(blob_id), *database, *transaction, temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int any_text_dump(ISC_QUAD* blob_id,
|
|
|
|
FB_API_HANDLE database,
|
|
|
|
FB_API_HANDLE transaction,
|
|
|
|
const SCHAR* file_name,
|
|
|
|
FB_BOOLEAN txt)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a n y _ t e x t _ d u m p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Dump a blob into a file.
|
|
|
|
*
|
|
|
|
**************************************/
|
2015-03-20 19:02:30 +01:00
|
|
|
LocalStatus ls;
|
|
|
|
CheckStatusWrapper st(&ls);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
RefPtr<IAttachment> att(REF_NO_INCR, handleToIAttachment(&st, &database));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
RefPtr<ITransaction> tra(REF_NO_INCR, handleToITransaction(&st, &transaction));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
|
2015-01-14 15:21:22 +01:00
|
|
|
UtilInterfacePtr()->dumpBlob(&st, blob_id, att, tra, file_name, txt);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2014-08-27 11:24:30 +02:00
|
|
|
isc_print_status(st.getErrors());
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
}
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_SUCCESS;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
int API_ROUTINE BLOB_text_dump(ISC_QUAD* blob_id,
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE database,
|
2008-04-18 08:00:48 +02:00
|
|
|
FB_API_HANDLE transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const SCHAR* file_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ t e x t _ d u m p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Dump a blob into a file.
|
|
|
|
* This call does CR/LF translation on NT.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return any_text_dump(blob_id, database, transaction, file_name, FB_TRUE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
int API_ROUTINE BLOB_dump(ISC_QUAD* blob_id,
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE database,
|
2008-04-18 08:00:48 +02:00
|
|
|
FB_API_HANDLE transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const SCHAR* file_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ d u m p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Dump a blob into a file.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return any_text_dump(blob_id, database, transaction, file_name, FB_FALSE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
int API_ROUTINE blob__edit(SLONG blob_id[2],
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE* database,
|
|
|
|
FB_API_HANDLE* transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const TEXT* field_name, const SSHORT* name_length)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* b l o b _ $ e d i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Translate a pascal callable edit
|
|
|
|
* into an internal edit call.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
const MetaName temp(field_name, *name_length);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
return BLOB_edit(reinterpret_cast<ISC_QUAD*>(blob_id), *database, *transaction, temp.c_str());
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
int API_ROUTINE BLOB_edit(ISC_QUAD* blob_id,
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE database,
|
2008-04-18 08:00:48 +02:00
|
|
|
FB_API_HANDLE transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const SCHAR* field_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ e d i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Open a blob, dump it to a file, allow the user to edit the
|
|
|
|
* window, and dump the data back into a blob. If the user
|
|
|
|
* bails out, return FALSE, otherwise return TRUE.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
LocalStatus st;
|
2015-01-12 01:21:38 +01:00
|
|
|
CheckStatusWrapper statusWrapper(&st);
|
|
|
|
|
|
|
|
RefPtr<IAttachment> att(REF_NO_INCR, handleToIAttachment(&statusWrapper, &database));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
2015-01-12 01:21:38 +01:00
|
|
|
RefPtr<ITransaction> tra(REF_NO_INCR, handleToITransaction(&statusWrapper, &transaction));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
|
2014-01-20 15:36:08 +01:00
|
|
|
int rc = FB_SUCCESS;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2015-01-12 01:21:38 +01:00
|
|
|
rc = edit(&statusWrapper, blob_id, att, tra, TRUE, field_name) ? FB_SUCCESS : FB_FAILURE;
|
2014-01-20 15:36:08 +01:00
|
|
|
}
|
|
|
|
catch (const Exception& ex)
|
|
|
|
{
|
2015-03-27 18:51:19 +01:00
|
|
|
ex.stuffException(&statusWrapper);
|
2014-01-20 15:36:08 +01:00
|
|
|
}
|
|
|
|
|
2015-03-27 18:51:19 +01:00
|
|
|
if (statusWrapper.getState() & Firebird::IStatus::STATE_ERRORS)
|
|
|
|
isc_print_status(statusWrapper.getErrors());
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
|
|
|
|
return rc;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
int API_ROUTINE BLOB_get(FB_BLOB_STREAM blobStream)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ g e t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Return the next byte of a blob. If the blob is exhausted, return
|
|
|
|
* EOF.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
if (!blobStream->bstr_buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
return EOF;
|
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
while (true)
|
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
if (--blobStream->bstr_cnt >= 0)
|
|
|
|
return *blobStream->bstr_ptr++ & 0377;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
isc_get_segment(status_vector, &blobStream->bstr_blob,
|
2007-10-06 21:08:50 +02:00
|
|
|
// safe - cast from short, alignment is OK
|
2012-03-23 15:06:14 +01:00
|
|
|
reinterpret_cast<USHORT*>(&blobStream->bstr_cnt),
|
|
|
|
blobStream->bstr_length, blobStream->bstr_buffer);
|
2009-08-19 16:12:04 +02:00
|
|
|
if (status_vector[1] && status_vector[1] != isc_segment)
|
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_ptr = 0;
|
|
|
|
blobStream->bstr_cnt = 0;
|
2003-11-08 17:40:17 +01:00
|
|
|
if (status_vector[1] != isc_segstr_eof)
|
|
|
|
isc_print_status(status_vector);
|
2001-05-23 15:26:42 +02:00
|
|
|
return EOF;
|
|
|
|
}
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_ptr = blobStream->bstr_buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
int API_ROUTINE blob__load(SLONG blob_id[2],
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE* database,
|
|
|
|
FB_API_HANDLE* transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const TEXT* file_name, const SSHORT* name_length)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* b l o b _ $ l o a d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Translate a pascal callable load
|
|
|
|
* into an internal load call.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-28 07:48:34 +01:00
|
|
|
// CVC: The old logic passed garbage to BLOB_load if !*name_length
|
|
|
|
TEXT temp[129];
|
|
|
|
USHORT l = *name_length;
|
2009-08-19 16:12:04 +02:00
|
|
|
if (l != 0)
|
|
|
|
{
|
2008-04-18 08:00:48 +02:00
|
|
|
if (l >= sizeof(temp))
|
2004-03-28 11:10:30 +02:00
|
|
|
l = sizeof(temp) - 1;
|
2008-04-18 08:00:48 +02:00
|
|
|
|
2006-02-23 06:08:26 +01:00
|
|
|
memcpy(temp, file_name, l);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2006-02-23 06:08:26 +01:00
|
|
|
temp[l] = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-12-25 07:09:37 +01:00
|
|
|
return BLOB_load(reinterpret_cast<ISC_QUAD*>(blob_id), *database, *transaction, temp);
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
static int any_text_load(ISC_QUAD* blob_id,
|
|
|
|
FB_API_HANDLE database,
|
|
|
|
FB_API_HANDLE transaction,
|
|
|
|
const TEXT* file_name,
|
|
|
|
FB_BOOLEAN flag)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* a n y _ t e x t _ l o a d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Load a blob with the contents of a file.
|
|
|
|
* Return TRUE is successful.
|
|
|
|
*
|
|
|
|
**************************************/
|
2015-03-20 19:02:30 +01:00
|
|
|
LocalStatus ls;
|
|
|
|
CheckStatusWrapper st(&ls);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
RefPtr<IAttachment> att(REF_NO_INCR, handleToIAttachment(&st, &database));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
RefPtr<ITransaction> tra(REF_NO_INCR, handleToITransaction(&st, &transaction));
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
|
2015-01-14 15:21:22 +01:00
|
|
|
UtilInterfacePtr()->loadBlob(&st, blob_id, att, tra, file_name, flag);
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
if (st.getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
{
|
2014-08-27 11:24:30 +02:00
|
|
|
isc_print_status(st.getErrors());
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_FAILURE;
|
|
|
|
}
|
2014-01-17 16:05:19 +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.
2014-01-15 14:02:08 +01:00
|
|
|
return FB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
int API_ROUTINE BLOB_text_load(ISC_QUAD* blob_id,
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE database,
|
2008-04-18 08:00:48 +02:00
|
|
|
FB_API_HANDLE transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const TEXT* file_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ t e x t _ l o a d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2008-04-18 08:00:48 +02:00
|
|
|
* Load a blob with the contents of a file.
|
2001-05-23 15:26:42 +02:00
|
|
|
* This call does CR/LF translation on NT.
|
|
|
|
* Return TRUE is successful.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return any_text_load(blob_id, database, transaction, file_name, FB_TRUE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-11 13:19:20 +01:00
|
|
|
int API_ROUTINE BLOB_load(ISC_QUAD* blob_id,
|
2008-04-18 08:00:48 +02:00
|
|
|
FB_API_HANDLE database,
|
|
|
|
FB_API_HANDLE transaction,
|
2003-11-28 07:48:34 +01:00
|
|
|
const TEXT* file_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ l o a d
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Load a blob with the contents of a file. Return TRUE is successful.
|
|
|
|
*
|
|
|
|
**************************************/
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return any_text_load(blob_id, database, transaction, file_name, FB_FALSE);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
FB_BLOB_STREAM API_ROUTINE Bopen(ISC_QUAD* blob_id,
|
|
|
|
FB_API_HANDLE database,
|
|
|
|
FB_API_HANDLE transaction,
|
|
|
|
const SCHAR* mode)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B o p e n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Initialize a blob-stream block.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-10-29 11:53:47 +01:00
|
|
|
// bpb is irrelevant, not used.
|
2003-11-28 07:48:34 +01:00
|
|
|
const USHORT bpb_length = 0;
|
|
|
|
const UCHAR* bpb = NULL;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE blob = 0;
|
2003-11-28 07:48:34 +01:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2008-01-16 11:17:51 +01:00
|
|
|
switch (*mode)
|
|
|
|
{
|
|
|
|
case 'w':
|
|
|
|
case 'W':
|
2009-01-20 09:33:59 +01:00
|
|
|
if (isc_create_blob2(status_vector, &database, &transaction, &blob, blob_id,
|
2008-12-25 07:09:37 +01:00
|
|
|
bpb_length, reinterpret_cast<const char*>(bpb)))
|
2003-09-15 13:14:47 +02:00
|
|
|
{
|
2003-09-13 01:37:06 +02:00
|
|
|
return NULL;
|
2003-09-15 13:14:47 +02:00
|
|
|
}
|
2008-01-16 11:17:51 +01:00
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
case 'R':
|
2009-01-20 09:33:59 +01:00
|
|
|
if (isc_open_blob2(status_vector, &database, &transaction, &blob, blob_id,
|
2008-12-25 07:09:37 +01:00
|
|
|
bpb_length, bpb))
|
2003-09-15 13:14:47 +02:00
|
|
|
{
|
2003-09-13 01:37:06 +02:00
|
|
|
return NULL;
|
2003-09-15 13:14:47 +02:00
|
|
|
}
|
2008-01-16 11:17:51 +01:00
|
|
|
break;
|
|
|
|
default:
|
2001-05-23 15:26:42 +02:00
|
|
|
return NULL;
|
2008-01-16 11:17:51 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
FB_BLOB_STREAM blobStream = BLOB_open(blob, NULL, 0);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-08-19 16:12:04 +02:00
|
|
|
if (*mode == 'w' || *mode == 'W')
|
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_mode |= BSTR_output;
|
|
|
|
blobStream->bstr_cnt = blobStream->bstr_length;
|
|
|
|
blobStream->bstr_ptr = blobStream->bstr_buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2009-08-19 16:12:04 +02:00
|
|
|
else
|
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_cnt = 0;
|
|
|
|
blobStream->bstr_mode |= BSTR_input;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
return blobStream;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
// CVC: This routine doesn't open a blob really!
|
2012-03-23 15:06:14 +01:00
|
|
|
FB_BLOB_STREAM API_ROUTINE BLOB_open(FB_API_HANDLE blob, SCHAR* buffer, int length)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ o p e n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Initialize a blob-stream block.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
if (!blob)
|
|
|
|
return NULL;
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
FB_BLOB_STREAM blobStream = (FB_BLOB_STREAM) gds__alloc((SLONG) sizeof(struct bstream));
|
2009-08-20 08:25:45 +02:00
|
|
|
// FREE: This structure is freed by BLOB_close
|
2012-03-23 15:06:14 +01:00
|
|
|
if (!blobStream) // NOMEM:
|
2001-05-23 15:26:42 +02:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
#ifdef DEBUG_gds__alloc
|
2009-08-20 08:25:45 +02:00
|
|
|
// This structure is handed to the user process, we depend on the client
|
|
|
|
// to call BLOB_close() for it to be freed.
|
2012-03-23 15:06:14 +01:00
|
|
|
gds_alloc_flag_unfreed((void*) blobStream);
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_blob = blob;
|
|
|
|
blobStream->bstr_length = length ? length : 512;
|
|
|
|
blobStream->bstr_mode = 0;
|
|
|
|
blobStream->bstr_cnt = 0;
|
|
|
|
blobStream->bstr_ptr = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
if (!(blobStream->bstr_buffer = buffer))
|
2009-08-19 16:12:04 +02:00
|
|
|
{
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_buffer = (SCHAR*) gds__alloc((SLONG) (sizeof(SCHAR) * blobStream->bstr_length));
|
2009-08-20 08:25:45 +02:00
|
|
|
// FREE: This structure is freed in BLOB_close()
|
2012-03-23 15:06:14 +01:00
|
|
|
if (!blobStream->bstr_buffer)
|
2009-08-19 16:12:04 +02:00
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// NOMEM:
|
2012-03-23 15:06:14 +01:00
|
|
|
gds__free(blobStream);
|
2001-05-23 15:26:42 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG_gds__alloc
|
2009-08-20 08:25:45 +02:00
|
|
|
// This structure is handed to the user process, we depend on the client
|
|
|
|
// to call BLOB_close() for it to be freed.
|
2012-03-23 15:06:14 +01:00
|
|
|
gds_alloc_flag_unfreed((void*) blobStream->bstr_buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
#endif
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_mode |= BSTR_alloc;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
return blobStream;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
int API_ROUTINE BLOB_put(SCHAR x, FB_BLOB_STREAM blobStream)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* B L O B _ p u t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Write a segment to a blob. First
|
|
|
|
* stick in the final character, then
|
|
|
|
* compute the length and send off the
|
|
|
|
* segment. Finally, set up the buffer
|
2008-04-18 08:00:48 +02:00
|
|
|
* block and retun TRUE if all is well.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2012-03-23 15:06:14 +01:00
|
|
|
if (!blobStream->bstr_buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
return FALSE;
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
*blobStream->bstr_ptr++ = (x & 0377);
|
|
|
|
const USHORT l = (blobStream->bstr_ptr - blobStream->bstr_buffer);
|
2004-12-23 07:28:41 +01:00
|
|
|
|
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2012-03-23 15:06:14 +01:00
|
|
|
if (isc_put_segment(status_vector, &blobStream->bstr_blob, l, blobStream->bstr_buffer))
|
2004-12-23 07:28:41 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
2012-03-23 15:06:14 +01:00
|
|
|
blobStream->bstr_cnt = blobStream->bstr_length;
|
|
|
|
blobStream->bstr_ptr = blobStream->bstr_buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2012-03-23 15:06:14 +01:00
|
|
|
|
|
|
|
int API_ROUTINE gds__thread_start(FPTR_INT_VOID_PTR* entrypoint,
|
|
|
|
void* arg,
|
|
|
|
int priority,
|
|
|
|
int /*flags*/,
|
|
|
|
void* thd_id)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g d s _ _ t h r e a d _ s t a r t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Start a thread.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
int rc = 0;
|
|
|
|
try
|
|
|
|
{
|
2014-08-15 16:59:38 +02:00
|
|
|
Thread::start((ThreadEntryPoint*) entrypoint, arg, priority, (Thread::Handle*) thd_id);
|
2012-03-23 15:06:14 +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.
2014-01-15 14:02:08 +01:00
|
|
|
catch (const status_exception& status)
|
2012-03-23 15:06:14 +01:00
|
|
|
{
|
|
|
|
rc = status.value()[1];
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2008-04-18 08:00:48 +02:00
|
|
|
#if (defined SOLARIS ) || (defined __cplusplus)
|
2004-06-07 08:50:38 +02:00
|
|
|
} //extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-01-12 01:21:38 +01:00
|
|
|
static void get_ods_version(CheckStatusWrapper* status, IAttachment* att,
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
USHORT* ods_version, USHORT* ods_minor_version)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* g e t _ o d s _ v e r s i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Obtain information about a on-disk structure (ods) versions
|
|
|
|
* of the database.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-11-28 07:48:34 +01:00
|
|
|
UCHAR buffer[16];
|
2001-05-23 15:26:42 +02: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.
2014-01-15 14:02:08 +01:00
|
|
|
att->getInfo(status, sizeof(ods_info), ods_info, sizeof(buffer), buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2015-02-18 16:01:17 +01:00
|
|
|
if (status->getState() & Firebird::IStatus::STATE_ERRORS)
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-28 07:48:34 +01:00
|
|
|
const UCHAR* p = buffer;
|
|
|
|
UCHAR item;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2009-01-20 09:33:59 +01:00
|
|
|
while ((item = *p++) != isc_info_end)
|
|
|
|
{
|
2003-11-28 07:48:34 +01:00
|
|
|
const USHORT l = static_cast<USHORT>(gds__vax_integer(p, 2));
|
2001-05-23 15:26:42 +02:00
|
|
|
p += 2;
|
2003-11-28 07:48:34 +01:00
|
|
|
const USHORT n = static_cast<USHORT>(gds__vax_integer(p, l));
|
2001-05-23 15:26:42 +02:00
|
|
|
p += l;
|
2009-01-20 09:33:59 +01:00
|
|
|
switch (item)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_info_ods_version:
|
2001-05-23 15:26:42 +02:00
|
|
|
*ods_version = n;
|
|
|
|
break;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_info_ods_minor_version:
|
2001-05-23 15:26:42 +02:00
|
|
|
*ods_minor_version = n;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
(Arg::Gds(isc_random) << "Invalid info item").raise();
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-29 11:53:47 +01:00
|
|
|
// CVC: I just made this alternative function to let the original unchanged.
|
|
|
|
// However, the original logic doesn't make sense.
|
|
|
|
static void isc_expand_dpb_internal(const UCHAR** dpb, SSHORT* dpb_size, ...)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* i s c _ e x p a n d _ d p b _ i n t e r n a l
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Extend a database parameter block dynamically
|
|
|
|
* to include runtime info. Generated
|
|
|
|
* by gpre to provide host variable support for
|
|
|
|
* READY statement options.
|
|
|
|
* This expects the list of variable args
|
|
|
|
* to be zero terminated.
|
|
|
|
*
|
|
|
|
* Note: dpb_size is signed short only for compatibility
|
|
|
|
* with other calls (isc_attach_database) that take a dpb length.
|
|
|
|
*
|
|
|
|
* TMN: Note: According to Ann Harrison:
|
|
|
|
* That routine should be deprecated. It doesn't do what it
|
|
|
|
* should, and does do things it shouldn't, and is harder to
|
|
|
|
* use than the natural alternative.
|
|
|
|
*
|
|
|
|
* CVC: This alternative version returns either the original dpb or a
|
|
|
|
* new one, but never overwrites the original dpb. More accurately, it's
|
|
|
|
* clearer than the original function that really never modifies its source
|
|
|
|
* dpb, but there appears to be a logic failure on an impossible path.
|
|
|
|
* Also, since the change from UCHAR** to const UCHAR** is not transparent,
|
|
|
|
* a new version was needed to make sure the old world wasn't broken.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
SSHORT length;
|
|
|
|
unsigned char* p = 0;
|
|
|
|
const char* q;
|
|
|
|
const unsigned char* uq;
|
|
|
|
va_list args;
|
|
|
|
USHORT type;
|
|
|
|
UCHAR* new_dpb;
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// calculate length of database parameter block, setting initial length to include version
|
2003-10-29 11:53:47 +01:00
|
|
|
|
|
|
|
SSHORT new_dpb_length;
|
|
|
|
if (!*dpb || !(new_dpb_length = *dpb_size))
|
|
|
|
{
|
|
|
|
new_dpb_length = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_start(args, dpb_size);
|
|
|
|
|
|
|
|
while (type = va_arg(args, int))
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
|
|
|
case isc_dpb_password:
|
2003-10-29 11:53:47 +01:00
|
|
|
case isc_dpb_sql_role_name:
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_lc_messages:
|
|
|
|
case isc_dpb_lc_ctype:
|
2003-10-29 11:53:47 +01:00
|
|
|
case isc_dpb_reserved:
|
|
|
|
q = va_arg(args, char*);
|
|
|
|
if (q)
|
|
|
|
{
|
2014-07-17 20:48:46 +02:00
|
|
|
length = static_cast<SSHORT>(strlen(q));
|
2003-10-29 11:53:47 +01:00
|
|
|
new_dpb_length += 2 + length;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
va_arg(args, int);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
va_end(args);
|
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// if items have been added, allocate space for the new dpb and copy the old one over
|
2003-10-29 11:53:47 +01:00
|
|
|
|
|
|
|
if (new_dpb_length > *dpb_size)
|
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// Note: gds__free done by GPRE generated code
|
2003-10-29 11:53:47 +01:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
new_dpb = (UCHAR*) gds__alloc((SLONG)(sizeof(UCHAR) * new_dpb_length));
|
2003-10-29 11:53:47 +01:00
|
|
|
p = new_dpb;
|
2009-08-20 08:25:45 +02:00
|
|
|
// FREE: done by client process in GPRE generated code
|
2003-10-29 11:53:47 +01:00
|
|
|
if (!new_dpb)
|
2009-08-19 16:12:04 +02:00
|
|
|
{
|
2009-08-20 08:25:45 +02:00
|
|
|
// NOMEM: don't trash existing dpb
|
2003-10-29 11:53:47 +01:00
|
|
|
DEV_REPORT("isc_extend_dpb: out of memory");
|
2009-08-20 08:25:45 +02:00
|
|
|
return; // NOMEM: not really handled
|
2003-10-29 11:53:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
uq = *dpb;
|
|
|
|
for (length = *dpb_size; length; length--)
|
|
|
|
{
|
|
|
|
*p++ = *uq++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// CVC: Notice the initialization is: new_dpb_length = *dpb_size
|
|
|
|
// Therefore, the worst case is new_dpb_length == *dpb_size
|
|
|
|
// Also, if *dpb_size == 0, then new_dpb_length is set to 1,
|
|
|
|
// so there will be again a bigger new buffer.
|
|
|
|
// Hence, this else just means "we found nothing that we can
|
|
|
|
// recognize in the variable params list to add and thus,
|
|
|
|
// there's nothing to do". The case for new_dpb_length being less
|
|
|
|
// than the original length simply can't happen. Therefore,
|
|
|
|
// the input can be declared const.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*dpb_size)
|
2003-11-08 17:40:17 +01:00
|
|
|
*p++ = isc_dpb_version1;
|
2003-10-29 11:53:47 +01:00
|
|
|
|
2009-08-20 08:25:45 +02:00
|
|
|
// copy in the new runtime items
|
2003-10-29 11:53:47 +01:00
|
|
|
|
|
|
|
va_start(args, dpb_size);
|
|
|
|
|
|
|
|
while (type = va_arg(args, int))
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_user_name:
|
|
|
|
case isc_dpb_password:
|
2003-10-29 11:53:47 +01:00
|
|
|
case isc_dpb_sql_role_name:
|
2003-11-08 17:40:17 +01:00
|
|
|
case isc_dpb_lc_messages:
|
|
|
|
case isc_dpb_lc_ctype:
|
2003-10-29 11:53:47 +01:00
|
|
|
case isc_dpb_reserved:
|
|
|
|
q = va_arg(args, char*);
|
|
|
|
if (q)
|
|
|
|
{
|
2014-07-17 20:48:46 +02:00
|
|
|
length = static_cast<SSHORT>(strlen(q));
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(type <= CHAR_MAX);
|
2003-10-29 11:53:47 +01:00
|
|
|
*p++ = (unsigned char) type;
|
2003-11-04 00:59:24 +01:00
|
|
|
fb_assert(length <= CHAR_MAX);
|
2003-10-29 11:53:47 +01:00
|
|
|
*p++ = (unsigned char) length;
|
|
|
|
while (length--)
|
|
|
|
*p++ = *q++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
va_arg(args, int);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
*dpb_size = p - new_dpb;
|
|
|
|
*dpb = new_dpb;
|
|
|
|
}
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-12-09 20:19:47 +01:00
|
|
|
// new utl
|
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.
2014-01-15 14:02:08 +01:00
|
|
|
static void setTag(ClumpletWriter& dpb, UCHAR tag, const char* env, bool utf8)
|
2004-12-09 20:19:47 +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.
2014-01-15 14:02:08 +01:00
|
|
|
string value;
|
2013-11-24 04:21:11 +01:00
|
|
|
|
|
|
|
if (fb_utils::readenv(env, value) && !dpb.find(tag))
|
2004-12-09 20:19:47 +01:00
|
|
|
{
|
2012-03-15 16:05:31 +01:00
|
|
|
if (utf8)
|
|
|
|
ISC_systemToUtf8(value);
|
2013-11-24 04:21:11 +01:00
|
|
|
|
2012-03-15 16:05:31 +01:00
|
|
|
dpb.insertString(tag, value);
|
2004-12-09 20:19:47 +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.
2014-01-15 14:02:08 +01:00
|
|
|
void setLogin(ClumpletWriter& dpb, bool spbFlag)
|
2004-12-09 20:19:47 +01:00
|
|
|
{
|
2011-12-30 15:11:24 +01:00
|
|
|
const UCHAR address_path = spbFlag ? isc_spb_address_path : isc_dpb_address_path;
|
|
|
|
const UCHAR trusted_auth = spbFlag ? isc_spb_trusted_auth : isc_dpb_trusted_auth;
|
|
|
|
const UCHAR auth_block = spbFlag ? isc_spb_auth_block : isc_dpb_auth_block;
|
2012-03-15 16:05:31 +01:00
|
|
|
const UCHAR utf8Tag = spbFlag ? isc_spb_utf8_filename : isc_dpb_utf8_filename;
|
2011-12-30 15:11:24 +01:00
|
|
|
// username and password tags match for both SPB and DPB
|
|
|
|
|
|
|
|
if (!(dpb.find(trusted_auth) || dpb.find(address_path) || dpb.find(auth_block)))
|
2004-12-09 20:19:47 +01:00
|
|
|
{
|
2012-03-15 16:05:31 +01:00
|
|
|
bool utf8 = dpb.find(utf8Tag);
|
2013-10-16 14:53:04 +02:00
|
|
|
|
|
|
|
setTag(dpb, isc_dpb_user_name, ISC_USER, utf8);
|
|
|
|
if (!dpb.find(isc_dpb_password_enc))
|
|
|
|
setTag(dpb, isc_dpb_password, ISC_PASSWORD, utf8);
|
2013-11-24 04:21:11 +01:00
|
|
|
|
2013-10-16 14:53:04 +02:00
|
|
|
if (spbFlag)
|
|
|
|
setTag(dpb, isc_spb_expected_db, "FB_EXPECTED_DB", utf8);
|
2004-12-09 20:19:47 +01:00
|
|
|
}
|
|
|
|
}
|
2015-03-27 15:36:30 +01:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// circularAlloc()
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifdef WIN_NT
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
class ThreadCleanup
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
static void add(FPTR_VOID_PTR cleanup, void* arg);
|
|
|
|
static void remove(FPTR_VOID_PTR cleanup, void* arg);
|
|
|
|
static void destructor(void*);
|
|
|
|
|
|
|
|
static void assertNoCleanupChain()
|
|
|
|
{
|
|
|
|
fb_assert(!chain);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
FPTR_VOID_PTR function;
|
|
|
|
void* argument;
|
|
|
|
ThreadCleanup* next;
|
|
|
|
|
|
|
|
static ThreadCleanup* chain;
|
|
|
|
static GlobalPtr<Mutex> cleanupMutex;
|
|
|
|
|
|
|
|
ThreadCleanup(FPTR_VOID_PTR cleanup, void* arg, ThreadCleanup* chain)
|
|
|
|
: function(cleanup), argument(arg), next(chain) { }
|
|
|
|
|
|
|
|
static void initThreadCleanup();
|
|
|
|
static void finiThreadCleanup();
|
|
|
|
|
|
|
|
static ThreadCleanup** findCleanup(FPTR_VOID_PTR cleanup, void* arg);
|
|
|
|
};
|
|
|
|
|
|
|
|
ThreadCleanup* ThreadCleanup::chain = NULL;
|
|
|
|
GlobalPtr<Mutex> ThreadCleanup::cleanupMutex;
|
|
|
|
|
|
|
|
#ifdef USE_POSIX_THREADS
|
|
|
|
|
|
|
|
pthread_key_t key;
|
|
|
|
pthread_once_t keyOnce = PTHREAD_ONCE_INIT;
|
|
|
|
bool keySet = false;
|
|
|
|
|
|
|
|
void makeKey()
|
|
|
|
{
|
|
|
|
int err = pthread_key_create(&key, ThreadCleanup::destructor);
|
|
|
|
if (err)
|
|
|
|
{
|
|
|
|
Firebird::system_call_failed("pthread_key_create", err);
|
|
|
|
}
|
|
|
|
keySet = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadCleanup::initThreadCleanup()
|
|
|
|
{
|
|
|
|
int err = pthread_once(&keyOnce, makeKey);
|
|
|
|
if (err)
|
|
|
|
{
|
|
|
|
Firebird::system_call_failed("pthread_once", err);
|
|
|
|
}
|
|
|
|
|
|
|
|
err = pthread_setspecific(key, &key);
|
|
|
|
if (err)
|
|
|
|
{
|
|
|
|
Firebird::system_call_failed("pthread_setspecific", err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadCleanup::finiThreadCleanup()
|
|
|
|
{
|
|
|
|
pthread_setspecific(key, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class FiniThreadCleanup
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
FiniThreadCleanup(Firebird::MemoryPool&)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
~FiniThreadCleanup()
|
|
|
|
{
|
|
|
|
ThreadCleanup::assertNoCleanupChain();
|
|
|
|
if (keySet)
|
|
|
|
{
|
|
|
|
int err = pthread_key_delete(key);
|
|
|
|
if (err)
|
|
|
|
Firebird::system_call_failed("pthread_key_delete", err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Firebird::GlobalPtr<FiniThreadCleanup> thrCleanup; // needed to call dtor
|
|
|
|
|
|
|
|
#endif // USE_POSIX_THREADS
|
|
|
|
|
|
|
|
#ifdef WIN_NT
|
|
|
|
void ThreadCleanup::initThreadCleanup()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadCleanup::finiThreadCleanup()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif // #ifdef WIN_NT
|
|
|
|
|
|
|
|
ThreadCleanup** ThreadCleanup::findCleanup(FPTR_VOID_PTR cleanup, void* arg)
|
|
|
|
{
|
|
|
|
for (ThreadCleanup** ptr = &chain; *ptr; ptr = &((*ptr)->next))
|
|
|
|
{
|
|
|
|
if ((*ptr)->function == cleanup && (*ptr)->argument == arg)
|
|
|
|
{
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadCleanup::destructor(void*)
|
|
|
|
{
|
|
|
|
MutexLockGuard guard(cleanupMutex, FB_FUNCTION);
|
|
|
|
|
|
|
|
for (ThreadCleanup* ptr = chain; ptr; ptr = ptr->next)
|
|
|
|
{
|
|
|
|
ptr->function(ptr->argument);
|
|
|
|
}
|
|
|
|
|
|
|
|
finiThreadCleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadCleanup::add(FPTR_VOID_PTR cleanup, void* arg)
|
|
|
|
{
|
|
|
|
Firebird::MutexLockGuard guard(cleanupMutex, FB_FUNCTION);
|
|
|
|
|
|
|
|
initThreadCleanup();
|
|
|
|
|
|
|
|
if (findCleanup(cleanup, arg))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-12 16:26:00 +02:00
|
|
|
chain = FB_NEW_POOL(*getDefaultMemoryPool()) ThreadCleanup(cleanup, arg, chain);
|
2015-03-27 15:36:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadCleanup::remove(FPTR_VOID_PTR cleanup, void* arg)
|
|
|
|
{
|
|
|
|
MutexLockGuard guard(cleanupMutex, FB_FUNCTION);
|
|
|
|
|
|
|
|
ThreadCleanup** ptr = findCleanup(cleanup, arg);
|
|
|
|
if (!ptr)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadCleanup* toDelete = *ptr;
|
|
|
|
*ptr = toDelete->next;
|
|
|
|
delete toDelete;
|
|
|
|
}
|
|
|
|
|
|
|
|
class ThreadBuffer : public GlobalStorage
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
const static size_t BUFFER_SIZE = 8192; // make it match with call stack limit == 2048
|
|
|
|
char buffer[BUFFER_SIZE];
|
|
|
|
char* buffer_ptr;
|
|
|
|
|
|
|
|
public:
|
|
|
|
ThreadBuffer() : buffer_ptr(buffer) { }
|
|
|
|
|
|
|
|
const char* alloc(const char* string, size_t length)
|
|
|
|
{
|
|
|
|
// if string is already in our buffer - return it
|
|
|
|
// it was already saved in our buffer once
|
|
|
|
if (string >= buffer && string < &buffer[BUFFER_SIZE])
|
|
|
|
return string;
|
|
|
|
|
|
|
|
// if string too long, truncate it
|
|
|
|
if (length > BUFFER_SIZE / 4)
|
|
|
|
length = BUFFER_SIZE / 4;
|
|
|
|
|
|
|
|
// If there isn't any more room in the buffer, start at the beginning again
|
|
|
|
if (buffer_ptr + length + 1 > buffer + BUFFER_SIZE)
|
|
|
|
buffer_ptr = buffer;
|
|
|
|
|
|
|
|
char* new_string = buffer_ptr;
|
|
|
|
memcpy(new_string, string, length);
|
|
|
|
new_string[length] = 0;
|
|
|
|
buffer_ptr += length + 1;
|
|
|
|
|
|
|
|
return new_string;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TLS_DECLARE(ThreadBuffer*, threadBuffer);
|
|
|
|
|
|
|
|
void cleanupAllStrings(void*)
|
|
|
|
{
|
|
|
|
///fprintf(stderr, "Cleanup is called\n");
|
|
|
|
|
|
|
|
delete TLS_GET(threadBuffer);
|
|
|
|
TLS_SET(threadBuffer, NULL);
|
|
|
|
|
|
|
|
///fprintf(stderr, "Buffer removed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadBuffer* getThreadBuffer()
|
|
|
|
{
|
|
|
|
ThreadBuffer* rc = TLS_GET(threadBuffer);
|
|
|
|
if (!rc)
|
|
|
|
{
|
|
|
|
ThreadCleanup::add(cleanupAllStrings, NULL);
|
2015-10-12 16:26:00 +02:00
|
|
|
rc = FB_NEW ThreadBuffer;
|
2015-03-27 15:36:30 +01:00
|
|
|
TLS_SET(threadBuffer, rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Needed to call dtor
|
|
|
|
class Strings
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Strings(MemoryPool&)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
~Strings()
|
|
|
|
{
|
|
|
|
ThreadCleanup::remove(cleanupAllStrings, NULL);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Firebird::GlobalPtr<Strings> cleanStrings;
|
|
|
|
|
|
|
|
const char* circularAlloc(const char* s, unsigned len)
|
|
|
|
{
|
|
|
|
return getThreadBuffer()->alloc(s, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CVC: Do not let "perm" be incremented before "trans", because it may lead to serious memory errors,
|
|
|
|
// since our code blindly passes the same vector twice.
|
|
|
|
void makePermanentVector(ISC_STATUS* perm, const ISC_STATUS* trans) throw()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
const ISC_STATUS type = *perm++ = *trans++;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case isc_arg_end:
|
|
|
|
return;
|
2015-03-28 01:36:04 +01:00
|
|
|
|
2015-03-27 15:36:30 +01:00
|
|
|
case isc_arg_cstring:
|
|
|
|
{
|
|
|
|
perm [-1] = isc_arg_string;
|
|
|
|
const size_t len = *trans++;
|
|
|
|
const char* temp = reinterpret_cast<char*>(*trans++);
|
|
|
|
*perm++ = (ISC_STATUS)(IPTR) circularAlloc(temp, len);
|
|
|
|
}
|
|
|
|
break;
|
2015-03-28 01:36:04 +01:00
|
|
|
|
2015-03-27 15:36:30 +01:00
|
|
|
case isc_arg_string:
|
|
|
|
case isc_arg_interpreted:
|
|
|
|
case isc_arg_sql_state:
|
|
|
|
{
|
|
|
|
const char* temp = reinterpret_cast<char*>(*trans++);
|
|
|
|
const size_t len = strlen(temp);
|
|
|
|
*perm++ = (ISC_STATUS)(IPTR) circularAlloc(temp, len);
|
|
|
|
}
|
|
|
|
break;
|
2015-03-28 01:36:04 +01:00
|
|
|
|
2015-03-27 15:36:30 +01:00
|
|
|
default:
|
|
|
|
*perm++ = *trans++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (const system_call_failed& ex)
|
|
|
|
{
|
|
|
|
memcpy(perm, ex.value(), sizeof(ISC_STATUS_ARRAY));
|
|
|
|
}
|
|
|
|
catch (const BadAlloc&)
|
|
|
|
{
|
|
|
|
*perm++ = isc_arg_gds;
|
|
|
|
*perm++ = isc_virmemexh;
|
|
|
|
*perm++ = isc_arg_end;
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
*perm++ = isc_arg_gds;
|
|
|
|
*perm++ = isc_random;
|
|
|
|
*perm++ = isc_arg_string;
|
|
|
|
*perm++ = (ISC_STATUS)(IPTR) "Unexpected exception in makePermanentVector()";
|
|
|
|
*perm++ = isc_arg_end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
void makePermanentVector(ISC_STATUS* v) throw()
|
|
|
|
{
|
|
|
|
makePermanentVector(v, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef WIN_NT
|
|
|
|
namespace Why
|
|
|
|
{
|
|
|
|
// This is called from ibinitdll.cpp:DllMain()
|
|
|
|
void threadCleanup()
|
|
|
|
{
|
|
|
|
ThreadCleanup::destructor(NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|