/ Check-in [4590e433]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enable the use of shared cache for an in-memory database, so that separate database connections can share the same in-memory database.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | shared-cache-memdb
Files: files | file ages | folders
SHA1:4590e433f2a595bb80fb061024b0a3d2ca25b7b2
User & Date: drh 2012-05-26 18:06:38
Context
2012-05-26
20:08
Only allow :memory: databases to share cache if there are created using a URI filename. This minimizes the risk of breakages in legacy applications that have shared-cache enabled but also use :memory: databases which they expect to keep separate. check-in: e3ad61e0 user: drh tags: shared-cache-memdb
18:06
Enable the use of shared cache for an in-memory database, so that separate database connections can share the same in-memory database. check-in: 4590e433 user: drh tags: shared-cache-memdb
2012-05-22
02:45
Version 3.7.12.1 check-in: 6d326d44 user: drh tags: trunk, release, version-3.7.12.1
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769



1770

1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  if( isMemdb==0 && isTempDb==0 ){
    if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
      int nFullPathname = pVfs->mxPathname+1;
      char *zFullPathname = sqlite3Malloc(nFullPathname);
      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
      p->sharable = 1;
      if( !zFullPathname ){
        sqlite3_free(p);
        return SQLITE_NOMEM;
      }



      rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);

      if( rc ){
        sqlite3_free(zFullPathname);
        sqlite3_free(p);
        return rc;

      }
#if SQLITE_THREADSAFE
      mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
      sqlite3_mutex_enter(mutexOpen);
      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
      sqlite3_mutex_enter(mutexShared);
#endif







|









>
>
>
|
>
|
|
|
|
>







1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
#endif

#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  /*
  ** If this Btree is a candidate for shared cache, try to find an
  ** existing BtShared object that we can share with
  */
  if( isTempDb==0 ){
    if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
      int nFullPathname = pVfs->mxPathname+1;
      char *zFullPathname = sqlite3Malloc(nFullPathname);
      MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
      p->sharable = 1;
      if( !zFullPathname ){
        sqlite3_free(p);
        return SQLITE_NOMEM;
      }
      if( isMemdb ){
        memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
      }else{
        rc = sqlite3OsFullPathname(pVfs, zFilename,
                                   nFullPathname, zFullPathname);
        if( rc ){
          sqlite3_free(zFullPathname);
          sqlite3_free(p);
          return rc;
        }
      }
#if SQLITE_THREADSAFE
      mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
      sqlite3_mutex_enter(mutexOpen);
      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
      sqlite3_mutex_enter(mutexShared);
#endif

Changes to src/pager.c.

4356
4357
4358
4359
4360
4361
4362


4363
4364
4365
4366
4367
4368
4369
....
6739
6740
6741
6742
6743
6744
6745

6746
6747
6748
6749
6750
6751
6752
6753

  /* Set the output variable to NULL in case an error occurs. */
  *ppPager = 0;

#ifndef SQLITE_OMIT_MEMORYDB
  if( flags & PAGER_MEMORY ){
    memDb = 1;


    zFilename = 0;
  }
#endif

  /* Compute and store the full pathname in an allocated buffer pointed
  ** to by zPathname, length nPathname. Or, if this is a temporary file,
  ** leave both nPathname and zPathname set to 0.
................................................................................

/*
** Return true if the underlying VFS for the given pager supports the
** primitives necessary for write-ahead logging.
*/
int sqlite3PagerWalSupported(Pager *pPager){
  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;

  return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
}

/*
** Attempt to take an exclusive lock on the database file. If a PENDING lock
** is obtained instead, immediately release it.
*/
static int pagerExclusiveLock(Pager *pPager){







>
>







 







>
|







4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
....
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756

  /* Set the output variable to NULL in case an error occurs. */
  *ppPager = 0;

#ifndef SQLITE_OMIT_MEMORYDB
  if( flags & PAGER_MEMORY ){
    memDb = 1;
    zPathname = sqlite3DbStrDup(0, zFilename);
    nPathname = sqlite3Strlen30(zPathname);
    zFilename = 0;
  }
#endif

  /* Compute and store the full pathname in an allocated buffer pointed
  ** to by zPathname, length nPathname. Or, if this is a temporary file,
  ** leave both nPathname and zPathname set to 0.
................................................................................

/*
** Return true if the underlying VFS for the given pager supports the
** primitives necessary for write-ahead logging.
*/
int sqlite3PagerWalSupported(Pager *pPager){
  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
  return pPager->memDb==0 && 
        (pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap));
}

/*
** Attempt to take an exclusive lock on the database file. If a PENDING lock
** is obtained instead, immediately release it.
*/
static int pagerExclusiveLock(Pager *pPager){

Changes to test/attach.test.

853
854
855
856
857
858
859
860
861
862
    SELECT name FROM inmem.sqlite_master;
  }
} {noname inmem}
do_test attach-10.2 {
  lrange [execsql {
    PRAGMA database_list;
  }] 9 end
} {4 noname {} 5 inmem {}}

finish_test







|


853
854
855
856
857
858
859
860
861
862
    SELECT name FROM inmem.sqlite_master;
  }
} {noname inmem}
do_test attach-10.2 {
  lrange [execsql {
    PRAGMA database_list;
  }] 9 end
} {4 noname {} 5 inmem :memory:}

finish_test

Changes to test/shared.test.

1052
1053
1054
1055
1056
1057
1058







1059


1060













1061
1062
} {1 2 6 8 9 12 1 2 5 11 12 14 1 2 4}
do_test shared-$av-15.2 {
  execsql { DROP TABLE t1 } db2
} {}
db close
db2 close








}
















sqlite3_enable_shared_cache $::enable_shared_cache
finish_test







>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>


1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
} {1 2 6 8 9 12 1 2 5 11 12 14 1 2 4}
do_test shared-$av-15.2 {
  execsql { DROP TABLE t1 } db2
} {}
db close
db2 close

# Shared cache on a :memory: database.
#
do_test shared-$av-16.1 {
  sqlite3 db1 :memory:
  sqlite3 db2 :memory:
  db1 eval {
    CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
  }
  db2 eval {
    SELECT x FROM t1 ORDER BY x;
  }
} {1 2 3}
do_test shared-$av-16.2 {
  db2 eval {
    INSERT INTO t1 VALUES(99);
    DELETE FROM t1 WHERE x=2;
  }
  db1 eval {
    SELECT x FROM t1 ORDER BY x;
  }
} {1 3 99}

}  ;# end of autovacuum on/off loop

sqlite3_enable_shared_cache $::enable_shared_cache
finish_test