Open
Description
in esp32.cpp the comment for this function specifies this:
static int ESP32Open(
sqlite3_vfs *pVfs, /* VFS */
const char *zName, /* File to open, or 0 for a temp file */
however, this is not implemented in esp32:
if( zName==0 ){
return SQLITE_IOERR;
}
In some issues this was already mentioned, but i did not find a complete implementation/fix.
#55
#41
ive made a drop in replacement for esp32open that will generate a temporary file name and open that in w+ mode.
also, to overcome the problem that different filesystems have differents roots (like /sd) ive added parsing out the root dir when a .db file is opened. This way the temp files will always be in the same folder as the .db file. Also, the temp file is unlinked right away so does not have to be cleaned up / deleted on file closing as the sqlite library specifies. This is the function:
static char dbrootpath[MAXPATHNAME+1];
/*
** Open a file handle.
*/
static int ESP32Open(
sqlite3_vfs *pVfs, /* VFS */
const char *zName, /* File to open, or 0 for a temp file */
sqlite3_file *pFile, /* Pointer to ESP32File struct to populate */
int flags, /* Input SQLITE_OPEN_XXX flags */
int *pOutFlags /* Output SQLITE_OPEN_XXX flags (or NULL) */
){
static const sqlite3_io_methods ESP32io = {
1, /* iVersion */
ESP32Close, /* xClose */
ESP32Read, /* xRead */
ESP32Write, /* xWrite */
ESP32Truncate, /* xTruncate */
ESP32Sync, /* xSync */
ESP32FileSize, /* xFileSize */
ESP32Lock, /* xLock */
ESP32Unlock, /* xUnlock */
ESP32CheckReservedLock, /* xCheckReservedLock */
ESP32FileControl, /* xFileControl */
ESP32SectorSize, /* xSectorSize */
ESP32DeviceCharacteristics /* xDeviceCharacteristics */
};
ESP32File *p = (ESP32File*)pFile; /* Populate this structure */
int oflags = 0; /* flags to pass to open() call */
char *aBuf = 0;
char mode[5];
//Serial.println("fn: Open");
strcpy(mode, "r");
if( flags&SQLITE_OPEN_MAIN_JOURNAL ){
aBuf = (char *)sqlite3_malloc(SQLITE_ESP32VFS_BUFFERSZ);
if( !aBuf ){
return SQLITE_NOMEM;
}
}
if( flags&SQLITE_OPEN_CREATE || flags&SQLITE_OPEN_READWRITE
|| flags&SQLITE_OPEN_MAIN_JOURNAL ) {
struct stat st;
memset(&st, 0, sizeof(struct stat));
int rc = (zName == 0 ? -1 : stat( zName, &st ));
//Serial.println(zName);
if (rc < 0) {
strcpy(mode, "w+");
//int fd = open(zName, (O_CREAT | O_RDWR | O_EXCL), S_IRUSR | S_IWUSR);
//close(fd);
//oflags |= (O_CREAT | O_RDWR);
//Serial.println("Create mode");
} else
strcpy(mode, "r+");
}
memset(p, 0, sizeof(ESP32File));
//p->fd = open(zName, oflags, 0600);
//p->fd = open(zName, oflags, S_IRUSR | S_IWUSR);
if (zName == 0) {
//generate a temporary file name
char *tName = tmpnam(NULL);
tName[4] = '_';
size_t len = strlen(dbrootpath);
memmove(tName + len, tName, strlen(tName) + 1);
memcpy(tName, dbrootpath, len);
p->fp = fopen(tName, mode);
//https://stackoverflow.com/questions/64424287/how-to-delete-a-file-in-c-using-a-file-descriptor
//for temp file, then no need to handle in esp32close
unlink(tName);
//Serial.println("Temporary file name generated: " + String(tName) + " mode: " + String(mode));
}
else {
//detect database root as folder for temporary files, every newly openened db will change this path
//this mainly fixes that vfs's have their own root name like /sd
char *ext = strrchr(zName, '.');
bool isdb = false;
if (ext) {
isdb = (strcmp(ext+1,"db") == 0);
}
if (isdb) {
char zDir[MAXPATHNAME+1];
int i=0;
strcpy(zDir,zName);
for(i=1; zDir[i]!='/'; i++) {};
zDir[i] = '\0';
strcpy(dbrootpath, zDir);
}
p->fp = fopen(zName, mode);
}
if( p->fp<=0){
if (aBuf)
sqlite3_free(aBuf);
//Serial.println("Can't open");
return SQLITE_CANTOPEN;
}
p->aBuffer = aBuf;
if( pOutFlags ){
*pOutFlags = flags;
}
p->base.pMethods = &ESP32io;
//Serial.println("fn:Open:Success");
return SQLITE_OK;
}
Or should i open a pull request?
Metadata
Metadata
Assignees
Labels
No labels