Ah, thanks for the tip. I'll have a look.

Steve

Simon Posnjak wrote:
Hi,

I do not now if you found it but there is another port of sqlite to
WinCE. You can find it at http://sqlite-wince.sourceforge.net/.
Would it be possible if your port and the sf port could be merged
together in main line src tree?

Regards Simon

On sre, 2006-01-04 at 10:13 -1000, Steve Lhomme wrote:

Hi everyone,

I'm a happy user of SQlite for a project I just started to make a multimedia database (a bit like the DB in iTunes). The idea is to make it as cross-platform as possible and free.

I tried to make it work under Windows CE but run into a few problems when compiling with Embedded Visual C++ 4. Although WinCE has a very similar API to Windows, it lacks some of the features.

- only the unicode API is present, so I disabled all the xxxA() API calls

- localtime() is defined but doesn't exist, so I coded one with the existing API

- LockFile(Ex) and UnlockFile(Ex) are not supported, only the Ex API is available on WinCE 5 but I need bigger support so I just made the code blank on WinCE. Is there any drawback to that ?

- FILE_ATTRIBUTE_TEMPORARY and FILE_FLAG_DELETE_ON_CLOSE are not supported for CreateFile. So I removed the flags for WinCE. But that means I have to delete the auto-deleting files on close. I modified the API to do that when calling sqlite3OsClose(). I realise changing the API is not so good, so calling sqlite3OsDelete() where the close is called could be a better option.

All of the changes are included in the following patch.

Steve

priloga plain text document (WinCE.patch)
Index: os.h
===================================================================
--- os.h        (revision 1)
+++ os.h        (working copy)
@@ -182,7 +182,7 @@
int sqlite3OsSyncDirectory(const char*);
int sqlite3OsTempFileName(char*);
int sqlite3OsIsDirWritable(char*);
-int sqlite3OsClose(OsFile*);
+int sqlite3OsClose(OsFile*, const char*);
int sqlite3OsRead(OsFile*, void*, int amt);
int sqlite3OsWrite(OsFile*, const void*, int amt);
int sqlite3OsSeek(OsFile*, i64 offset);
Index: os_unix.c
===================================================================
--- os_unix.c   (revision 1)
+++ os_unix.c   (working copy)
@@ -1278,7 +1278,7 @@
/*
** Close a file.
*/
-int sqlite3OsClose(OsFile *id){
+int sqlite3OsClose(OsFile *id, const char*){
  if( !id->isOpen ) return SQLITE_OK;
  if( CHECK_THREADID(id) ) return SQLITE_MISUSE;
  sqlite3OsUnlock(id, NO_LOCK);
Index: os_win.c
===================================================================
--- os_win.c    (revision 1)
+++ os_win.c    (working copy)
@@ -33,6 +33,64 @@
** Include code that is common to all os_*.c files
*/
#include "os_common.h"
+
+#if defined(_WIN32_WCE)
+#include <time.h>
+struct tm * __cdecl localtime(const time_t *t)
+{
+  static struct tm y;
+  FILETIME uTm, lTm;
+  SYSTEMTIME pTm;
+  uTm.dwLowDateTime = *t & 0xFFFFFFFF;
+  uTm.dwHighDateTime= *t >> 32;
+  FileTimeToLocalFileTime(&uTm,&lTm);
+  FileTimeToSystemTime(&lTm,&pTm);
+  y.tm_year = pTm.wYear - 1900;
+  y.tm_mon = pTm.wMonth - 1;
+  y.tm_wday = pTm.wDayOfWeek;
+  y.tm_mday = pTm.wDay;
+  y.tm_hour = pTm.wHour;
+  y.tm_min = pTm.wMinute;
+  y.tm_sec = pTm.wSecond;
+  return &y;
+}
+
+#ifndef LOCKFILE_EXCLUSIVE_LOCK
+#define LockFileEx(a,b,c,d,e,f) (1)
+#define UnlockFileEx(a,b,c,d,e) (1)
+#endif
+
+BOOL LockFile(
+  HANDLE hFile,
+  DWORD dwFileOffsetLow,
+  DWORD dwFileOffsetHigh,
+  DWORD nNumberOfBytesToLockLow,
+  DWORD nNumberOfBytesToLockHigh
+)
+{
+  OVERLAPPED ovlp;
+  ovlp.Offset = dwFileOffsetLow;
+  ovlp.OffsetHigh = dwFileOffsetHigh;
+  ovlp.hEvent = 0;
+  return LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 0, 
nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &ovlp);
+}
+
+
+BOOL UnlockFile(
+  HANDLE hFile,
+  DWORD dwFileOffsetLow,
+  DWORD dwFileOffsetHigh,
+  DWORD nNumberOfBytesToUnlockLow,
+  DWORD nNumberOfBytesToUnlockHigh
+)
+{
+  OVERLAPPED ovlp;
+  ovlp.Offset = dwFileOffsetLow;
+  ovlp.OffsetHigh = dwFileOffsetHigh;
+  ovlp.hEvent = 0;
+  return UnlockFileEx(hFile, 0, nNumberOfBytesToUnlockLow, 
nNumberOfBytesToUnlockHigh, &ovlp);
+}
+#endif

/*
** Do not include any of the File I/O interface procedures if the
@@ -66,14 +124,18 @@
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
-static int isNT(void){
+static int isNT(void){
+#if !defined(_WIN32_WCE)
  if( sqlite3_os_type==0 ){
    OSVERSIONINFO sInfo;
    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
    GetVersionEx(&sInfo);
    sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
  }
-  return sqlite3_os_type==2;
+  return sqlite3_os_type==2;
+#else
+  return 1;
+#endif
}

/*
@@ -131,9 +193,11 @@
  if( zWide ){
    DeleteFileW(zWide);
    sqliteFree(zWide);
+#if !defined(_WIN32_WCE)
  }else{
    DeleteFileA(zFilename);
-  }
+#endif
+  }
  TRACE2("DELETE \"%s\"\n", zFilename);
  return SQLITE_OK;
}
@@ -147,8 +211,10 @@
  if( zWide ){
    exists = GetFileAttributesW(zWide) != 0xffffffff;
    sqliteFree(zWide);
+#if !defined(_WIN32_WCE)
  }else{
-    exists = GetFileAttributesA(zFilename) != 0xffffffff;
+    exists = GetFileAttributesA(zFilename) != 0xffffffff;
+#endif
  }
  return exists;
}
@@ -201,6 +267,7 @@
      *pReadonly = 0;
    }
    sqliteFree(zWide);
+#if !defined(_WIN32_WCE)
  }else{
    h = CreateFileA(zFilename,
       GENERIC_READ | GENERIC_WRITE,
@@ -225,7 +292,8 @@
      *pReadonly = 1;
    }else{
      *pReadonly = 0;
-    }
+    }
+#endif
  }
  id->h = h;
  id->locktype = NO_LOCK;
@@ -257,8 +325,12 @@
  WCHAR *zWide = utf8ToUnicode(zFilename);
  assert( !id->isOpen );
  if( delFlag ){
- fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS - | FILE_FLAG_DELETE_ON_CLOSE;
+#if defined(_WIN32_WCE)
+    fileflags = FILE_FLAG_RANDOM_ACCESS;
+#else
+ fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS + | FILE_FLAG_DELETE_ON_CLOSE;
+#endif
  }else{
    fileflags = FILE_FLAG_RANDOM_ACCESS;
  }
@@ -271,7 +343,11 @@
       fileflags,
       NULL
    );
+#if defined(_WIN32_WCE)
+  SetFileAttributes(zWide, FILE_ATTRIBUTE_TEMPORARY);
+#endif
    sqliteFree(zWide);
+#if !defined(_WIN32_WCE)
  }else{
    h = CreateFileA(zFilename,
       GENERIC_READ | GENERIC_WRITE,
@@ -280,9 +356,10 @@
       CREATE_ALWAYS,
       fileflags,
       NULL
-    );
+    );
+#endif
  }
-  if( h==INVALID_HANDLE_VALUE ){
+  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
  }
  id->h = h;
@@ -315,6 +392,7 @@
       NULL
    );
    sqliteFree(zWide);
+#if !defined(_WIN32_WCE)
  }else{
    h = CreateFileA(zFilename,
       GENERIC_READ,
@@ -323,7 +401,8 @@
       OPEN_EXISTING,
       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
       NULL
-    );
+    );
+#endif
  }
  if( h==INVALID_HANDLE_VALUE ){
    return SQLITE_CANTOPEN;
@@ -381,7 +460,11 @@
  if( sqlite3_temp_directory ){
    strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
    zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
-  }else if( isNT() ){
+#if !defined(_WIN32_WCE)
+  }else if( !isNT() ){
+    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
+#endif
+  }else{
    char *zMulti;
    WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
    GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
@@ -391,8 +474,6 @@
      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
      sqliteFree(zMulti);
    }
-  }else{
-    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
  }
  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;
@@ -413,11 +494,18 @@
/*
** Close a file.
*/
-int sqlite3OsClose(OsFile *id){
+int sqlite3OsClose(OsFile *id, const char *FilePath){
  if( id->isOpen ){
    TRACE2("CLOSE %d\n", id->h);
    CloseHandle(id->h);
-    OpenCounter(-1);
+    OpenCounter(-1);
+#if defined(_WIN32_WCE)
+       {
+               WCHAR *path = utf8ToUnicode(FilePath);
+               DeleteFile(path);
+               sqliteFree(path);
+       }
+#endif
    id->isOpen = 0;
  }
  return SQLITE_OK;
@@ -556,7 +644,7 @@
    int lk;
    sqlite3Randomness(sizeof(lk), &lk);
    id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
-    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
+    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
  }
  return res;
}
@@ -565,12 +653,12 @@
** Undo a readlock
*/
static int unlockReadLock(OsFile *id){
-  int res;
+  int res;
  if( isNT() ){
    res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
  }else{
    res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
-  }
+  }
  return res;
}

@@ -588,8 +676,10 @@
  if( zWide ){
    fileAttr = GetFileAttributesW(zWide);
    sqliteFree(zWide);
+#if !defined(_WIN32_WCE)
  }else{
-    fileAttr = GetFileAttributesA(zDirname);
+    fileAttr = GetFileAttributesA(zDirname);
+#endif
  }
  if( fileAttr == 0xffffffff ) return 0;
  if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
@@ -800,7 +890,7 @@
*/
char *sqlite3OsFullPathname(const char *zRelative){
  char *zNotUsed;
-  char *zFull;
+  char *zFull=0;
  WCHAR *zWide;
  int nByte;
#ifdef __CYGWIN__
@@ -808,7 +898,7 @@
  zFull = sqliteMalloc( nByte );
  if( zFull==0 ) return 0;
  if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
-#else
+#elif !defined(_WIN32_WCE)
  zWide = utf8ToUnicode(zRelative);
  if( zWide ){
    WCHAR *zTemp, *zNotUsedW;
@@ -823,8 +913,13 @@
    nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
    zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
    if( zFull==0 ) return 0;
-    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
+    GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
  }
+#else
+  nByte = strlen(zRelative)+1;
+  zFull = sqliteMalloc(nByte);
+  if (zFull)
+         memcpy(zFull,zRelative,nByte);
#endif
  return zFull;
}
@@ -919,14 +1014,20 @@
** Find the current time (in Universal Coordinated Time).  Write the
** current time and date as a Julian Day number into *prNow and
** return 0.  Return 1 if the time and date cannot be found.
-*/
+*/
int sqlite3OsCurrentTime(double *prNow){
  FILETIME ft;
/* FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */
  double now;
-  GetSystemTimeAsFileTime( &ft );
+#if defined(_WIN32_WCE)
+  SYSTEMTIME time;
+  GetSystemTime(&time);
+  SystemTimeToFileTime(&time,&ft);
+#else
+  GetSystemTimeAsFileTime( &ft );
+#endif
now = ((double)ft.dwHighDateTime) * 4294967296.0; *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
#ifdef SQLITE_TEST
@@ -935,6 +1036,6 @@
  }
#endif
  return 0;
-}
+}

#endif /* OS_WIN */
Index: pager.c
===================================================================
--- pager.c     (revision 1)
+++ pager.c     (working copy)
@@ -907,11 +907,11 @@
  }
  sqlite3pager_stmt_commit(pPager);
  if( pPager->stmtOpen ){
-    sqlite3OsClose(&pPager->stfd);
+    sqlite3OsClose(&pPager->stfd, pPager->zFilename);
    pPager->stmtOpen = 0;
  }
  if( pPager->journalOpen ){
-    sqlite3OsClose(&pPager->jfd);
+         sqlite3OsClose(&pPager->jfd, pPager->tempFile?pPager->zFilename:NULL);
    pPager->journalOpen = 0;
    sqlite3OsDelete(pPager->zJournal);
    sqliteFree( pPager->aInJournal );
@@ -1128,7 +1128,7 @@
        }

        rc = readMasterJournal(&journal, &zMasterPtr);
-        sqlite3OsClose(&journal);
+        sqlite3OsClose(&journal, NULL);
        if( rc!=SQLITE_OK ){
          goto delmaster_out;
        }
@@ -1151,7 +1151,7 @@
    sqliteFree(zMasterJournal);
} if( master_open ){
-    sqlite3OsClose(&master);
+    sqlite3OsClose(&master, NULL);
  }
  return rc;
}
@@ -1633,18 +1633,18 @@
    }
  }
  if( !zFullPathname ){
-    sqlite3OsClose(&fd);
+    sqlite3OsClose(&fd, zFilename);
    return SQLITE_NOMEM;
  }
  if( rc!=SQLITE_OK ){
-    sqlite3OsClose(&fd);
+    sqlite3OsClose(&fd, zFilename);
    sqliteFree(zFullPathname);
    return rc;
  }
  nameLen = strlen(zFullPathname);
  pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
  if( pPager==0 ){
-    sqlite3OsClose(&fd);
+    sqlite3OsClose(&fd, zFilename);
    sqliteFree(zFullPathname);
    return SQLITE_NOMEM;
  }
@@ -2002,13 +2002,13 @@
  TRACE2("CLOSE %d\n", PAGERID(pPager));
  assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
  if( pPager->journalOpen ){
-    sqlite3OsClose(&pPager->jfd);
+         sqlite3OsClose(&pPager->jfd, pPager->tempFile?pPager->zJournal:NULL);
  }
  sqliteFree(pPager->aInJournal);
  if( pPager->stmtOpen ){
-    sqlite3OsClose(&pPager->stfd);
+    sqlite3OsClose(&pPager->stfd, pPager->zFilename);
  }
-  sqlite3OsClose(&pPager->fd);
+  sqlite3OsClose(&pPager->fd, NULL);
  /* Temp files are automatically deleted by the OS
  ** if( pPager->tempFile ){
  **   sqlite3OsDelete(pPager->zFilename);
Index: vdbeaux.c
===================================================================
--- vdbeaux.c   (revision 1)
+++ vdbeaux.c   (working copy)
@@ -1003,7 +1003,7 @@
        }
        rc = sqlite3OsWrite(&master, zFile, strlen(zFile)+1);
        if( rc!=SQLITE_OK ){
-          sqlite3OsClose(&master);
+          sqlite3OsClose(&master, 0);
          sqlite3OsDelete(zMaster);
          sqliteFree(zMaster);
          return rc;
@@ -1019,7 +1019,7 @@
    rc = sqlite3OsOpenDirectory(zMainFile, &master);
    if( rc!=SQLITE_OK ||
          (needSync && (rc=sqlite3OsSync(&master,0))!=SQLITE_OK) ){
-      sqlite3OsClose(&master);
+      sqlite3OsClose(&master, 0);
      sqlite3OsDelete(zMaster);
      sqliteFree(zMaster);
      return rc;
@@ -1040,13 +1040,13 @@
      if( pBt && sqlite3BtreeIsInTrans(pBt) ){
        rc = sqlite3BtreeSync(pBt, zMaster);
        if( rc!=SQLITE_OK ){
-          sqlite3OsClose(&master);
+          sqlite3OsClose(&master, 0);
          sqliteFree(zMaster);
          return rc;
        }
      }
    }
-    sqlite3OsClose(&master);
+    sqlite3OsClose(&master, 0);

    /* Delete the master journal file. This commits the transaction. After
    ** doing this the directory is synced again before any individual




--
robUx4 on blog <http://robux4.blogspot.com/>

Reply via email to