Hi all,
Pls find enclosed patch which implements:
dbCreateTemp( <cAlias>, <aStruct>, <cRDD>, <cDelimArg>, <cCodePage>,
<nConnection> ) -> <lSuccess>
This creates and opens a new temporary table. The file automatically
gets deleted on close, all indexes created are also handled as temporary.
Please review and comment.
Brgds,
Viktor
---
Index: include/hbrdddbf.h
===================================================================
--- include/hbrdddbf.h (revision 10239)
+++ include/hbrdddbf.h (working copy)
@@ -223,6 +223,7 @@
BOOL fMemoFlush; /* data was written to MEMO and not
commited */
BOOL fShared; /* Shared file */
BOOL fReadonly; /* Read only file */
+ BOOL fTemporary; /* Temporary file */
BOOL fValidBuffer; /* State of buffer */
BOOL fPositioned; /* Positioned record */
BOOL fRecordChanged; /* Record changed */
Index: include/hbrddnsx.h
===================================================================
--- include/hbrddnsx.h (revision 10239)
+++ include/hbrddnsx.h (working copy)
@@ -307,7 +307,7 @@
} NSXLEAFPAGE;
typedef NSXLEAFPAGE * LPNSXLEAFPAGE;
-#if 0
+#if 0
/* meta structures for description only, cannot be compiled due to
variable member sizes */
typedef struct _NSXBRANCHKEY
@@ -595,6 +595,7 @@
BOOL fMemoFlush; /* data was written to MEMO and not
commited */
BOOL fShared; /* Shared file */
BOOL fReadonly; /* Read only file */
+ BOOL fTemporary; /* Temporary file */
BOOL fValidBuffer; /* State of buffer */
BOOL fPositioned; /* Positioned record */
BOOL fRecordChanged; /* Record changed */
Index: include/hbapirdd.h
===================================================================
--- include/hbapirdd.h (revision 10239)
+++ include/hbapirdd.h (working copy)
@@ -197,6 +197,7 @@
BYTE * atomAlias; /* The logical name of the data store */
BOOL fShared; /* Share mode of the data store */
BOOL fReadonly; /* Readonly mode of the data store */
+ BOOL fTemporary; /* Is this a temporary data store */
BYTE * cdpId; /* Id of a codepage */
ULONG ulConnection; /* connection handler for RDDs which support it
*/
void * lpdbHeader; /* Pointer to a header of the data store */
@@ -1195,6 +1196,11 @@
BOOL fKeepOpen,
const char * szCpId, ULONG ulConnection,
PHB_ITEM pStruct, PHB_ITEM pDelim );
+extern HB_EXPORT HB_ERRCODE hb_rddCreateTableTemp(
+ const char * szDriver,
+ const char * szAlias,
+ const char * szCpId, ULONG ulConnection,
+ PHB_ITEM pStruct, PHB_ITEM pDelim );
extern HB_EXPORT HB_ERRCODE hb_dbTransStruct(
AREAP lpaSource, AREAP lpaDest,
LPDBTRANSINFO lpdbTransInfo,
Index: include/dbinfo.ch
===================================================================
--- include/dbinfo.ch (revision 10239)
+++ include/dbinfo.ch (working copy)
@@ -289,6 +289,7 @@
#define DBI_MEMOPACK 142 /* Pack memo file */
#define DBI_DIRTYREAD 143 /* Get/Set index dirty read flag */
#define DBI_POSITIONED 144 /* Is cursor positioned to valid
record */
+#define DBI_ISTEMPORARY 145 /* Is the table a temporary one? */
/* RECORD MAP (RM) support */
#define DBI_RM_SUPPORTED 150 /* has WA RDD record map support? */
Index: include/hbrddcdx.h
===================================================================
--- include/hbrddcdx.h (revision 10239)
+++ include/hbrddcdx.h (working copy)
@@ -506,6 +506,7 @@
BOOL fMemoFlush; /* data was written to MEMO and not
commited */
BOOL fShared; /* Shared file */
BOOL fReadonly; /* Read only file */
+ BOOL fTemporary; /* Temporary file */
BOOL fValidBuffer; /* State of buffer */
BOOL fPositioned; /* Positioned record */
BOOL fRecordChanged; /* Record changed */
Index: include/hbrddntx.h
===================================================================
--- include/hbrddntx.h (revision 10239)
+++ include/hbrddntx.h (working copy)
@@ -400,6 +400,7 @@
BOOL fMemoFlush; /* data was written to MEMO and not
commited */
BOOL fShared; /* Shared file */
BOOL fReadonly; /* Read only file */
+ BOOL fTemporary; /* Temporary file */
BOOL fValidBuffer; /* State of buffer */
BOOL fPositioned; /* Positioned record */
BOOL fRecordChanged; /* Record changed */
Index: source/rdd/dbfntx/dbfntx1.c
===================================================================
--- source/rdd/dbfntx/dbfntx1.c (revision 10239)
+++ source/rdd/dbfntx/dbfntx1.c (working copy)
@@ -6235,6 +6235,9 @@
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
+ if( pArea->fTemporary )
+ fTemporary = TRUE;
+
pData = DBFAREA_DATA( pArea );
/*
* abBagName -> cBag, atomBagName -> cTag
Index: source/rdd/dbfnsx/dbfnsx1.c
===================================================================
--- source/rdd/dbfnsx/dbfnsx1.c (revision 10239)
+++ source/rdd/dbfnsx/dbfnsx1.c (working copy)
@@ -6675,6 +6675,9 @@
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
+ if( pArea->fTemporary )
+ fTemporary = TRUE;
+
/*
* abBagName -> cBag, atomBagName -> cTag
* The following scheme implemented:
Index: source/rdd/dbfcdx/dbfcdx1.c
===================================================================
--- source/rdd/dbfcdx/dbfcdx1.c (revision 10239)
+++ source/rdd/dbfcdx/dbfcdx1.c (working copy)
@@ -7592,6 +7592,9 @@
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
+ if( pArea->fTemporary )
+ fTemporary = TRUE;
+
/*
* abBagName -> cBag, atomBagName -> cTag
* The following scheme implemented:
Index: source/rdd/dbcmd.c
===================================================================
--- source/rdd/dbcmd.c (revision 10239)
+++ source/rdd/dbcmd.c (working copy)
@@ -399,6 +399,63 @@
}
/*
+ * dbCreateTemp( <cAlias>, <aStruct>, <cRDD>, <cDelimArg>, <cCodePage>,
<nConnection> ) -> <lSuccess>
+ */
+HB_FUNC( DBCREATETEMP )
+{
+ char * szAlias, * szDriver, * szCpId;
+ USHORT uiSize, uiLen;
+ PHB_ITEM pStruct, pFieldDesc, pDelim;
+ ULONG ulConnection;
+
+ szAlias = hb_parc( 1 );
+ pStruct = hb_param( 2, HB_IT_ARRAY );
+ szDriver = hb_parc( 3 );
+ pDelim = hb_param( 4, HB_IT_ANY );
+ szCpId = hb_parc( 5 );
+ ulConnection = hb_parnl( 6 );
+
+ /*
+ * Clipper allows to use empty struct array for RDDs which does not
+ * support fields, f.e.: DBFBLOB in CL5.3
+ * In CL5.3 it's also possible to create DBF file without fields.
+ * if some RDD wants to block it then they should serve it in lower
+ * level, [druzus]
+ */
+ if( !pStruct
+#ifdef HB_C52_STRICT
+ || hb_arrayLen( pStruct ) == 0
+#endif
+ )
+ {
+ hb_errRT_DBCMD( EG_ARG, EDBCMD_DBCMDBADPARAMETER, NULL,
HB_ERR_FUNCNAME );
+ return;
+ }
+ uiLen = ( USHORT ) hb_arrayLen( pStruct );
+
+ for( uiSize = 1; uiSize <= uiLen; ++uiSize )
+ {
+ pFieldDesc = hb_arrayGetItemPtr( pStruct, uiSize );
+
+ /* Validate items types of fields */
+ if( hb_arrayLen( pFieldDesc ) < 4 ||
+ !( hb_arrayGetType( pFieldDesc, 1 ) & HB_IT_STRING ) ||
+ !( hb_arrayGetType( pFieldDesc, 2 ) & HB_IT_STRING ) ||
+ !( hb_arrayGetType( pFieldDesc, 3 ) & HB_IT_NUMERIC ) ||
+ !( hb_arrayGetType( pFieldDesc, 4 ) & HB_IT_NUMERIC ) )
+ {
+ hb_errRT_DBCMD( EG_ARG, EDBCMD_DBCMDBADPARAMETER, NULL,
HB_ERR_FUNCNAME );
+ return;
+ }
+ }
+
+ hb_retl( hb_rddCreateTableTemp( szDriver,
+ szAlias,
+ szCpId, ulConnection,
+ pStruct, pDelim ) == HB_SUCCESS );
+}
+
+/*
* I'm not sure if lKeepOpen open works exactly like in DBCREATE, I haven't
* tested it with Clipper yet. If it doesn't then please inform me about it
* and I'll update the code. [druzus]
Index: source/rdd/dbf1.c
===================================================================
--- source/rdd/dbf1.c (revision 10239)
+++ source/rdd/dbf1.c (working copy)
@@ -2660,6 +2660,9 @@
{
hb_fileClose( pArea->pDataFile );
pArea->pDataFile = NULL;
+
+ if( pArea->fTemporary )
+ hb_fsDelete( ( BYTE * ) pArea->szDataFileName );
}
/* Close the memo file */
@@ -2667,8 +2670,14 @@
{
hb_fileClose( pArea->pMemoFile );
pArea->pMemoFile = NULL;
+
+ if( pArea->fTemporary )
+ hb_fsDelete( ( BYTE * ) pArea->szMemoFileName );
}
+ if( pArea->fTemporary )
+ pArea->fTemporary = FALSE;
+
/* Free field offset array */
if( pArea->pFieldOffset )
{
@@ -2730,27 +2739,31 @@
HB_TRACE(HB_TR_DEBUG, ("hb_dbfCreate(%p, %p)", pArea, pCreateInfo));
pArea->lpdbOpenInfo = pCreateInfo;
+ pArea->fTemporary = pCreateInfo->fTemporary;
- pFileName = hb_fsFNameSplit( ( char * ) pCreateInfo->abName );
+ if( ! pArea->fTemporary )
+ {
+ pFileName = hb_fsFNameSplit( ( char * ) pCreateInfo->abName );
- if( ! pFileName->szExtension && hb_setGetDefExtension() )
- {
- pItem = hb_itemPutC( pItem, NULL );
- if( SELF_INFO( ( AREAP ) pArea, DBI_TABLEEXT, pItem ) != HB_SUCCESS )
+ if( ! pFileName->szExtension && hb_setGetDefExtension() )
{
- hb_itemRelease( pItem );
- hb_xfree( pFileName );
- pArea->lpdbOpenInfo = NULL;
- return HB_FAILURE;
+ pItem = hb_itemPutC( pItem, NULL );
+ if( SELF_INFO( ( AREAP ) pArea, DBI_TABLEEXT, pItem ) !=
HB_SUCCESS )
+ {
+ hb_itemRelease( pItem );
+ hb_xfree( pFileName );
+ pArea->lpdbOpenInfo = NULL;
+ return HB_FAILURE;
+ }
+ pFileName->szExtension = hb_itemGetCPtr( pItem );
+ hb_fsFNameMerge( ( char * ) szFileName, pFileName );
}
- pFileName->szExtension = hb_itemGetCPtr( pItem );
- hb_fsFNameMerge( ( char * ) szFileName, pFileName );
+ else
+ {
+ hb_strncpy( ( char * ) szFileName, ( char * ) pCreateInfo->abName,
sizeof( szFileName ) - 1 );
+ }
+ hb_xfree( pFileName );
}
- else
- {
- hb_strncpy( ( char * ) szFileName, ( char * ) pCreateInfo->abName,
sizeof( szFileName ) - 1 );
- }
- hb_xfree( pFileName );
pItem = hb_itemPutL( pItem, FALSE );
fRawBlob = SELF_RDDINFO( SELF_RDDNODE( pArea ), RDDI_BLOB_SUPPORT,
pCreateInfo->ulConnection, pItem ) == HB_SUCCESS &&
@@ -2826,10 +2839,13 @@
/* Try create */
do
{
- pArea->pDataFile = hb_fileExtOpen( szFileName, NULL,
- FO_READWRITE | FO_EXCLUSIVE |
FXO_TRUNCATE |
- FXO_DEFAULTS | FXO_SHARELOCK |
FXO_COPYNAME,
- NULL, pError );
+ if( pArea->fTemporary )
+ pArea->pDataFile = hb_fileCreateTempEx( szFileName, NULL, NULL,
NULL, FC_NORMAL );
+ else
+ pArea->pDataFile = hb_fileExtOpen( szFileName, NULL,
+ FO_READWRITE | FO_EXCLUSIVE
| FXO_TRUNCATE |
+ FXO_DEFAULTS | FXO_SHARELOCK
| FXO_COPYNAME,
+ NULL, pError );
if( ! pArea->pDataFile )
{
if( !pError )
@@ -3075,7 +3091,7 @@
}
pThisField++;
}
- pArea->fShared = FALSE; /* pCreateInfo->fShared; */
+ pArea->fShared = FALSE; /* pCreateInfo->fShared */
pArea->fReadonly = FALSE; /* pCreateInfo->fReadonly */
pArea->ulRecCount = 0;
pArea->uiHeaderLen = ( USHORT ) ( sizeof( DBFHEADER ) + ulSize );
@@ -3273,6 +3289,10 @@
hb_itemPutL( pItem, pArea->fReadonly );
break;
+ case DBI_ISTEMPORARY:
+ hb_itemPutL( pItem, pArea->fTemporary );
+ break;
+
case DBI_VALIDBUFFER:
hb_itemPutL( pItem, pArea->fValidBuffer );
break;
@@ -3642,6 +3662,7 @@
#endif
pArea->fShared = pOpenInfo->fShared;
pArea->fReadonly = pOpenInfo->fReadonly;
+/* pArea->fTemporary = pOpenInfo->fTemporary; */
/* Force exclusive mode
* 0: AUTOSHARE disabled.
* 1: AUTOSHARE enabled.
Index: source/rdd/wafunc.c
===================================================================
--- source/rdd/wafunc.c (revision 10239)
+++ source/rdd/wafunc.c (working copy)
@@ -583,10 +583,10 @@
}
HB_ERRCODE hb_rddOpenTable( const char * szFileName, const char * szDriver,
- USHORT uiArea, const char *szAlias,
- BOOL fShared, BOOL fReadonly,
- const char * szCpId, ULONG ulConnection,
- PHB_ITEM pStruct, PHB_ITEM pDelim )
+ USHORT uiArea, const char *szAlias,
+ BOOL fShared, BOOL fReadonly,
+ const char * szCpId, ULONG ulConnection,
+ PHB_ITEM pStruct, PHB_ITEM pDelim )
{
char szDriverBuffer[ HB_RDD_MAX_DRIVERNAME_LEN + 1 ];
DBOPENINFO pInfo;
@@ -671,10 +671,10 @@
}
HB_ERRCODE hb_rddCreateTable( const char * szFileName, const char *
szDriver,
- USHORT uiArea, const char *szAlias,
- BOOL fKeepOpen,
- const char * szCpId, ULONG ulConnection,
- PHB_ITEM pStruct, PHB_ITEM pDelim )
+ USHORT uiArea, const char *szAlias,
+ BOOL fKeepOpen,
+ const char * szCpId, ULONG ulConnection,
+ PHB_ITEM pStruct, PHB_ITEM pDelim )
{
char szDriverBuffer[ HB_RDD_MAX_DRIVERNAME_LEN + 1 ];
DBOPENINFO pInfo;
@@ -748,6 +748,76 @@
return errCode;
}
+HB_ERRCODE hb_rddCreateTableTemp( const char * szDriver,
+ const char * szAlias,
+ const char * szCpId, ULONG ulConnection,
+ PHB_ITEM pStruct, PHB_ITEM pDelim )
+{
+ char szDriverBuffer[ HB_RDD_MAX_DRIVERNAME_LEN + 1 ];
+ DBOPENINFO pInfo;
+ HB_ERRCODE errCode;
+ USHORT uiPrevArea;
+ AREAP pArea;
+
+ if( szDriver && szDriver[ 0 ] )
+ {
+ hb_strncpyUpper( szDriverBuffer, szDriver, sizeof( szDriverBuffer ) -
1 );
+ szDriver = szDriverBuffer;
+ }
+ else
+ szDriver = hb_rddDefaultDrv( NULL );
+
+ uiPrevArea = hb_rddGetCurrentWorkAreaNumber();
+
+ /*
+ * 0 means chose first available in hb_rddInsertAreaNode()
+ * This hack is necessary to avoid race condition in MT
+ * mode where workareas are shared between threads and
+ * we don't want to lock whole RDD subsystem, [druzus]
+ */
+ hb_rddSelectWorkAreaNumber( 0 );
+
+ /* Create a new WorkArea node */
+ if( ! hb_rddInsertAreaNode( szDriver ) )
+ {
+ hb_rddSelectWorkAreaNumber( uiPrevArea );
+ hb_errRT_DBCMD( EG_ARG, EDBCMD_BADPARAMETER, NULL, HB_ERR_FUNCNAME );
+ return HB_FAILURE;
+ }
+ pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer();
+
+ /* Fill pInfo structure */
+ pInfo.uiArea = pArea->uiArea;
+ pInfo.abName = NULL;
+ pInfo.atomAlias = ( BYTE * ) szAlias;
+ pInfo.fShared = FALSE;
+ pInfo.fReadonly = FALSE;
+ pInfo.fTemporary = TRUE;
+ pInfo.cdpId = ( BYTE * ) szCpId;
+ pInfo.ulConnection = ulConnection;
+ pInfo.lpdbHeader = NULL;
+
+ if( pDelim && !HB_IS_NIL( pDelim ) )
+ errCode = SELF_INFO( pArea, DBI_SETDELIMITER, pDelim );
+ else
+ errCode = HB_SUCCESS;
+
+ if( errCode == HB_SUCCESS )
+ {
+ errCode = SELF_CREATEFIELDS( pArea, pStruct );
+ if( errCode == HB_SUCCESS )
+ errCode = SELF_CREATE( pArea, &pInfo );
+ }
+
+ if( errCode != HB_SUCCESS )
+ {
+ hb_rddReleaseCurrentArea();
+ hb_rddSelectWorkAreaNumber( uiPrevArea );
+ }
+
+ return errCode;
+}
+
static void hb_fldStructure( AREAP pArea, USHORT uiField, USHORT uiSize,
PHB_ITEM pField )
{
---
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour