Hello,
meanwhile i could reproduce my situation more precisely.
Short:
- create a memory db
- attach a file db
- backup memory db
 this fails.
Please watch my compile ready example (VS 2013) attached.
Thank you for help

Am 10.03.2016 um 21:56 schrieb R Smith:
>
>
> On 2016/03/10 10:41 PM, asdf asdf wrote:
>> Hello,
>> what do you mean, please ? What code is not shown:my own code (and what
>> could be the cause then) using the example or what i posted in
>> stackoverflow.
>>
>>   I would be happy to solve it. Any information appreciated-
>
> He means that there is something else that is wrong in your code that
> you've used to test this Backup feature. We cannot see your full code,
> so we do not know what is wrong with it, but we know something is
> wrong because the backup from memory works when we do it, and works
> when done like the example. You can easily use the command line
> SQLite3.exe tool to test it.
>
> So, if it works correctly for us, meaning it is not an SQLite bug, but
> there might be something in your code that is missing or weird and we
> would like to help you find it, however, only if you show us the exact
> code you've used to test with. Also the DB schema - some SQL perhaps
> to populate the in-memory database. Perhaps something about the schema
> is strange and causes the problem, then it might even be a bug - but
> we can't know that until we have exactly what you have.
>
> Thanks,
> Ryan
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

-------------- next part --------------
#include "stdafx.h"
#include "sqlite3.h"
#include <string>
#include <iostream>
#include <sstream> 


int backupDb(
  sqlite3 *pDb,               /* Database to back up */
  const char *zFilename,      /* Name of file to back up to */
  void(*xProgress)(int, int)  /* Progress function to invoke */     
){
  int rc;                     /* Function return code */
  sqlite3 *pFile;             /* Database connection opened on zFilename */
  sqlite3_backup *pBackup;    /* Backup handle used to copy data */

  /* Open the database file identified by zFilename. */
  rc = sqlite3_open(zFilename, &pFile);
  if( rc==SQLITE_OK ){

    /* Open the sqlite3_backup object used to accomplish the transfer */
    pBackup = sqlite3_backup_init(pFile, "main", pDb, "main");
    if( pBackup ){

      /* Each iteration of this loop copies 5 database pages from database
      ** pDb to the backup database. If the return value of backup_step()
      ** indicates that there are still further pages to copy, sleep for
      ** 250 ms before repeating. */
      do {
        rc = sqlite3_backup_step(pBackup, 5);
        if(xProgress != nullptr)
        {
            xProgress(
                sqlite3_backup_remaining(pBackup),
                sqlite3_backup_pagecount(pBackup)
                );
        }
        if( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
          sqlite3_sleep(5);
        }
      } while( rc==SQLITE_OK || rc==SQLITE_BUSY || rc==SQLITE_LOCKED );

      /* Release resources allocated by backup_init(). */
      (void)sqlite3_backup_finish(pBackup);
    }
    rc = sqlite3_errcode(pFile);
  }

  /* Close the database connection opened on database file zFilename
  ** and return the result of this function. */
  (void)sqlite3_close(pFile);
  return rc;
}

bool    do_select(sqlite3*    db, const std::string& sql, const std::string& 
comment = "")
{
    if (db == nullptr)
        std::cout << "\ndo_select: no database";;
    sqlite3_stmt* stmt = nullptr;

    std::cout << "\ndo_select("<<comment<<") <"<<sql<<">";

    int res = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, 0);
    if (res == SQLITE_OK)
    {
        /// cycle result rows
        do{
            res = sqlite3_step(stmt);
            int row = 0;
            int cols = sqlite3_column_count(stmt);
            switch (res)
            {
            case SQLITE_DONE:
            break;
            case SQLITE_ROW:
            {
                /// cycle result columns
                for (int col = 0; col < cols; col++)
                {
                    std::string sres = (const char*)sqlite3_column_text(stmt, 
0);
                    std::cout << "\n\t" <<"(" << row << "," << col << ") : " << 
sres.c_str();
                }
            }
            break;
            default:
            {
                sqlite3_finalize(stmt);

                std::cout << "\n\t"<< "sql error: " << sql.c_str();
                return false;
            }
            break;
            } /// switch
        } while (res == SQLITE_ROW);

        sqlite3_finalize(stmt);
        stmt = nullptr;
        return true;
    }
    else
    {
        sqlite3_finalize(stmt);
        std::cout << "\n\t" << "sql error: " << sql.c_str();

    }
    return false;
}

sqlite3*    create_db(const std::string& name,bool make_table_and_data)
{
    sqlite3*    db = nullptr;
    /// create memory db
    if (sqlite3_open(name.c_str(), &db) == SQLITE_OK)
    {
        if(make_table_and_data == false)
            return db;

        /// create table
        std::string sql = "CREATE TABLE [stock] ("
            "[sid] VARCHAR(40) UNIQUE NOT NULL PRIMARY KEY,"
            "[price] FLOAT "
            " ) ";


        char* db_err = nullptr;
        if (sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &db_err) == 
SQLITE_OK)
        {
            /// fill table with 10000 records
            for (int i = 0; i < 1000; i++)
            {
                std::ostringstream sstr;
                sstr << "INSERT INTO stock (sid,price) VALUES(";
                sstr << "'" << i << "',";
                sstr << (double) i / 7;
                sstr << ")";
                sql = sstr.str();

                if (sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &db_err) != 
SQLITE_OK)
                {
                    std::cout << "\nsql error: " << sql.c_str();
                    return nullptr;
                }
            }

            /// check we have content
            sqlite3_stmt* stmt = nullptr;
            do_select(db,"SELECT count(*) FROM stock",name);
        }
        else
        {
            std::cout << "\nsql error: " << sql.c_str();
            return nullptr;
        }
    }


    return db;
}

bool    attach_db_test_sqlite_mem(sqlite3*    dest,const std::string& 
dbfilename)
{
    if(dest != nullptr && dbfilename.length() > 0)
    {
        std::ostringstream sstr;
        sstr << "ATTACH DATABASE '";
        sstr << dbfilename.c_str();
        sstr << "' AS attached";
        std:: string sql = sstr.str();

        char* db_err = nullptr;
        if (sqlite3_exec(dest, sql.c_str(), nullptr, nullptr, &db_err) == 
SQLITE_OK)
            return true;
    }
    return false;
}
/// ******************************
/// working backup
bool    backup_test_sqlite_mem(void)
{
    sqlite3*    db =create_db(":memory:",true);

    /// do the backup
    int ibackup= backupDb(db,"memdb_file_backup.db",nullptr);

    /// set break here to check backup in explorer
    return true;
}

/// ******************************
/// failing backup
bool    backup_test_sqlite_mem2(void)
{
    /// create a file db
    sqlite3*    file_db =create_db("filedb.db",true);
    if(file_db != nullptr)
        sqlite3_close(file_db);

    /// we now have a database file

    /// create an empty mem db
    sqlite3*    mem_db=create_db(":memory:",false);

    /// attached prior created file to mem db
    attach_db_test_sqlite_mem(mem_db,"filedb.db");

    /// check we have content in mem db
    do_select(mem_db, "SELECT count(*) FROM stock","rows in 
backup_test_sqlite_mem2");

    /// finally back memdb
    int ibackup= backupDb(mem_db,"memdb_from_attached_backup.db",nullptr);

    /// the above backup is empty
    return (ibackup == SQLITE_OK ? true : false);
}
int main(int argc, _TCHAR* argv[])
{
    /// this memdb backup works fine
    backup_test_sqlite_mem();

    /// this memdb backup works not. The memdb prior to backup was filled by an 
attach command
    backup_test_sqlite_mem2();
        return 0;
}

Reply via email to