Базы данных WindowsCE
От: AntonGr  
Дата: 08.07.09 04:44
Оценка:
Здравствуйте, мне надо сделать в WindowsCE работу с базой данных. Я использую API функции типа CeOpenDatabaseEx2, CeCreateDatabaseEx2 и т.д. Вот на таком коде остановился сейчас.


CEDBASEINFOEX ceDBInfo;
CEGUID pceguid;
CEOID ceDB;

HANDLE OpenDB(wchar_t DBName[32])
{
    // Формируем имя создаваемой базы
    // Получаем хэндл выполняемого модуля
    HMODULE hModule = GetModuleHandle(NULL);
    // Вытаскиваем имя файла
    wchar_t wcFileName[64];
    DWORD dwFileNameLen = GetModuleFileName(hModule, wcFileName, 64);

    // Ищем где находится последний символ "/"
    for(int i=((int)dwFileNameLen-1); i>-1; i--)
        if(wcFileName[i] == 0x5c)
            dwFileNameLen = i;

    // Формируем имя создаваемой базы
    for(i=0; i<((int)wcslen(DBName)+1); i++)
        wcFileName[i+(int)dwFileNameLen+1] = DBName[i];
    
    // Добавляем расширение
    wcFileName[i++] = 0x2e;
    wcFileName[i++] = 0x63;
    wcFileName[i++] = 0x64;
    wcFileName[i++] = 0x62;
    wcFileName[i++] = 0x00;

    // Создаем ceguid который ни с кем не связан
    CREATE_INVALIDGUID(&pceguid);
    
    #ifdef _DEBUG
        DWORD dwErr;
    #endif

    // Монтируем том базы данных
    if(!CeMountDBVol(&pceguid,wcFileName,OPEN_ALWAYS))
    {
        #ifdef _DEBUG
            dwErr = GetLastError();
        #endif
        return INVALID_HANDLE_VALUE;
    }

    // Обнуляем память, которая хранит информацию о базе
    ZeroMemory(&ceDBInfo, sizeof(CEDBASEINFOEX));
    // Заносим некоторые параметры
    ceDBInfo.wVersion = 1;
    ceDBInfo.dwFlags = CEDB_VALIDNAME;
    //swprintf(ceDBInfo.szDbaseName, L"%s", wcFileName);
    swprintf(ceDBInfo.szDbaseName, L"\\test.cdb", wcFileName);    
    ceDBInfo.dwSize = sizeof(CEDBASEINFOEX);

    ceDB = 0;
    // Создаем базу
    ceDB = CeCreateDatabaseEx2(&pceguid,&ceDBInfo);
    #ifdef _DEBUG
        dwErr = GetLastError();
    #endif
    if(!ceDB && GetLastError() != ERROR_DUP_NAME)
    {
        #ifdef _DEBUG
            dwErr = GetLastError();
        #endif
        return INVALID_HANDLE_VALUE;
    }

    // Открываем базу для работы
    HANDLE hDB = INVALID_HANDLE_VALUE;
    //hDB = CeOpenDatabaseEx2(&pceguid,&ceDB,wcFileName,0,CEDB_AUTOINCREMENT,NULL);
    hDB = CeOpenDatabaseEx2(&pceguid,&ceDB,L"\\test.cdb",0,CEDB_AUTOINCREMENT,NULL);
    if(hDB == INVALID_HANDLE_VALUE)
    {
        #ifdef _DEBUG
            dwErr = GetLastError();
        #endif
        return INVALID_HANDLE_VALUE;
    }
    
    return hDB;
}

int main(int argc, char *argv[])
{
    HANDLE hDB = INVALID_HANDLE_VALUE;
    hDB = OpenDB(L"test");
    if((HANDLE)hDB != INVALID_HANDLE_VALUE)
        printf("DB opened.\n");
    else
    {
        printf("DB NOT opened.\n");
        return -1;
    }
    printf("%d\n" , ceDBInfo.dwNumRecords);

    //ceDB = (CEOID)SeekDB(hDB, CEDB_SEEK_BEGINNING, 0);
    //if(ceDB == NULL && GetLastError() != ERROR_SEEK)
    //    return -1;

    CEPROPVAL NewProp[2];
    NewProp[0].propid = CEVT_I2;
    //NewProp[0].wLenData = 0;
    //NewProp[0].wFlags = 0;
    NewProp[0].val.iVal = 11;
    NewProp[1].propid = CEVT_I2;
    //NewProp[1].wLenData = 0;
    //NewProp[1].wFlags = 0;
    NewProp[1].val.iVal = 12;
    ceDB = CeWriteRecordProps(hDB, 0, 2, NewProp);

    DWORD test = GetLastError();
    CloseHandle(hDB);

    //CeDeleteDatabaseEx(&pceguid,ceDB);

    test = GetLastError();

    return 0;
}


Указатель на базу возвращается нормально. Вообще вся функцмя OpenDB нормально работает, без ошибок, а вот после выполения ceDB = CeWriteRecordProps(hDB, 0, 2, NewProp) в переменную test попадает ошибка ERROR_MOD_NOT_FOUND(126). Подскажите, в чем может быть проблема. Может я чего-то не понял в работе с базой?
Re: Базы данных WindowsCE
От: Аноним  
Дата: 09.07.09 17:57
Оценка:
AG>а вот после выполения ceDB = CeWriteRecordProps(hDB, 0, 2, NewProp) в переменную test попадает ошибка ERROR_MOD_NOT_FOUND(126)
а в результате ceDB == 0 ?
Re[2]: Базы данных WindowsCE
От: AntonGr  
Дата: 28.07.09 05:31
Оценка:
Здравствуйте, Аноним, Вы писали:

AG>>а вот после выполения ceDB = CeWriteRecordProps(hDB, 0, 2, NewProp) в переменную test попадает ошибка ERROR_MOD_NOT_FOUND(126)

А>а в результате ceDB == 0 ?

Возвращается отличное от 0 значение.
Re: Базы данных WindowsCE
От: AntonGr  
Дата: 28.07.09 07:25
Оценка:
Попробовал исправить программу и начал все с начала с проверкой всех переменных. На данный момент вот какая картина. После функций показаны возвращаемые ими значения.

#pragma comment(linker,"/SUBSYSTEM:CONSOLE")
#pragma comment(linker,"/ENTRY:main")

#include <stdio.h>
//#include <afx.h>
//#include <afxdb.h>
#include <winbase.h>
#include <windows.h>

int main(int argc, char *argv[])
{
    BOOL bResult;    // Переменная для хранения результатов выполнения функций
    DWORD dwErr;    // Переменная для хранения ошибок

    //------ Монтируем volume для базы данных -------
    CEGUID cedbVol;                                            // Переменная для храннения идентификатора volume
    ZeroMemory(&cedbVol, sizeof(CEGUID));

    //CREATE_SYSTEMGUID(&cedbVol);    
    
    dwErr = 0;
    bResult = CeMountDBVol(&cedbVol, TEXT("sql.cdb"), OPEN_ALWAYS);    // 1
    dwErr = GetLastError();    // 0 или 183
    //bResult = CHECK_SYSTEMGUID(&cedbVol);    // 0

    if(bResult)
        printf("Volume mounted\n");
    else
    {
        printf("Volume not mounted\n");
        return -1;
    }
    // ----------------------------------------------

    // ------ Открываем базу по имени ---------------
    HANDLE hDB = INVALID_HANDLE_VALUE;
    CEOID ceoid = 0;
    dwErr = 0;
    hDB = CeOpenDatabaseEx2(&cedbVol, &ceoid, TEXT("settings"), NULL, 0, NULL);
    dwErr = GetLastError();    // 2 или 25
    if(hDB == INVALID_HANDLE_VALUE)    // Если база не открылась, то ее надо попробовать создать
    {
        // Создаем структуру для создания базы
        CEDBASEINFOEX cedbInfo;
        ZeroMemory(&cedbInfo, sizeof(CEDBASEINFOEX));
        cedbInfo.wVersion = 1;
        cedbInfo.dwFlags = CEDB_VALIDNAME;
        swprintf(cedbInfo.szDbaseName, L"%s", TEXT("settings"));
        cedbInfo.dwSize = 1024;

        // Создаем базу
        ceoid = 0;
        dwErr = 0;
        ceoid = CeCreateDatabaseEx2(&cedbVol, &cedbInfo);
        dwErr = GetLastError();    // 2 или 52
        if(ceoid != NULL)
            printf("DB created\n");
        else
        {
            printf("DB not created\n");
            return -1;
        }

        // Открываем созданную базу
        dwErr = 0;
        hDB = CeOpenDatabaseEx2(&cedbVol, &ceoid, TEXT("settigs"), NULL, 0, NULL);
        dwErr = GetLastError();    // 25
        if(hDB != INVALID_HANDLE_VALUE)
            printf("DB opened\n");
        else
        {
            printf("DB not opened\n");
            return -1;
        }
    } else    // Если все открылось
        printf("DB opened\n");
    // ----------------------------------------------

    //------ Демонтируем volume для базы данных -----
    dwErr = 0;
    bResult = CeUnmountDBVol(&cedbVol);    // 1
    dwErr = GetLastError();    // 25
    if(bResult)
        printf("Volume unmounted\n");
    else
    {
        printf("Volume not unmounted\n");
        return -1;
    }
    // ----------------------------------------------




    return 0;
}


Как видите всегда возникают какие-то ошибки, хотя функции вроде возвращают не ошибочные значения.
Re: Базы данных WindowsCE
От: AntonGr  
Дата: 19.08.09 11:05
Оценка:
С работой баз я рахобрался, но вот не понял, как реализуется работа с ней из нескольких потоков. Есть ли необходимость использовать объекты синхронизации или достаточно потоку передать указатель на идентификатор, который возвращается от функции CeMountDBVol, а дальше открывают базу и работают с ней они пусть сами, самостоятельно?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.