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

Reply via email to