[lxc-devel] [lxd/master] Move db*.go files into their own store/ sub-package

freeekanayaka on Github lxc-bot at linuxcontainers.org
Wed Aug 16 15:56:05 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1019 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170816/5a742203/attachment.bin>
-------------- next part --------------
From 9a8fa6759af1f5bcd04fc38fe80f6e266fd496c9 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Wed, 16 Aug 2017 15:20:39 +0000
Subject: [PATCH] Move db*.go files into their own store/ sub-package

This branch is very large but almost completely mechanical. It moves
all db-related code into a standalone subpackage (store). This
facilitates testing and makes further refactoring easier to reason
about. Intially the new sub-package was named "db/", but then I went
for "store/" since "db" collides with the idiomatic variable name of a
sql.DB instance. I still have the branch that names it "db/", if it's
preferred for some reason.

The only point worth mentioning is that containerArgs and
storagePoolVolumeTypeToName had to be moved to the db package, to
avoid circular dependencies. We will probably want to clean that up
down the road.

Signed-off-by: Free Ekanayaka <free.ekanayaka at canonical.com>
---
 lxd/api_1.0.go                                     |   5 +-
 lxd/api_internal.go                                |  43 ++--
 lxd/certificates.go                                |  17 +-
 lxd/container.go                                   |  58 ++---
 lxd/container_lxc.go                               |  91 +++----
 lxd/container_patch.go                             |   3 +-
 lxd/container_post.go                              |   3 +-
 lxd/container_put.go                               |   3 +-
 lxd/container_snapshot.go                          |  11 +-
 lxd/container_state.go                             |   3 +-
 lxd/container_test.go                              |  69 +++---
 lxd/containers.go                                  |   9 +-
 lxd/containers_get.go                              |   5 +-
 lxd/containers_post.go                             |  41 ++--
 lxd/daemon.go                                      |  23 +-
 lxd/daemon_config.go                               |   5 +-
 lxd/daemon_images.go                               |  19 +-
 lxd/daemon_images_test.go                          |   7 +-
 lxd/devices.go                                     |   7 +-
 lxd/devlxd.go                                      |   3 +-
 lxd/images.go                                      | 111 ++++-----
 lxd/main_activateifneeded.go                       |   3 +-
 lxd/main_test.go                                   |   9 +-
 lxd/networks.go                                    |  25 +-
 lxd/networks_utils.go                              |   9 +-
 lxd/patches.go                                     | 266 +++++++++++----------
 lxd/profiles.go                                    |  23 +-
 lxd/profiles_test.go                               |  10 +-
 lxd/profiles_utils.go                              |  21 +-
 lxd/response.go                                    |   5 +-
 lxd/storage.go                                     |  11 +-
 lxd/storage_btrfs.go                               |   7 +-
 lxd/storage_ceph.go                                |   5 +-
 lxd/storage_ceph_migration.go                      |   3 +-
 lxd/storage_ceph_utils.go                          |  15 +-
 lxd/storage_dir.go                                 |   3 +-
 lxd/storage_lvm.go                                 |   5 +-
 lxd/storage_lvm_utils.go                           |   5 +-
 lxd/storage_migration.go                           |   7 +-
 lxd/storage_pools.go                               |  21 +-
 lxd/storage_pools_utils.go                         |  65 ++++-
 lxd/storage_shared.go                              |   5 +-
 lxd/storage_utils.go                               |   7 +-
 lxd/storage_volumes.go                             |  25 +-
 lxd/storage_volumes_utils.go                       |  47 ++--
 lxd/storage_zfs.go                                 |   3 +-
 lxd/{db_certificates.go => store/certificates.go}  |  40 ++--
 lxd/{db_config.go => store/config.go}              |  10 +-
 lxd/{db_containers.go => store/containers.go}      | 121 ++++++----
 lxd/{ => store}/db.go                              |  44 ++--
 lxd/{ => store}/db_test.go                         |  82 +++----
 lxd/{db_devices.go => store/devices.go}            |  10 +-
 lxd/{db_images.go => store/images.go}              |  94 ++++----
 lxd/{db_networks.go => store/networks.go}          |  64 ++---
 lxd/{db_patches.go => store/patches.go}            |   8 +-
 lxd/{db_profiles.go => store/profiles.go}          |  58 ++---
 .../storage_pools.go}                              | 179 +++++++-------
 .../storage_volumes.go}                            |  14 +-
 lxd/{db_update.go => store/update.go}              |  10 +-
 59 files changed, 989 insertions(+), 886 deletions(-)
 rename lxd/{db_certificates.go => store/certificates.go} (65%)
 rename lxd/{db_config.go => store/config.go} (81%)
 rename lxd/{db_containers.go => store/containers.go} (72%)
 rename lxd/{ => store}/db.go (93%)
 rename lxd/{ => store}/db_test.go (85%)
 rename lxd/{db_devices.go => store/devices.go} (92%)
 rename lxd/{db_images.go => store/images.go} (76%)
 rename lxd/{db_networks.go => store/networks.go} (70%)
 rename lxd/{db_patches.go => store/patches.go} (71%)
 rename lxd/{db_profiles.go => store/profiles.go} (72%)
 rename lxd/{db_storage_pools.go => store/storage_pools.go} (59%)
 rename lxd/{db_storage_volumes.go => store/storage_volumes.go} (75%)
 rename lxd/{db_update.go => store/update.go} (98%)

diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index f6c7e5491..777999dd9 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -10,6 +10,7 @@ import (
 
 	"gopkg.in/lxc/go-lxc.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/osarch"
@@ -242,7 +243,7 @@ func api10Get(d *Daemon, r *http.Request) Response {
 }
 
 func api10Put(d *Daemon, r *http.Request) Response {
-	oldConfig, err := dbConfigValuesGet(d.db)
+	oldConfig, err := store.ConfigValuesGet(d.db)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -261,7 +262,7 @@ func api10Put(d *Daemon, r *http.Request) Response {
 }
 
 func api10Patch(d *Daemon, r *http.Request) Response {
-	oldConfig, err := dbConfigValuesGet(d.db)
+	oldConfig, err := store.ConfigValuesGet(d.db)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 09c49da3f..6130ad11c 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -12,6 +12,7 @@ import (
 	"github.com/gorilla/mux"
 	"gopkg.in/yaml.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -190,9 +191,9 @@ func internalImport(d *Daemon, r *http.Request) Response {
 
 	// Try to retrieve the storage pool the container supposedly lives on.
 	var poolErr error
-	poolID, pool, poolErr := dbStoragePoolGet(d.db, containerPoolName)
+	poolID, pool, poolErr := store.StoragePoolGet(d.db, containerPoolName)
 	if poolErr != nil {
-		if poolErr != NoSuchObjectError {
+		if poolErr != store.NoSuchObjectError {
 			return SmartError(poolErr)
 		}
 	}
@@ -202,14 +203,14 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("No storage pool struct in the backup file found. The storage pool needs to be recovered manually."))
 	}
 
-	if poolErr == NoSuchObjectError {
+	if poolErr == store.NoSuchObjectError {
 		// Create the storage pool db entry if it doesn't exist.
 		err := storagePoolDBCreate(d, containerPoolName, "", backup.Pool.Driver, backup.Pool.Config)
 		if err != nil {
 			return SmartError(err)
 		}
 
-		poolID, err = dbStoragePoolGetID(d.db, containerPoolName)
+		poolID, err = store.StoragePoolGetID(d.db, containerPoolName)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -224,9 +225,9 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	}
 
 	// Check if a storage volume entry for the container already exists.
-	_, volume, ctVolErr := dbStoragePoolVolumeGetType(d.db, req.Name, storagePoolVolumeTypeContainer, poolID)
+	_, volume, ctVolErr := store.StoragePoolVolumeGetType(d.db, req.Name, storagePoolVolumeTypeContainer, poolID)
 	if ctVolErr != nil {
-		if ctVolErr != NoSuchObjectError {
+		if ctVolErr != store.NoSuchObjectError {
 			return SmartError(ctVolErr)
 		}
 	}
@@ -236,7 +237,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	}
 
 	// Check if an entry for the container already exists in the db.
-	_, containerErr := dbContainerId(d.db, req.Name)
+	_, containerErr := store.ContainerId(d.db, req.Name)
 	if containerErr != nil {
 		if containerErr != sql.ErrNoRows {
 			return SmartError(containerErr)
@@ -288,7 +289,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		onDiskSnapshots[snap.Name] = snap
 
 		// Check if an entry for the snapshot already exists in the db.
-		_, snapErr := dbContainerId(d.db, snap.Name)
+		_, snapErr := store.ContainerId(d.db, snap.Name)
 		if snapErr != nil {
 			if snapErr != sql.ErrNoRows {
 				return SmartError(snapErr)
@@ -301,9 +302,9 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		}
 
 		// Check if a storage volume entry for the snapshot already exists.
-		_, _, snapVolErr := dbStoragePoolVolumeGetType(d.db, snap.Name, storagePoolVolumeTypeContainer, poolID)
+		_, _, snapVolErr := store.StoragePoolVolumeGetType(d.db, snap.Name, storagePoolVolumeTypeContainer, poolID)
 		if snapVolErr != nil {
-			if snapVolErr != NoSuchObjectError {
+			if snapVolErr != store.NoSuchObjectError {
 				return SmartError(snapVolErr)
 			}
 		}
@@ -329,7 +330,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 
 		// Remove the storage volume db entry for the container since
 		// force was specified.
-		err := dbStoragePoolVolumeDelete(d.db, req.Name, storagePoolVolumeTypeContainer, poolID)
+		err := store.StoragePoolVolumeDelete(d.db, req.Name, storagePoolVolumeTypeContainer, poolID)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -338,7 +339,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	if containerErr == nil {
 		// Remove the storage volume db entry for the container since
 		// force was specified.
-		err := dbContainerRemove(d.db, req.Name)
+		err := store.ContainerRemove(d.db, req.Name)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -350,13 +351,13 @@ func internalImport(d *Daemon, r *http.Request) Response {
 	if err != nil {
 		return SmartError(err)
 	}
-	_, err = containerCreateInternal(d, containerArgs{
+	_, err = containerCreateInternal(d, store.ContainerArgs{
 		Architecture: arch,
 		BaseImage:    baseImage,
 		Config:       backup.Container.Config,
 		CreationDate: backup.Container.CreatedAt,
 		LastUsedDate: backup.Container.LastUsedAt,
-		Ctype:        cTypeRegular,
+		Ctype:        store.CTypeRegular,
 		Devices:      backup.Container.Devices,
 		Ephemeral:    backup.Container.Ephemeral,
 		Name:         backup.Container.Name,
@@ -369,7 +370,7 @@ func internalImport(d *Daemon, r *http.Request) Response {
 
 	for snapName, snap := range onDiskSnapshots {
 		// Check if an entry for the snapshot already exists in the db.
-		_, snapErr := dbContainerId(d.db, snapName)
+		_, snapErr := store.ContainerId(d.db, snapName)
 		if snapErr != nil {
 			if snapErr != sql.ErrNoRows {
 				return SmartError(snapErr)
@@ -382,9 +383,9 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		}
 
 		// Check if a storage volume entry for the snapshot already exists.
-		_, _, csVolErr := dbStoragePoolVolumeGetType(d.db, snapName, storagePoolVolumeTypeContainer, poolID)
+		_, _, csVolErr := store.StoragePoolVolumeGetType(d.db, snapName, storagePoolVolumeTypeContainer, poolID)
 		if csVolErr != nil {
-			if csVolErr != NoSuchObjectError {
+			if csVolErr != store.NoSuchObjectError {
 				return SmartError(csVolErr)
 			}
 		}
@@ -395,14 +396,14 @@ func internalImport(d *Daemon, r *http.Request) Response {
 		}
 
 		if snapErr == nil {
-			err := dbContainerRemove(d.db, snapName)
+			err := store.ContainerRemove(d.db, snapName)
 			if err != nil {
 				return SmartError(err)
 			}
 		}
 
 		if csVolErr == nil {
-			err := dbStoragePoolVolumeDelete(d.db, snapName, storagePoolVolumeTypeContainer, poolID)
+			err := store.StoragePoolVolumeDelete(d.db, snapName, storagePoolVolumeTypeContainer, poolID)
 			if err != nil {
 				return SmartError(err)
 			}
@@ -431,13 +432,13 @@ func internalImport(d *Daemon, r *http.Request) Response {
 			return SmartError(err)
 		}
 
-		_, err = containerCreateInternal(d, containerArgs{
+		_, err = containerCreateInternal(d, store.ContainerArgs{
 			Architecture: arch,
 			BaseImage:    baseImage,
 			Config:       snap.Config,
 			CreationDate: snap.CreationDate,
 			LastUsedDate: snap.LastUsedDate,
-			Ctype:        cTypeSnapshot,
+			Ctype:        store.CTypeSnapshot,
 			Devices:      snap.Devices,
 			Ephemeral:    snap.Ephemeral,
 			Name:         snapName,
diff --git a/lxd/certificates.go b/lxd/certificates.go
index 6154b8be1..a0b765aea 100644
--- a/lxd/certificates.go
+++ b/lxd/certificates.go
@@ -11,6 +11,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -23,7 +24,7 @@ func certificatesGet(d *Daemon, r *http.Request) Response {
 	if recursion {
 		certResponses := []api.Certificate{}
 
-		baseCerts, err := dbCertsGet(d.db)
+		baseCerts, err := store.CertsGet(d.db)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -53,7 +54,7 @@ func certificatesGet(d *Daemon, r *http.Request) Response {
 func readSavedClientCAList(d *Daemon) {
 	d.clientCerts = []x509.Certificate{}
 
-	dbCerts, err := dbCertsGet(d.db)
+	dbCerts, err := store.CertsGet(d.db)
 	if err != nil {
 		logger.Infof("Error reading certificates from database: %s", err)
 		return
@@ -76,7 +77,7 @@ func readSavedClientCAList(d *Daemon) {
 }
 
 func saveCert(d *Daemon, host string, cert *x509.Certificate) error {
-	baseCert := new(dbCertInfo)
+	baseCert := new(store.CertInfo)
 	baseCert.Fingerprint = shared.CertFingerprint(cert)
 	baseCert.Type = 1
 	baseCert.Name = host
@@ -84,7 +85,7 @@ func saveCert(d *Daemon, host string, cert *x509.Certificate) error {
 		pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}),
 	)
 
-	return dbCertSave(d.db, baseCert)
+	return store.CertSave(d.db, baseCert)
 }
 
 func certificatesPost(d *Daemon, r *http.Request) Response {
@@ -166,7 +167,7 @@ func certificateFingerprintGet(d *Daemon, r *http.Request) Response {
 func doCertificateGet(d *Daemon, fingerprint string) (api.Certificate, error) {
 	resp := api.Certificate{}
 
-	dbCertInfo, err := dbCertGet(d.db, fingerprint)
+	dbCertInfo, err := store.CertGet(d.db, fingerprint)
 	if err != nil {
 		return resp, err
 	}
@@ -245,7 +246,7 @@ func doCertificateUpdate(d *Daemon, fingerprint string, req api.CertificatePut)
 		return BadRequest(fmt.Errorf("Unknown request type %s", req.Type))
 	}
 
-	err := dbCertUpdate(d.db, fingerprint, req.Name, 1)
+	err := store.CertUpdate(d.db, fingerprint, req.Name, 1)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -256,12 +257,12 @@ func doCertificateUpdate(d *Daemon, fingerprint string, req api.CertificatePut)
 func certificateFingerprintDelete(d *Daemon, r *http.Request) Response {
 	fingerprint := mux.Vars(r)["fingerprint"]
 
-	certInfo, err := dbCertGet(d.db, fingerprint)
+	certInfo, err := store.CertGet(d.db, fingerprint)
 	if err != nil {
 		return NotFound
 	}
 
-	err = dbCertDelete(d.db, certInfo.Fingerprint)
+	err = store.CertDelete(d.db, certInfo.Fingerprint)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/container.go b/lxd/container.go
index a601c5270..09964a750 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -11,6 +11,7 @@ import (
 
 	"gopkg.in/lxc/go-lxc.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -338,7 +339,7 @@ func containerValidDevices(d *Daemon, devices types.Devices, profile bool, expan
 					return fmt.Errorf("Storage volumes cannot be specified as absolute paths.")
 				}
 
-				_, err := dbStoragePoolGetID(d.db, m["pool"])
+				_, err := store.StoragePoolGetID(d.db, m["pool"])
 				if err != nil {
 					return fmt.Errorf("The \"%s\" storage pool doesn't exist.", m["pool"])
 				}
@@ -396,25 +397,6 @@ func containerValidDevices(d *Daemon, devices types.Devices, profile bool, expan
 	return nil
 }
 
-// The container arguments
-type containerArgs struct {
-	// Don't set manually
-	Id int
-
-	Description  string
-	Architecture int
-	BaseImage    string
-	Config       map[string]string
-	CreationDate time.Time
-	LastUsedDate time.Time
-	Ctype        containerType
-	Devices      types.Devices
-	Ephemeral    bool
-	Name         string
-	Profiles     []string
-	Stateful     bool
-}
-
 // The container interface
 type container interface {
 	// Container actions
@@ -434,7 +416,7 @@ type container interface {
 
 	// Config handling
 	Rename(newName string) error
-	Update(newConfig containerArgs, userRequested bool) error
+	Update(newConfig store.ContainerArgs, userRequested bool) error
 
 	Delete() error
 	Export(w io.Writer, properties map[string]string) error
@@ -516,7 +498,7 @@ type container interface {
 }
 
 // Loader functions
-func containerCreateAsEmpty(d *Daemon, args containerArgs) (container, error) {
+func containerCreateAsEmpty(d *Daemon, args store.ContainerArgs) (container, error) {
 	// Create the container
 	c, err := containerCreateInternal(d, args)
 	if err != nil {
@@ -539,7 +521,7 @@ func containerCreateAsEmpty(d *Daemon, args containerArgs) (container, error) {
 	return c, nil
 }
 
-func containerCreateEmptySnapshot(d *Daemon, args containerArgs) (container, error) {
+func containerCreateEmptySnapshot(d *Daemon, args store.ContainerArgs) (container, error) {
 	// Create the snapshot
 	c, err := containerCreateInternal(d, args)
 	if err != nil {
@@ -555,9 +537,9 @@ func containerCreateEmptySnapshot(d *Daemon, args containerArgs) (container, err
 	return c, nil
 }
 
-func containerCreateFromImage(d *Daemon, args containerArgs, hash string) (container, error) {
+func containerCreateFromImage(d *Daemon, args store.ContainerArgs, hash string) (container, error) {
 	// Get the image properties
-	_, img, err := dbImageGet(d.db, hash, false, false)
+	_, img, err := store.ImageGet(d.db, hash, false, false)
 	if err != nil {
 		return nil, err
 	}
@@ -578,7 +560,7 @@ func containerCreateFromImage(d *Daemon, args containerArgs, hash string) (conta
 		return nil, err
 	}
 
-	if err := dbImageLastAccessUpdate(d.db, hash, time.Now().UTC()); err != nil {
+	if err := store.ImageLastAccessUpdate(d.db, hash, time.Now().UTC()); err != nil {
 		return nil, fmt.Errorf("Error updating image last use date: %s", err)
 	}
 
@@ -598,7 +580,7 @@ func containerCreateFromImage(d *Daemon, args containerArgs, hash string) (conta
 	return c, nil
 }
 
-func containerCreateAsCopy(d *Daemon, args containerArgs, sourceContainer container, containerOnly bool) (container, error) {
+func containerCreateAsCopy(d *Daemon, args store.ContainerArgs, sourceContainer container, containerOnly bool) (container, error) {
 	// Create the container.
 	ct, err := containerCreateInternal(d, args)
 	if err != nil {
@@ -616,10 +598,10 @@ func containerCreateAsCopy(d *Daemon, args containerArgs, sourceContainer contai
 		for i, snap := range snapshots {
 			fields := strings.SplitN(snap.Name(), shared.SnapshotDelimiter, 2)
 			newSnapName := fmt.Sprintf("%s/%s", ct.Name(), fields[1])
-			csArgs := containerArgs{
+			csArgs := store.ContainerArgs{
 				Architecture: snap.Architecture(),
 				Config:       snap.LocalConfig(),
-				Ctype:        cTypeSnapshot,
+				Ctype:        store.CTypeSnapshot,
 				Devices:      snap.LocalDevices(),
 				Ephemeral:    snap.IsEphemeral(),
 				Name:         newSnapName,
@@ -663,7 +645,7 @@ func containerCreateAsCopy(d *Daemon, args containerArgs, sourceContainer contai
 	return ct, nil
 }
 
-func containerCreateAsSnapshot(d *Daemon, args containerArgs, sourceContainer container) (container, error) {
+func containerCreateAsSnapshot(d *Daemon, args store.ContainerArgs, sourceContainer container) (container, error) {
 	// Deal with state
 	if args.Stateful {
 		if !sourceContainer.IsRunning() {
@@ -732,7 +714,7 @@ func containerCreateAsSnapshot(d *Daemon, args containerArgs, sourceContainer co
 	return c, nil
 }
 
-func containerCreateInternal(d *Daemon, args containerArgs) (container, error) {
+func containerCreateInternal(d *Daemon, args store.ContainerArgs) (container, error) {
 	// Set default values
 	if args.Profiles == nil {
 		args.Profiles = []string{"default"}
@@ -755,7 +737,7 @@ func containerCreateInternal(d *Daemon, args containerArgs) (container, error) {
 	}
 
 	// Validate container name
-	if args.Ctype == cTypeRegular {
+	if args.Ctype == store.CTypeRegular {
 		err := containerValidName(args.Name)
 		if err != nil {
 			return nil, err
@@ -785,7 +767,7 @@ func containerCreateInternal(d *Daemon, args containerArgs) (container, error) {
 	}
 
 	// Validate profiles
-	profiles, err := dbProfiles(d.db)
+	profiles, err := store.Profiles(d.db)
 	if err != nil {
 		return nil, err
 	}
@@ -797,9 +779,9 @@ func containerCreateInternal(d *Daemon, args containerArgs) (container, error) {
 	}
 
 	// Create the container entry
-	id, err := dbContainerCreate(d.db, args)
+	id, err := store.ContainerCreate(d.db, args)
 	if err != nil {
-		if err == DbErrAlreadyDefined {
+		if err == store.DbErrAlreadyDefined {
 			thing := "Container"
 			if shared.IsSnapshot(args.Name) {
 				thing = "Snapshot"
@@ -815,7 +797,7 @@ func containerCreateInternal(d *Daemon, args containerArgs) (container, error) {
 	args.Id = id
 
 	// Read the timestamp from the database
-	dbArgs, err := dbContainerGet(d.db, args.Name)
+	dbArgs, err := store.ContainerGet(d.db, args.Name)
 	if err != nil {
 		return nil, err
 	}
@@ -879,7 +861,7 @@ func containerConfigureInternal(c container) error {
 
 func containerLoadById(d *Daemon, id int) (container, error) {
 	// Get the DB record
-	name, err := dbContainerName(d.db, id)
+	name, err := store.ContainerName(d.db, id)
 	if err != nil {
 		return nil, err
 	}
@@ -889,7 +871,7 @@ func containerLoadById(d *Daemon, id int) (container, error) {
 
 func containerLoadByName(d *Daemon, name string) (container, error) {
 	// Get the DB record
-	args, err := dbContainerGet(d.db, name)
+	args, err := store.ContainerGet(d.db, name)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 8d26217f6..160a1e307 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -24,6 +24,7 @@ import (
 	"gopkg.in/lxc/go-lxc.v2"
 	"gopkg.in/yaml.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -235,7 +236,7 @@ func lxcStatusCode(state lxc.State) api.StatusCode {
 }
 
 // Loader functions
-func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
+func containerLXCCreate(d *Daemon, args store.ContainerArgs) (container, error) {
 	// Create the container struct
 	c := &containerLXC{
 		daemon:       d,
@@ -296,7 +297,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	storagePool := rootDiskDevice["pool"]
 
 	// Get the storage pool ID for the container
-	poolID, pool, err := dbStoragePoolGet(d.db, storagePool)
+	poolID, pool, err := store.StoragePoolGet(d.db, storagePool)
 	if err != nil {
 		c.Delete()
 		return nil, err
@@ -310,7 +311,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	}
 
 	// Create a new database entry for the container's storage volume
-	_, err = dbStoragePoolVolumeCreate(d.db, args.Name, "", storagePoolVolumeTypeContainer, poolID, volumeConfig)
+	_, err = store.StoragePoolVolumeCreate(d.db, args.Name, "", storagePoolVolumeTypeContainer, poolID, volumeConfig)
 	if err != nil {
 		c.Delete()
 		return nil, err
@@ -401,7 +402,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 	return c, nil
 }
 
-func containerLXCLoad(d *Daemon, args containerArgs) (container, error) {
+func containerLXCLoad(d *Daemon, args store.ContainerArgs) (container, error) {
 	// Create the container struct
 	c := &containerLXC{
 		daemon:       d,
@@ -432,7 +433,7 @@ func containerLXCLoad(d *Daemon, args containerArgs) (container, error) {
 type containerLXC struct {
 	// Properties
 	architecture int
-	cType        containerType
+	cType        store.ContainerType
 	creationDate time.Time
 	lastUsedDate time.Time
 	ephemeral    bool
@@ -677,7 +678,7 @@ func findIdmap(daemon *Daemon, cName string, isolatedStr string, configBase stri
 	idmapLock.Lock()
 	defer idmapLock.Unlock()
 
-	cs, err := dbContainersList(daemon.db, cTypeRegular)
+	cs, err := store.ContainersList(daemon.db, store.CTypeRegular)
 	if err != nil {
 		return nil, 0, err
 	}
@@ -1501,7 +1502,7 @@ func (c *containerLXC) expandConfig() error {
 
 	// Apply all the profiles
 	for _, name := range c.profiles {
-		profileConfig, err := dbProfileConfig(c.daemon.db, name)
+		profileConfig, err := store.ProfileConfig(c.daemon.db, name)
 		if err != nil {
 			return err
 		}
@@ -1525,7 +1526,7 @@ func (c *containerLXC) expandDevices() error {
 
 	// Apply all the profiles
 	for _, p := range c.profiles {
-		profileDevices, err := dbDevices(c.daemon.db, p, true)
+		profileDevices, err := store.Devices(c.daemon.db, p, true)
 		if err != nil {
 			return err
 		}
@@ -1651,7 +1652,7 @@ func (c *containerLXC) startCommon() (string, error) {
 		}
 
 		// Remove the volatile key from the DB
-		err = dbContainerConfigRemove(c.daemon.db, c.id, "volatile.apply_quota")
+		err = store.ContainerConfigRemove(c.daemon.db, c.id, "volatile.apply_quota")
 		if err != nil {
 			return "", err
 		}
@@ -1985,7 +1986,7 @@ func (c *containerLXC) startCommon() (string, error) {
 	}
 
 	// Update time container was last started
-	err = dbContainerLastUsedUpdate(c.daemon.db, c.id, time.Now().UTC())
+	err = store.ContainerLastUsedUpdate(c.daemon.db, c.id, time.Now().UTC())
 	if err != nil {
 		return "", fmt.Errorf("Error updating last used: %v", err)
 	}
@@ -2043,7 +2044,7 @@ func (c *containerLXC) Start(stateful bool) error {
 		os.RemoveAll(c.StatePath())
 		c.stateful = false
 
-		err = dbContainerSetStateful(c.daemon.db, c.id, false)
+		err = store.ContainerSetStateful(c.daemon.db, c.id, false)
 		if err != nil {
 			logger.Error("Failed starting container", ctxMap)
 			return err
@@ -2060,7 +2061,7 @@ func (c *containerLXC) Start(stateful bool) error {
 		}
 
 		c.stateful = false
-		err = dbContainerSetStateful(c.daemon.db, c.id, false)
+		err = store.ContainerSetStateful(c.daemon.db, c.id, false)
 		if err != nil {
 			return err
 		}
@@ -2153,7 +2154,7 @@ func (c *containerLXC) OnStart() error {
 		}
 
 		// Remove the volatile key from the DB
-		err := dbContainerConfigRemove(c.daemon.db, c.id, key)
+		err := store.ContainerConfigRemove(c.daemon.db, c.id, key)
 		if err != nil {
 			AADestroy(c)
 			if ourStart {
@@ -2207,7 +2208,7 @@ func (c *containerLXC) OnStart() error {
 	}
 
 	// Record current state
-	err = dbContainerSetState(c.daemon.db, c.id, "RUNNING")
+	err = store.ContainerSetState(c.daemon.db, c.id, "RUNNING")
 	if err != nil {
 		return err
 	}
@@ -2261,7 +2262,7 @@ func (c *containerLXC) Stop(stateful bool) error {
 		}
 
 		c.stateful = true
-		err = dbContainerSetStateful(c.daemon.db, c.id, true)
+		err = store.ContainerSetStateful(c.daemon.db, c.id, true)
 		if err != nil {
 			op.Done(err)
 			logger.Error("Failed stopping container", ctxMap)
@@ -2445,7 +2446,7 @@ func (c *containerLXC) OnStop(target string) error {
 		deviceTaskSchedulerTrigger("container", c.name, "stopped")
 
 		// Record current state
-		err = dbContainerSetState(c.daemon.db, c.id, "STOPPED")
+		err = store.ContainerSetState(c.daemon.db, c.id, "STOPPED")
 		if err != nil {
 			logger.Error("Failed to set container state", log.Ctx{"container": c.Name(), "err": err})
 		}
@@ -2645,7 +2646,7 @@ func (c *containerLXC) RenderState() (*api.ContainerState, error) {
 
 func (c *containerLXC) Snapshots() ([]container, error) {
 	// Get all the snapshots
-	snaps, err := dbContainerGetSnapshots(c.daemon.db, c.name)
+	snaps, err := store.ContainerGetSnapshots(c.daemon.db, c.name)
 	if err != nil {
 		return nil, err
 	}
@@ -2734,7 +2735,7 @@ func (c *containerLXC) Restore(sourceContainer container, stateful bool) error {
 	}
 
 	// Restore the configuration
-	args := containerArgs{
+	args := store.ContainerArgs{
 		Architecture: sourceContainer.Architecture(),
 		Config:       sourceContainer.LocalConfig(),
 		Devices:      sourceContainer.LocalDevices(),
@@ -2854,7 +2855,7 @@ func (c *containerLXC) Delete() error {
 	}
 
 	// Remove the database record
-	if err := dbContainerRemove(c.daemon.db, c.Name()); err != nil {
+	if err := store.ContainerRemove(c.daemon.db, c.Name()); err != nil {
 		logger.Error("Failed deleting container entry", log.Ctx{"name": c.Name(), "err": err})
 		return err
 	}
@@ -2867,7 +2868,7 @@ func (c *containerLXC) Delete() error {
 		poolID, _ := c.storage.GetContainerPoolInfo()
 
 		// Remove volume from storage pool.
-		err := dbStoragePoolVolumeDelete(c.daemon.db, c.Name(), storagePoolVolumeTypeContainer, poolID)
+		err := store.StoragePoolVolumeDelete(c.daemon.db, c.Name(), storagePoolVolumeTypeContainer, poolID)
 		if err != nil {
 			return err
 		}
@@ -2947,7 +2948,7 @@ func (c *containerLXC) Rename(newName string) error {
 	}
 
 	// Rename the database entry
-	err = dbContainerRename(c.daemon.db, oldName, newName)
+	err = store.ContainerRename(c.daemon.db, oldName, newName)
 	if err != nil {
 		logger.Error("Failed renaming container", ctxMap)
 		return err
@@ -2955,7 +2956,7 @@ func (c *containerLXC) Rename(newName string) error {
 
 	// Rename storage volume for the container.
 	poolID, _ := c.storage.GetContainerPoolInfo()
-	err = dbStoragePoolVolumeRename(c.daemon.db, oldName, newName, storagePoolVolumeTypeContainer, poolID)
+	err = store.StoragePoolVolumeRename(c.daemon.db, oldName, newName, storagePoolVolumeTypeContainer, poolID)
 	if err != nil {
 		logger.Error("Failed renaming storage volume", ctxMap)
 		return err
@@ -2963,7 +2964,7 @@ func (c *containerLXC) Rename(newName string) error {
 
 	if !c.IsSnapshot() {
 		// Rename all the snapshots
-		results, err := dbContainerGetSnapshots(c.daemon.db, oldName)
+		results, err := store.ContainerGetSnapshots(c.daemon.db, oldName)
 		if err != nil {
 			logger.Error("Failed renaming container", ctxMap)
 			return err
@@ -2973,14 +2974,14 @@ func (c *containerLXC) Rename(newName string) error {
 			// Rename the snapshot
 			baseSnapName := filepath.Base(sname)
 			newSnapshotName := newName + shared.SnapshotDelimiter + baseSnapName
-			err := dbContainerRename(c.daemon.db, sname, newSnapshotName)
+			err := store.ContainerRename(c.daemon.db, sname, newSnapshotName)
 			if err != nil {
 				logger.Error("Failed renaming container", ctxMap)
 				return err
 			}
 
 			// Rename storage volume for the snapshot.
-			err = dbStoragePoolVolumeRename(c.daemon.db, sname, newSnapshotName, storagePoolVolumeTypeContainer, poolID)
+			err = store.StoragePoolVolumeRename(c.daemon.db, sname, newSnapshotName, storagePoolVolumeTypeContainer, poolID)
 			if err != nil {
 				logger.Error("Failed renaming storage volume", ctxMap)
 				return err
@@ -3042,7 +3043,7 @@ func (c *containerLXC) CGroupSet(key string, value string) error {
 func (c *containerLXC) ConfigKeySet(key string, value string) error {
 	c.localConfig[key] = value
 
-	args := containerArgs{
+	args := store.ContainerArgs{
 		Architecture: c.architecture,
 		Config:       c.localConfig,
 		Devices:      c.localDevices,
@@ -3103,13 +3104,13 @@ func writeBackupFile(c container) error {
 		return err
 	}
 
-	db := c.Daemon().db
-	poolID, pool, err := dbStoragePoolGet(c.Daemon().db, poolName)
+	d := c.Daemon()
+	poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return err
 	}
 
-	_, volume, err := dbStoragePoolVolumeGetType(db, c.Name(), storagePoolVolumeTypeContainer, poolID)
+	_, volume, err := store.StoragePoolVolumeGetType(d.db, c.Name(), storagePoolVolumeTypeContainer, poolID)
 	if err != nil {
 		return err
 	}
@@ -3143,7 +3144,7 @@ func writeBackupFile(c container) error {
 	return nil
 }
 
-func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
+func (c *containerLXC) Update(args store.ContainerArgs, userRequested bool) error {
 	// Set sane defaults for unset keys
 	if args.Architecture == 0 {
 		args.Architecture = c.architecture
@@ -3174,7 +3175,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 	}
 
 	// Validate the new profiles
-	profiles, err := dbProfiles(c.daemon.db)
+	profiles, err := store.Profiles(c.daemon.db)
 	if err != nil {
 		return err
 	}
@@ -4008,42 +4009,42 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 	}
 
 	// Finally, apply the changes to the database
-	tx, err := dbBegin(c.daemon.db)
+	tx, err := store.Begin(c.daemon.db)
 	if err != nil {
 		return err
 	}
 
-	err = dbContainerConfigClear(tx, c.id)
+	err = store.ContainerConfigClear(tx, c.id)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbContainerConfigInsert(tx, c.id, c.localConfig)
+	err = store.ContainerConfigInsert(tx, c.id, c.localConfig)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbContainerProfilesInsert(tx, c.id, c.profiles)
+	err = store.ContainerProfilesInsert(tx, c.id, c.profiles)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbDevicesAdd(tx, "container", int64(c.id), c.localDevices)
+	err = store.DevicesAdd(tx, "container", int64(c.id), c.localDevices)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbContainerUpdate(tx, c.id, c.description, c.architecture, c.ephemeral)
+	err = store.ContainerUpdate(tx, c.id, c.description, c.architecture, c.ephemeral)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	if err := txCommit(tx); err != nil {
+	if err := store.TxCommit(tx); err != nil {
 		return err
 	}
 
@@ -5960,18 +5961,18 @@ func (c *containerLXC) fillNetworkDevice(name string, m types.Device) (types.Dev
 	}
 
 	updateKey := func(key string, value string) error {
-		tx, err := dbBegin(c.daemon.db)
+		tx, err := store.Begin(c.daemon.db)
 		if err != nil {
 			return err
 		}
 
-		err = dbContainerConfigInsert(tx, c.id, map[string]string{key: value})
+		err = store.ContainerConfigInsert(tx, c.id, map[string]string{key: value})
 		if err != nil {
 			tx.Rollback()
 			return err
 		}
 
-		err = txCommit(tx)
+		err = store.TxCommit(tx)
 		if err != nil {
 			return err
 		}
@@ -5994,7 +5995,7 @@ func (c *containerLXC) fillNetworkDevice(name string, m types.Device) (types.Dev
 			err = updateKey(configKey, volatileHwaddr)
 			if err != nil {
 				// Check if something else filled it in behind our back
-				value, err1 := dbContainerConfigGet(c.daemon.db, c.id, configKey)
+				value, err1 := store.ContainerConfigGet(c.daemon.db, c.id, configKey)
 				if err1 != nil || value == "" {
 					return nil, err
 				}
@@ -6024,7 +6025,7 @@ func (c *containerLXC) fillNetworkDevice(name string, m types.Device) (types.Dev
 			err = updateKey(configKey, volatileName)
 			if err != nil {
 				// Check if something else filled it in behind our back
-				value, err1 := dbContainerConfigGet(c.daemon.db, c.id, configKey)
+				value, err1 := store.ContainerConfigGet(c.daemon.db, c.id, configKey)
 				if err1 != nil || value == "" {
 					return nil, err
 				}
@@ -6820,7 +6821,7 @@ func (c *containerLXC) IsRunning() bool {
 }
 
 func (c *containerLXC) IsSnapshot() bool {
-	return c.cType == cTypeSnapshot
+	return c.cType == store.CTypeSnapshot
 }
 
 // Various property query functions
@@ -6978,7 +6979,7 @@ func (c *containerLXC) StatePath() string {
 }
 
 func (c *containerLXC) StoragePool() (string, error) {
-	poolName, err := dbContainerPool(c.daemon.db, c.Name())
+	poolName, err := store.ContainerPool(c.daemon.db, c.Name())
 	if err != nil {
 		return "", err
 	}
diff --git a/lxd/container_patch.go b/lxd/container_patch.go
index 0d86bd148..7f271a36b 100644
--- a/lxd/container_patch.go
+++ b/lxd/container_patch.go
@@ -9,6 +9,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/osarch"
@@ -99,7 +100,7 @@ func containerPatch(d *Daemon, r *http.Request) Response {
 	}
 
 	// Update container configuration
-	args := containerArgs{
+	args := store.ContainerArgs{
 		Architecture: architecture,
 		Description:  req.Description,
 		Config:       req.Config,
diff --git a/lxd/container_post.go b/lxd/container_post.go
index 69a697824..fcd0d0f4f 100644
--- a/lxd/container_post.go
+++ b/lxd/container_post.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 )
@@ -80,7 +81,7 @@ func containerPost(d *Daemon, r *http.Request) Response {
 	}
 
 	// Check that the name isn't already in use
-	id, _ := dbContainerId(d.db, req.Name)
+	id, _ := store.ContainerId(d.db, req.Name)
 	if id > 0 {
 		return Conflict
 	}
diff --git a/lxd/container_put.go b/lxd/container_put.go
index 5ad47c6b5..ad8bf6c28 100644
--- a/lxd/container_put.go
+++ b/lxd/container_put.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/osarch"
@@ -47,7 +48,7 @@ func containerPut(d *Daemon, r *http.Request) Response {
 	if configRaw.Restore == "" {
 		// Update container configuration
 		do = func(op *operation) error {
-			args := containerArgs{
+			args := store.ContainerArgs{
 				Architecture: architecture,
 				Description:  configRaw.Description,
 				Config:       configRaw.Config,
diff --git a/lxd/container_snapshot.go b/lxd/container_snapshot.go
index 0002e23cd..8b55ffbca 100644
--- a/lxd/container_snapshot.go
+++ b/lxd/container_snapshot.go
@@ -10,6 +10,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/version"
@@ -67,9 +68,9 @@ func nextSnapshot(d *Daemon, name string) int {
 	length := len(base)
 	q := fmt.Sprintf("SELECT name FROM containers WHERE type=? AND SUBSTR(name,1,?)=?")
 	var numstr string
-	inargs := []interface{}{cTypeSnapshot, length, base}
+	inargs := []interface{}{store.CTypeSnapshot, length, base}
 	outfmt := []interface{}{numstr}
-	results, err := dbQueryScan(d.db, q, inargs, outfmt)
+	results, err := store.QueryScan(d.db, q, inargs, outfmt)
 	if err != nil {
 		return 0
 	}
@@ -132,9 +133,9 @@ func containerSnapshotsPost(d *Daemon, r *http.Request) Response {
 		req.Name
 
 	snapshot := func(op *operation) error {
-		args := containerArgs{
+		args := store.ContainerArgs{
 			Name:         fullName,
-			Ctype:        cTypeSnapshot,
+			Ctype:        store.CTypeSnapshot,
 			Config:       c.LocalConfig(),
 			Profiles:     c.Profiles(),
 			Ephemeral:    c.IsEphemeral(),
@@ -282,7 +283,7 @@ func snapshotPost(d *Daemon, r *http.Request, sc container, containerName string
 	fullName := containerName + shared.SnapshotDelimiter + newName
 
 	// Check that the name isn't already in use
-	id, _ := dbContainerId(d.db, fullName)
+	id, _ := store.ContainerId(d.db, fullName)
 	if id > 0 {
 		return Conflict
 	}
diff --git a/lxd/container_state.go b/lxd/container_state.go
index a766db8bf..d8e441934 100644
--- a/lxd/container_state.go
+++ b/lxd/container_state.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 )
@@ -99,7 +100,7 @@ func containerStatePut(d *Daemon, r *http.Request) Response {
 
 			if ephemeral {
 				// Unset ephemeral flag
-				args := containerArgs{
+				args := store.ContainerArgs{
 					Description:  c.Description(),
 					Architecture: c.Architecture(),
 					Config:       c.LocalConfig(),
diff --git a/lxd/container_test.go b/lxd/container_test.go
index 4215f2829..994a324c5 100644
--- a/lxd/container_test.go
+++ b/lxd/container_test.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"testing"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -15,8 +16,8 @@ type containerTestSuite struct {
 }
 
 func (suite *containerTestSuite) TestContainer_ProfilesDefault() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Name:      "testFoo",
 	}
@@ -39,7 +40,7 @@ func (suite *containerTestSuite) TestContainer_ProfilesDefault() {
 
 func (suite *containerTestSuite) TestContainer_ProfilesMulti() {
 	// Create an unprivileged profile
-	_, err := dbProfileCreate(
+	_, err := store.ProfileCreate(
 		suite.d.db,
 		"unprivileged",
 		"unprivileged",
@@ -48,11 +49,11 @@ func (suite *containerTestSuite) TestContainer_ProfilesMulti() {
 
 	suite.Req.Nil(err, "Failed to create the unprivileged profile.")
 	defer func() {
-		dbProfileDelete(suite.d.db, "unprivileged")
+		store.ProfileDelete(suite.d.db, "unprivileged")
 	}()
 
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Profiles:  []string{"default", "unprivileged"},
 		Name:      "testFoo",
@@ -74,8 +75,8 @@ func (suite *containerTestSuite) TestContainer_ProfilesMulti() {
 }
 
 func (suite *containerTestSuite) TestContainer_ProfilesOverwriteDefaultNic() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Config:    map[string]string{"security.privileged": "true"},
 		Devices: types.Devices{
@@ -104,8 +105,8 @@ func (suite *containerTestSuite) TestContainer_ProfilesOverwriteDefaultNic() {
 }
 
 func (suite *containerTestSuite) TestContainer_LoadFromDB() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Config:    map[string]string{"security.privileged": "true"},
 		Devices: types.Devices{
@@ -136,8 +137,8 @@ func (suite *containerTestSuite) TestContainer_LoadFromDB() {
 
 func (suite *containerTestSuite) TestContainer_Path_Regular() {
 	// Regular
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Name:      "testFoo",
 	}
@@ -153,8 +154,8 @@ func (suite *containerTestSuite) TestContainer_Path_Regular() {
 
 func (suite *containerTestSuite) TestContainer_Path_Snapshot() {
 	// Snapshot
-	args := containerArgs{
-		Ctype:     cTypeSnapshot,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeSnapshot,
 		Ephemeral: false,
 		Name:      "test/snap0",
 	}
@@ -173,8 +174,8 @@ func (suite *containerTestSuite) TestContainer_Path_Snapshot() {
 }
 
 func (suite *containerTestSuite) TestContainer_LogPath() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Name:      "testFoo",
 	}
@@ -187,8 +188,8 @@ func (suite *containerTestSuite) TestContainer_LogPath() {
 }
 
 func (suite *containerTestSuite) TestContainer_IsPrivileged_Privileged() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Config:    map[string]string{"security.privileged": "true"},
 		Name:      "testFoo",
@@ -202,8 +203,8 @@ func (suite *containerTestSuite) TestContainer_IsPrivileged_Privileged() {
 }
 
 func (suite *containerTestSuite) TestContainer_IsPrivileged_Unprivileged() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Config:    map[string]string{"security.privileged": "false"},
 		Name:      "testFoo",
@@ -217,8 +218,8 @@ func (suite *containerTestSuite) TestContainer_IsPrivileged_Unprivileged() {
 }
 
 func (suite *containerTestSuite) TestContainer_Rename() {
-	args := containerArgs{
-		Ctype:     cTypeRegular,
+	args := store.ContainerArgs{
+		Ctype:     store.CTypeRegular,
 		Ephemeral: false,
 		Name:      "testFoo",
 	}
@@ -232,8 +233,8 @@ func (suite *containerTestSuite) TestContainer_Rename() {
 }
 
 func (suite *containerTestSuite) TestContainer_findIdmap_isolated() {
-	c1, err := containerCreateInternal(suite.d, containerArgs{
-		Ctype: cTypeRegular,
+	c1, err := containerCreateInternal(suite.d, store.ContainerArgs{
+		Ctype: store.CTypeRegular,
 		Name:  "isol-1",
 		Config: map[string]string{
 			"security.idmap.isolated": "true",
@@ -242,8 +243,8 @@ func (suite *containerTestSuite) TestContainer_findIdmap_isolated() {
 	suite.Req.Nil(err)
 	defer c1.Delete()
 
-	c2, err := containerCreateInternal(suite.d, containerArgs{
-		Ctype: cTypeRegular,
+	c2, err := containerCreateInternal(suite.d, store.ContainerArgs{
+		Ctype: store.CTypeRegular,
 		Name:  "isol-2",
 		Config: map[string]string{
 			"security.idmap.isolated": "true",
@@ -273,8 +274,8 @@ func (suite *containerTestSuite) TestContainer_findIdmap_isolated() {
 }
 
 func (suite *containerTestSuite) TestContainer_findIdmap_mixed() {
-	c1, err := containerCreateInternal(suite.d, containerArgs{
-		Ctype: cTypeRegular,
+	c1, err := containerCreateInternal(suite.d, store.ContainerArgs{
+		Ctype: store.CTypeRegular,
 		Name:  "isol-1",
 		Config: map[string]string{
 			"security.idmap.isolated": "false",
@@ -283,8 +284,8 @@ func (suite *containerTestSuite) TestContainer_findIdmap_mixed() {
 	suite.Req.Nil(err)
 	defer c1.Delete()
 
-	c2, err := containerCreateInternal(suite.d, containerArgs{
-		Ctype: cTypeRegular,
+	c2, err := containerCreateInternal(suite.d, store.ContainerArgs{
+		Ctype: store.CTypeRegular,
 		Name:  "isol-2",
 		Config: map[string]string{
 			"security.idmap.isolated": "true",
@@ -314,8 +315,8 @@ func (suite *containerTestSuite) TestContainer_findIdmap_mixed() {
 }
 
 func (suite *containerTestSuite) TestContainer_findIdmap_raw() {
-	c1, err := containerCreateInternal(suite.d, containerArgs{
-		Ctype: cTypeRegular,
+	c1, err := containerCreateInternal(suite.d, store.ContainerArgs{
+		Ctype: store.CTypeRegular,
 		Name:  "isol-1",
 		Config: map[string]string{
 			"security.idmap.isolated": "false",
@@ -353,8 +354,8 @@ func (suite *containerTestSuite) TestContainer_findIdmap_maxed() {
 	maps := []*shared.IdmapSet{}
 
 	for i := 0; i < 7; i++ {
-		c, err := containerCreateInternal(suite.d, containerArgs{
-			Ctype: cTypeRegular,
+		c, err := containerCreateInternal(suite.d, store.ContainerArgs{
+			Ctype: store.CTypeRegular,
 			Name:  fmt.Sprintf("isol-%d", i),
 			Config: map[string]string{
 				"security.idmap.isolated": "true",
diff --git a/lxd/containers.go b/lxd/containers.go
index a48a4b51d..8ba97737b 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -6,6 +6,7 @@ import (
 	"sync"
 	"time"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 
@@ -97,7 +98,7 @@ func (slice containerAutostartList) Swap(i, j int) {
 
 func containersRestart(d *Daemon) error {
 	// Get all the containers
-	result, err := dbContainersList(d.db, cTypeRegular)
+	result, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
@@ -144,13 +145,13 @@ func containersShutdown(d *Daemon) error {
 	var wg sync.WaitGroup
 
 	// Get all the containers
-	results, err := dbContainersList(d.db, cTypeRegular)
+	results, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
 
 	// Reset all container states
-	_, err = dbExec(d.db, "DELETE FROM containers_config WHERE key='volatile.last_state.power'")
+	_, err = store.Exec(d.db, "DELETE FROM containers_config WHERE key='volatile.last_state.power'")
 	if err != nil {
 		return err
 	}
@@ -198,7 +199,7 @@ func containerDeleteSnapshots(d *Daemon, cname string) error {
 	logger.Debug("containerDeleteSnapshots",
 		log.Ctx{"container": cname})
 
-	results, err := dbContainerGetSnapshots(d.db, cname)
+	results, err := store.ContainerGetSnapshots(d.db, cname)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/containers_get.go b/lxd/containers_get.go
index eecdc6721..661839056 100644
--- a/lxd/containers_get.go
+++ b/lxd/containers_get.go
@@ -5,6 +5,7 @@ import (
 	"net/http"
 	"time"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
@@ -16,7 +17,7 @@ func containersGet(d *Daemon, r *http.Request) Response {
 		if err == nil {
 			return SyncResponse(true, result)
 		}
-		if !isDbLockedError(err) {
+		if !store.IsDbLockedError(err) {
 			logger.Debugf("DBERR: containersGet: error %q", err)
 			return SmartError(err)
 		}
@@ -31,7 +32,7 @@ func containersGet(d *Daemon, r *http.Request) Response {
 }
 
 func doContainersGet(d *Daemon, recursion bool) (interface{}, error) {
-	result, err := dbContainersList(d.db, cTypeRegular)
+	result, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 0fc382f1c..023fb9b6c 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -11,6 +11,7 @@ import (
 	"github.com/dustinkirkland/golang-petname"
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
@@ -30,7 +31,7 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 		if req.Source.Server != "" {
 			hash = req.Source.Alias
 		} else {
-			_, alias, err := dbImageAliasGet(d.db, req.Source.Alias, true)
+			_, alias, err := store.ImageAliasGet(d.db, req.Source.Alias, true)
 			if err != nil {
 				return SmartError(err)
 			}
@@ -42,7 +43,7 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 			return BadRequest(fmt.Errorf("Property match is only supported for local images"))
 		}
 
-		hashes, err := dbImagesGet(d.db, false)
+		hashes, err := store.ImagesGet(d.db, false)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -50,7 +51,7 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 		var image *api.Image
 
 		for _, imageHash := range hashes {
-			_, img, err := dbImageGet(d.db, imageHash, false, true)
+			_, img, err := store.ImageGet(d.db, imageHash, false, true)
 			if err != nil {
 				continue
 			}
@@ -84,9 +85,9 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 	}
 
 	run := func(op *operation) error {
-		args := containerArgs{
+		args := store.ContainerArgs{
 			Config:    req.Config,
-			Ctype:     cTypeRegular,
+			Ctype:     store.CTypeRegular,
 			Devices:   req.Devices,
 			Ephemeral: req.Ephemeral,
 			Name:      req.Name,
@@ -102,7 +103,7 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 				return err
 			}
 		} else {
-			_, info, err = dbImageGet(d.db, hash, false, false)
+			_, info, err = store.ImageGet(d.db, hash, false, false)
 			if err != nil {
 				return err
 			}
@@ -129,9 +130,9 @@ func createFromImage(d *Daemon, req *api.ContainersPost) Response {
 }
 
 func createFromNone(d *Daemon, req *api.ContainersPost) Response {
-	args := containerArgs{
+	args := store.ContainerArgs{
 		Config:    req.Config,
-		Ctype:     cTypeRegular,
+		Ctype:     store.CTypeRegular,
 		Devices:   req.Devices,
 		Ephemeral: req.Ephemeral,
 		Name:      req.Name,
@@ -177,11 +178,11 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 	}
 
 	// Prepare the container creation request
-	args := containerArgs{
+	args := store.ContainerArgs{
 		Architecture: architecture,
 		BaseImage:    req.Source.BaseImage,
 		Config:       req.Config,
-		Ctype:        cTypeRegular,
+		Ctype:        store.CTypeRegular,
 		Devices:      req.Devices,
 		Ephemeral:    req.Ephemeral,
 		Name:         req.Name,
@@ -200,8 +201,8 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 
 	// Handle copying/moving between two storage-api LXD instances.
 	if storagePool != "" {
-		_, err := dbStoragePoolGetID(d.db, storagePool)
-		if err == NoSuchObjectError {
+		_, err := store.StoragePoolGetID(d.db, storagePool)
+		if err == store.NoSuchObjectError {
 			storagePool = ""
 			// Unset the local root disk device storage pool if not
 			// found.
@@ -212,7 +213,7 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 	// If we don't have a valid pool yet, look through profiles
 	if storagePool == "" {
 		for _, pName := range req.Profiles {
-			_, p, err := dbProfileGet(d.db, pName)
+			_, p, err := store.ProfileGet(d.db, pName)
 			if err != nil {
 				return SmartError(err)
 			}
@@ -229,9 +230,9 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 	logger.Debugf("No valid storage pool in the container's local root disk device and profiles found.")
 	// If there is just a single pool in the database, use that
 	if storagePool == "" {
-		pools, err := dbStoragePools(d.db)
+		pools, err := store.StoragePools(d.db)
 		if err != nil {
-			if err == NoSuchObjectError {
+			if err == store.NoSuchObjectError {
 				return BadRequest(fmt.Errorf("This LXD instance does not have any storage pools configured."))
 			}
 			return SmartError(err)
@@ -286,7 +287,7 @@ func createFromMigration(d *Daemon, req *api.ContainersPost) Response {
 	 * point and just negotiate it over the migration control
 	 * socket. Anyway, it'll happen later :)
 	 */
-	_, _, err = dbImageGet(d.db, req.Source.BaseImage, false, true)
+	_, _, err = store.ImageGet(d.db, req.Source.BaseImage, false, true)
 	if err != nil {
 		c, err = containerCreateAsEmpty(d, args)
 		if err != nil {
@@ -472,11 +473,11 @@ func createFromCopy(d *Daemon, req *api.ContainersPost) Response {
 		}
 	}
 
-	args := containerArgs{
+	args := store.ContainerArgs{
 		Architecture: source.Architecture(),
 		BaseImage:    req.Source.BaseImage,
 		Config:       req.Config,
-		Ctype:        cTypeRegular,
+		Ctype:        store.CTypeRegular,
 		Devices:      req.Devices,
 		Ephemeral:    req.Ephemeral,
 		Name:         req.Name,
@@ -512,13 +513,13 @@ func containersPost(d *Daemon, r *http.Request) Response {
 	}
 
 	// If no storage pool is found, error out.
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err != nil || len(pools) == 0 {
 		return BadRequest(fmt.Errorf("No storage pool found. Please create a new storage pool."))
 	}
 
 	if req.Name == "" {
-		cs, err := dbContainersList(d.db, cTypeRegular)
+		cs, err := store.ContainersList(d.db, store.CTypeRegular)
 		if err != nil {
 			return SmartError(err)
 		}
diff --git a/lxd/daemon.go b/lxd/daemon.go
index c3e1f547f..0c5433868 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -30,6 +30,7 @@ import (
 	"gopkg.in/tomb.v2"
 
 	"github.com/lxc/lxd/client"
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/logging"
@@ -293,9 +294,9 @@ func (d *Daemon) createCmd(version string, c Command) {
 }
 
 func (d *Daemon) SetupStorageDriver(forceCheck bool) error {
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err != nil {
-		if err == NoSuchObjectError {
+		if err == store.NoSuchObjectError {
 			logger.Debugf("No existing storage pools detected.")
 			return nil
 		}
@@ -310,7 +311,7 @@ func (d *Daemon) SetupStorageDriver(forceCheck bool) error {
 	// but the upgrade somehow got messed up then there will be no
 	// "storage_api" entry in the db.
 	if len(pools) > 0 && !forceCheck {
-		appliedPatches, err := dbPatches(d.db)
+		appliedPatches, err := store.Patches(d.db)
 		if err != nil {
 			return err
 		}
@@ -346,8 +347,8 @@ func (d *Daemon) SetupStorageDriver(forceCheck bool) error {
 	// appropriate. (Should be cheaper then querying the db all the time,
 	// especially if we keep adding more storage drivers.)
 	if !storagePoolDriversCacheInitialized {
-		tmp, err := dbStoragePoolsGetDrivers(d.db)
-		if err != nil && err != NoSuchObjectError {
+		tmp, err := store.StoragePoolsGetDrivers(d.db)
+		if err != nil && err != store.NoSuchObjectError {
 			return nil
 		}
 
@@ -1145,7 +1146,7 @@ func (d *Daemon) CheckTrustState(cert x509.Certificate) bool {
 }
 
 func (d *Daemon) numRunningContainers() (int, error) {
-	results, err := dbContainersList(d.db, cTypeRegular)
+	results, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return 0, err
 	}
@@ -1254,7 +1255,7 @@ func (d *Daemon) ExpireLogs() error {
 		return err
 	}
 
-	result, err := dbContainersList(d.db, cTypeRegular)
+	result, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
@@ -1408,19 +1409,19 @@ func initializeDbObject(d *Daemon, path string) error {
 	var err error
 
 	// Open the database. If the file doesn't exist it is created.
-	d.db, err = openDb(path)
+	d.db, err = store.OpenDb(path)
 	if err != nil {
 		return err
 	}
 
 	// Create the DB if it doesn't exist.
-	err = createDb(d.db)
+	err = store.CreateDb(d.db, patchesGetNames())
 	if err != nil {
 		return fmt.Errorf("Error creating database: %s", err)
 	}
 
 	// Detect LXD downgrades
-	if dbGetSchema(d.db) > dbGetLatestSchema() {
+	if store.GetSchema(d.db) > store.GetLatestSchema() {
 		return fmt.Errorf("The database schema is more recent than LXD's schema.")
 	}
 
@@ -1431,7 +1432,7 @@ func initializeDbObject(d *Daemon, path string) error {
 	// patches mechanism was introduced in lxd/patches.go. The
 	// rest of non-db patches will be applied separately via
 	// patchesApplyAll. See PR #3322 for more details.
-	err = dbUpdatesApplyAll(d.db, true, func(version int) error {
+	err = store.UpdatesApplyAll(d.db, true, func(version int) error {
 		if legacyPatch, ok := legacyPatches[version]; ok {
 			return legacyPatch(d)
 		}
diff --git a/lxd/daemon_config.go b/lxd/daemon_config.go
index d1ae46590..1ef3c6f0c 100644
--- a/lxd/daemon_config.go
+++ b/lxd/daemon_config.go
@@ -14,6 +14,7 @@ import (
 	"golang.org/x/crypto/scrypt"
 	log "gopkg.in/inconshreveable/log15.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -127,7 +128,7 @@ func (k *daemonConfigKey) Set(d *Daemon, value string) error {
 	k.currentValue = value
 	daemonConfigLock.Unlock()
 
-	err = dbConfigValueSet(d.db, name, value)
+	err = store.ConfigValueSet(d.db, name, value)
 	if err != nil {
 		return err
 	}
@@ -201,7 +202,7 @@ func daemonConfigInit(db *sql.DB) error {
 	}
 
 	// Load the values from the DB
-	dbValues, err := dbConfigValuesGet(db)
+	dbValues, err := store.ConfigValuesGet(db)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/daemon_images.go b/lxd/daemon_images.go
index c5a926898..28e08d126 100644
--- a/lxd/daemon_images.go
+++ b/lxd/daemon_images.go
@@ -15,6 +15,7 @@ import (
 	"gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/client"
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/cancel"
@@ -230,14 +231,14 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 	// auto-update is on).
 	interval := daemonConfig["images.auto_update_interval"].GetInt64()
 	if preferCached && interval > 0 && alias != fp {
-		cachedFingerprint, err := dbImageSourceGetCachedFingerprint(d.db, server, protocol, alias)
+		cachedFingerprint, err := store.ImageSourceGetCachedFingerprint(d.db, server, protocol, alias)
 		if err == nil && cachedFingerprint != fp {
 			fp = cachedFingerprint
 		}
 	}
 
 	// Check if the image already exists (partial hash match)
-	_, imgInfo, err := dbImageGet(d.db, fp, false, true)
+	_, imgInfo, err := store.ImageGet(d.db, fp, false, true)
 	if err == nil {
 		logger.Debug("Image already exists in the db", log.Ctx{"image": fp})
 		info = imgInfo
@@ -248,13 +249,13 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 		}
 
 		// Get the ID of the target storage pool
-		poolID, err := dbStoragePoolGetID(d.db, storagePool)
+		poolID, err := store.StoragePoolGetID(d.db, storagePool)
 		if err != nil {
 			return nil, err
 		}
 
 		// Check if the image is already in the pool
-		poolIDs, err := dbImageGetPools(d.db, info.Fingerprint)
+		poolIDs, err := store.ImageGetPools(d.db, info.Fingerprint)
 		if err != nil {
 			return nil, err
 		}
@@ -291,7 +292,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 		<-waitChannel
 
 		// Grab the database entry
-		_, imgInfo, err := dbImageGet(d.db, fp, false, true)
+		_, imgInfo, err := store.ImageGet(d.db, fp, false, true)
 		if err != nil {
 			// Other download failed, lets try again
 			logger.Error("Other image download didn't succeed", log.Ctx{"image": fp})
@@ -504,7 +505,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 	}
 
 	// Create the database entry
-	err = dbImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
+	err = store.ImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 	if err != nil {
 		return nil, err
 	}
@@ -513,12 +514,12 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 	failure = false
 
 	if alias != fp {
-		id, _, err := dbImageGet(d.db, fp, false, true)
+		id, _, err := store.ImageGet(d.db, fp, false, true)
 		if err != nil {
 			return nil, err
 		}
 
-		err = dbImageSourceInsert(d.db, id, server, protocol, certificate, alias)
+		err = store.ImageSourceInsert(d.db, id, server, protocol, certificate, alias)
 		if err != nil {
 			return nil, err
 		}
@@ -534,7 +535,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 
 	// Mark the image as "cached" if downloading for a container
 	if forContainer {
-		err := dbImageLastAccessInit(d.db, fp)
+		err := store.ImageLastAccessInit(d.db, fp)
 		if err != nil {
 			return nil, err
 		}
diff --git a/lxd/daemon_images_test.go b/lxd/daemon_images_test.go
index 92c182506..58fbdcb34 100644
--- a/lxd/daemon_images_test.go
+++ b/lxd/daemon_images_test.go
@@ -5,6 +5,7 @@ import (
 	"time"
 
 	"github.com/lxc/lxd/client"
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/stretchr/testify/suite"
 )
@@ -19,11 +20,11 @@ type daemonImagesTestSuite struct {
 // newer image even if available, and just use the cached one.
 func (suite *daemonImagesTestSuite) TestUseCachedImagesIfAvailable() {
 	// Create an image with alias "test" and fingerprint "abcd".
-	err := dbImageInsert(suite.d.db, "abcd", "foo.xz", 1, false, true, "amd64", time.Now(), time.Now(), map[string]string{})
+	err := store.ImageInsert(suite.d.db, "abcd", "foo.xz", 1, false, true, "amd64", time.Now(), time.Now(), map[string]string{})
 	suite.Req.Nil(err)
-	id, _, err := dbImageGet(suite.d.db, "abcd", false, true)
+	id, _, err := store.ImageGet(suite.d.db, "abcd", false, true)
 	suite.Req.Nil(err)
-	err = dbImageSourceInsert(suite.d.db, id, "img.srv", "simplestreams", "", "test")
+	err = store.ImageSourceInsert(suite.d.db, id, "img.srv", "simplestreams", "", "test")
 	suite.Req.Nil(err)
 
 	// Pretend we have already a non-expired entry for the remote
diff --git a/lxd/devices.go b/lxd/devices.go
index 2fa749a1f..2be4e3839 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -19,6 +19,7 @@ import (
 
 	_ "github.com/mattn/go-sqlite3"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 
@@ -589,7 +590,7 @@ func deviceTaskBalance(d *Daemon) {
 	}
 
 	// Iterate through the containers
-	containers, err := dbContainersList(d.db, cTypeRegular)
+	containers, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		logger.Error("problem loading containers list", log.Ctx{"err": err})
 		return
@@ -715,7 +716,7 @@ func deviceNetworkPriority(d *Daemon, netif string) {
 		return
 	}
 
-	containers, err := dbContainersList(d.db, cTypeRegular)
+	containers, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return
 	}
@@ -746,7 +747,7 @@ func deviceNetworkPriority(d *Daemon, netif string) {
 }
 
 func deviceUSBEvent(d *Daemon, usb usbDevice) {
-	containers, err := dbContainersList(d.db, cTypeRegular)
+	containers, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		logger.Error("problem loading containers list", log.Ctx{"err": err})
 		return
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index c2ece9d30..4b773e45a 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -15,6 +15,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/version"
@@ -371,7 +372,7 @@ func findContainerForPid(pid int32, d *Daemon) (container, error) {
 		return nil, err
 	}
 
-	containers, err := dbContainersList(d.db, cTypeRegular)
+	containers, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/images.go b/lxd/images.go
index 8a89fd4ab..2f0f8bc33 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -22,6 +22,7 @@ import (
 	"github.com/gorilla/mux"
 	"gopkg.in/yaml.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -288,7 +289,7 @@ func imgPostContInfo(d *Daemon, r *http.Request, req api.ImagesPost, builddir st
 
 	info.Fingerprint = fmt.Sprintf("%x", sha256.Sum(nil))
 
-	_, _, err = dbImageGet(d.db, info.Fingerprint, false, true)
+	_, _, err = store.ImageGet(d.db, info.Fingerprint, false, true)
 	if err == nil {
 		return nil, fmt.Errorf("The image already exists: %s", info.Fingerprint)
 	}
@@ -304,7 +305,7 @@ func imgPostContInfo(d *Daemon, r *http.Request, req api.ImagesPost, builddir st
 	info.Properties = req.Properties
 
 	// Create the database entry
-	err = dbImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
+	err = store.ImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 	if err != nil {
 		return nil, err
 	}
@@ -329,7 +330,7 @@ func imgPostRemoteInfo(d *Daemon, req api.ImagesPost, op *operation) (*api.Image
 		return nil, err
 	}
 
-	id, info, err := dbImageGet(d.db, info.Fingerprint, false, true)
+	id, info, err := store.ImageGet(d.db, info.Fingerprint, false, true)
 	if err != nil {
 		return nil, err
 	}
@@ -341,7 +342,7 @@ func imgPostRemoteInfo(d *Daemon, req api.ImagesPost, op *operation) (*api.Image
 
 	// Update the DB record if needed
 	if req.Public || req.AutoUpdate || req.Filename != "" || len(req.Properties) > 0 {
-		err = dbImageUpdate(d.db, id, req.Filename, info.Size, req.Public, req.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
+		err = store.ImageUpdate(d.db, id, req.Filename, info.Size, req.Public, req.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 		if err != nil {
 			return nil, err
 		}
@@ -398,7 +399,7 @@ func imgPostURLInfo(d *Daemon, req api.ImagesPost, op *operation) (*api.Image, e
 		return nil, err
 	}
 
-	id, info, err := dbImageGet(d.db, info.Fingerprint, false, false)
+	id, info, err := store.ImageGet(d.db, info.Fingerprint, false, false)
 	if err != nil {
 		return nil, err
 	}
@@ -409,7 +410,7 @@ func imgPostURLInfo(d *Daemon, req api.ImagesPost, op *operation) (*api.Image, e
 	}
 
 	if req.Public || req.AutoUpdate || req.Filename != "" || len(req.Properties) > 0 {
-		err = dbImageUpdate(d.db, id, req.Filename, info.Size, req.Public, req.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
+		err = store.ImageUpdate(d.db, id, req.Filename, info.Size, req.Public, req.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 		if err != nil {
 			return nil, err
 		}
@@ -606,7 +607,7 @@ func getImgPostInfo(d *Daemon, r *http.Request, builddir string, post *os.File)
 	}
 
 	// Check if the image already exists
-	exists, err := dbImageExists(d.db, info.Fingerprint)
+	exists, err := store.ImageExists(d.db, info.Fingerprint)
 	if err != nil {
 		return nil, err
 	}
@@ -614,7 +615,7 @@ func getImgPostInfo(d *Daemon, r *http.Request, builddir string, post *os.File)
 		return nil, fmt.Errorf("Image with same fingerprint already exists")
 	}
 	// Create the database entry
-	err = dbImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
+	err = store.ImageInsert(d.db, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 	if err != nil {
 		return nil, err
 	}
@@ -729,17 +730,17 @@ func imagesPost(d *Daemon, r *http.Request) Response {
 
 		// Apply any provided alias
 		for _, alias := range req.Aliases {
-			_, _, err := dbImageAliasGet(d.db, alias.Name, true)
+			_, _, err := store.ImageAliasGet(d.db, alias.Name, true)
 			if err == nil {
 				return fmt.Errorf("Alias already exists: %s", alias.Name)
 			}
 
-			id, _, err := dbImageGet(d.db, info.Fingerprint, false, false)
+			id, _, err := store.ImageGet(d.db, info.Fingerprint, false, false)
 			if err != nil {
 				return err
 			}
 
-			err = dbImageAliasAdd(d.db, alias.Name, id, alias.Description)
+			err = store.ImageAliasAdd(d.db, alias.Name, id, alias.Description)
 			if err != nil {
 				return err
 			}
@@ -805,7 +806,7 @@ func getImageMetadata(fname string) (*api.ImageMetadata, error) {
 }
 
 func doImagesGet(d *Daemon, recursion bool, public bool) (interface{}, error) {
-	results, err := dbImagesGet(d.db, public)
+	results, err := store.ImagesGet(d.db, public)
 	if err != nil {
 		return []string{}, err
 	}
@@ -850,14 +851,14 @@ var imagesCmd = Command{name: "images", post: imagesPost, untrustedGet: true, ge
 func autoUpdateImages(d *Daemon) {
 	logger.Infof("Updating images")
 
-	images, err := dbImagesGet(d.db, false)
+	images, err := store.ImagesGet(d.db, false)
 	if err != nil {
 		logger.Error("Unable to retrieve the list of images", log.Ctx{"err": err})
 		return
 	}
 
 	for _, fingerprint := range images {
-		id, info, err := dbImageGet(d.db, fingerprint, false, true)
+		id, info, err := store.ImageGet(d.db, fingerprint, false, true)
 		if err != nil {
 			logger.Error("Error loading image", log.Ctx{"err": err, "fp": fingerprint})
 			continue
@@ -877,7 +878,7 @@ func autoUpdateImages(d *Daemon) {
 // Returns whether the image has been updated.
 func autoUpdateImage(d *Daemon, op *operation, id int, info *api.Image) error {
 	fingerprint := info.Fingerprint
-	_, source, err := dbImageSourceGet(d.db, id)
+	_, source, err := store.ImageSourceGet(d.db, id)
 	if err != nil {
 		logger.Error("Error getting source image", log.Ctx{"err": err, "fp": fingerprint})
 		return err
@@ -885,14 +886,14 @@ func autoUpdateImage(d *Daemon, op *operation, id int, info *api.Image) error {
 
 	// Get the IDs of all storage pools on which a storage volume
 	// for the requested image currently exists.
-	poolIDs, err := dbImageGetPools(d.db, fingerprint)
+	poolIDs, err := store.ImageGetPools(d.db, fingerprint)
 	if err != nil {
 		logger.Error("Error getting image pools", log.Ctx{"err": err, "fp": fingerprint})
 		return err
 	}
 
 	// Translate the IDs to poolNames.
-	poolNames, err := dbImageGetPoolNamesFromIDs(d.db, poolIDs)
+	poolNames, err := store.ImageGetPoolNamesFromIDs(d.db, poolIDs)
 	if err != nil {
 		logger.Error("Error getting image pools", log.Ctx{"err": err, "fp": fingerprint})
 		return err
@@ -931,19 +932,19 @@ func autoUpdateImage(d *Daemon, op *operation, id int, info *api.Image) error {
 			continue
 		}
 
-		newId, _, err := dbImageGet(d.db, hash, false, true)
+		newId, _, err := store.ImageGet(d.db, hash, false, true)
 		if err != nil {
 			logger.Error("Error loading image", log.Ctx{"err": err, "fp": hash})
 			continue
 		}
 
-		err = dbImageLastAccessUpdate(d.db, hash, info.LastUsedAt)
+		err = store.ImageLastAccessUpdate(d.db, hash, info.LastUsedAt)
 		if err != nil {
 			logger.Error("Error setting last use date", log.Ctx{"err": err, "fp": hash})
 			continue
 		}
 
-		err = dbImageAliasesMove(d.db, id, newId)
+		err = store.ImageAliasesMove(d.db, id, newId)
 		if err != nil {
 			logger.Error("Error moving aliases", log.Ctx{"err": err, "fp": hash})
 			continue
@@ -984,7 +985,7 @@ func autoUpdateImage(d *Daemon, op *operation, id int, info *api.Image) error {
 	}
 
 	// Remove the database entry for the image.
-	if err = dbImageDelete(d.db, id); err != nil {
+	if err = store.ImageDelete(d.db, id); err != nil {
 		logger.Debugf("Error deleting image from database %s: %s", fname, err)
 	}
 
@@ -997,7 +998,7 @@ func pruneExpiredImages(d *Daemon) {
 
 	// Get the list of expired images.
 	expiry := daemonConfig["images.remote_cache_expiry"].GetInt64()
-	images, err := dbImagesGetExpired(d.db, expiry)
+	images, err := store.ImagesGetExpired(d.db, expiry)
 	if err != nil {
 		logger.Error("Unable to retrieve the list of expired images", log.Ctx{"err": err})
 		return
@@ -1007,13 +1008,13 @@ func pruneExpiredImages(d *Daemon) {
 	for _, fp := range images {
 		// Get the IDs of all storage pools on which a storage volume
 		// for the requested image currently exists.
-		poolIDs, err := dbImageGetPools(d.db, fp)
+		poolIDs, err := store.ImageGetPools(d.db, fp)
 		if err != nil {
 			continue
 		}
 
 		// Translate the IDs to poolNames.
-		poolNames, err := dbImageGetPoolNamesFromIDs(d.db, poolIDs)
+		poolNames, err := store.ImageGetPoolNamesFromIDs(d.db, poolIDs)
 		if err != nil {
 			continue
 		}
@@ -1044,13 +1045,13 @@ func pruneExpiredImages(d *Daemon) {
 			}
 		}
 
-		imgID, _, err := dbImageGet(d.db, fp, false, false)
+		imgID, _, err := store.ImageGet(d.db, fp, false, false)
 		if err != nil {
 			logger.Debugf("Error retrieving image info %s: %s", fp, err)
 		}
 
 		// Remove the database entry for the image.
-		if err = dbImageDelete(d.db, imgID); err != nil {
+		if err = store.ImageDelete(d.db, imgID); err != nil {
 			logger.Debugf("Error deleting image %s from database: %s", fp, err)
 		}
 	}
@@ -1080,17 +1081,17 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 	deleteFromAllPools := func() error {
 		// Use the fingerprint we received in a LIKE query and use the full
 		// fingerprint we receive from the database in all further queries.
-		imgID, imgInfo, err := dbImageGet(d.db, fingerprint, false, false)
+		imgID, imgInfo, err := store.ImageGet(d.db, fingerprint, false, false)
 		if err != nil {
 			return err
 		}
 
-		poolIDs, err := dbImageGetPools(d.db, imgInfo.Fingerprint)
+		poolIDs, err := store.ImageGetPools(d.db, imgInfo.Fingerprint)
 		if err != nil {
 			return err
 		}
 
-		pools, err := dbImageGetPoolNamesFromIDs(d.db, poolIDs)
+		pools, err := store.ImageGetPoolNamesFromIDs(d.db, poolIDs)
 		if err != nil {
 			return err
 		}
@@ -1121,7 +1122,7 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 		}
 
 		// Remove the database entry for the image.
-		return dbImageDelete(d.db, imgID)
+		return store.ImageDelete(d.db, imgID)
 	}
 
 	rmimg := func(op *operation) error {
@@ -1140,7 +1141,7 @@ func imageDelete(d *Daemon, r *http.Request) Response {
 }
 
 func doImageGet(d *Daemon, fingerprint string, public bool) (*api.Image, Response) {
-	_, imgInfo, err := dbImageGet(d.db, fingerprint, public, false)
+	_, imgInfo, err := store.ImageGet(d.db, fingerprint, public, false)
 	if err != nil {
 		return nil, SmartError(err)
 	}
@@ -1199,7 +1200,7 @@ func imageGet(d *Daemon, r *http.Request) Response {
 func imagePut(d *Daemon, r *http.Request) Response {
 	// Get current value
 	fingerprint := mux.Vars(r)["fingerprint"]
-	id, info, err := dbImageGet(d.db, fingerprint, false, false)
+	id, info, err := store.ImageGet(d.db, fingerprint, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1216,7 +1217,7 @@ func imagePut(d *Daemon, r *http.Request) Response {
 		return BadRequest(err)
 	}
 
-	err = dbImageUpdate(d.db, id, info.Filename, info.Size, req.Public, req.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, req.Properties)
+	err = store.ImageUpdate(d.db, id, info.Filename, info.Size, req.Public, req.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, req.Properties)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1227,7 +1228,7 @@ func imagePut(d *Daemon, r *http.Request) Response {
 func imagePatch(d *Daemon, r *http.Request) Response {
 	// Get current value
 	fingerprint := mux.Vars(r)["fingerprint"]
-	id, info, err := dbImageGet(d.db, fingerprint, false, false)
+	id, info, err := store.ImageGet(d.db, fingerprint, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1282,7 +1283,7 @@ func imagePatch(d *Daemon, r *http.Request) Response {
 		info.Properties = properties
 	}
 
-	err = dbImageUpdate(d.db, id, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
+	err = store.ImageUpdate(d.db, id, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1303,17 +1304,17 @@ func aliasesPost(d *Daemon, r *http.Request) Response {
 	}
 
 	// This is just to see if the alias name already exists.
-	_, _, err := dbImageAliasGet(d.db, req.Name, true)
+	_, _, err := store.ImageAliasGet(d.db, req.Name, true)
 	if err == nil {
 		return Conflict
 	}
 
-	id, _, err := dbImageGet(d.db, req.Target, false, false)
+	id, _, err := store.ImageGet(d.db, req.Target, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	err = dbImageAliasAdd(d.db, req.Name, id, req.Description)
+	err = store.ImageAliasAdd(d.db, req.Name, id, req.Description)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1328,7 +1329,7 @@ func aliasesGet(d *Daemon, r *http.Request) Response {
 	var name string
 	inargs := []interface{}{}
 	outfmt := []interface{}{name}
-	results, err := dbQueryScan(d.db, q, inargs, outfmt)
+	results, err := store.QueryScan(d.db, q, inargs, outfmt)
 	if err != nil {
 		return BadRequest(err)
 	}
@@ -1341,7 +1342,7 @@ func aliasesGet(d *Daemon, r *http.Request) Response {
 			responseStr = append(responseStr, url)
 
 		} else {
-			_, alias, err := dbImageAliasGet(d.db, name, d.isTrustedClient(r))
+			_, alias, err := store.ImageAliasGet(d.db, name, d.isTrustedClient(r))
 			if err != nil {
 				continue
 			}
@@ -1359,7 +1360,7 @@ func aliasesGet(d *Daemon, r *http.Request) Response {
 func aliasGet(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
-	_, alias, err := dbImageAliasGet(d.db, name, d.isTrustedClient(r))
+	_, alias, err := store.ImageAliasGet(d.db, name, d.isTrustedClient(r))
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1369,12 +1370,12 @@ func aliasGet(d *Daemon, r *http.Request) Response {
 
 func aliasDelete(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
-	_, _, err := dbImageAliasGet(d.db, name, true)
+	_, _, err := store.ImageAliasGet(d.db, name, true)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	err = dbImageAliasDelete(d.db, name)
+	err = store.ImageAliasDelete(d.db, name)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1385,7 +1386,7 @@ func aliasDelete(d *Daemon, r *http.Request) Response {
 func aliasPut(d *Daemon, r *http.Request) Response {
 	// Get current value
 	name := mux.Vars(r)["name"]
-	id, alias, err := dbImageAliasGet(d.db, name, true)
+	id, alias, err := store.ImageAliasGet(d.db, name, true)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1405,12 +1406,12 @@ func aliasPut(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("The target field is required"))
 	}
 
-	imageId, _, err := dbImageGet(d.db, req.Target, false, false)
+	imageId, _, err := store.ImageGet(d.db, req.Target, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	err = dbImageAliasUpdate(d.db, id, imageId, req.Description)
+	err = store.ImageAliasUpdate(d.db, id, imageId, req.Description)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1421,7 +1422,7 @@ func aliasPut(d *Daemon, r *http.Request) Response {
 func aliasPatch(d *Daemon, r *http.Request) Response {
 	// Get current value
 	name := mux.Vars(r)["name"]
-	id, alias, err := dbImageAliasGet(d.db, name, true)
+	id, alias, err := store.ImageAliasGet(d.db, name, true)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1457,12 +1458,12 @@ func aliasPatch(d *Daemon, r *http.Request) Response {
 		alias.Description = description
 	}
 
-	imageId, _, err := dbImageGet(d.db, alias.Target, false, false)
+	imageId, _, err := store.ImageGet(d.db, alias.Target, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	err = dbImageAliasUpdate(d.db, id, imageId, alias.Description)
+	err = store.ImageAliasUpdate(d.db, id, imageId, alias.Description)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1479,17 +1480,17 @@ func aliasPost(d *Daemon, r *http.Request) Response {
 	}
 
 	// Check that the name isn't already in use
-	id, _, _ := dbImageAliasGet(d.db, req.Name, true)
+	id, _, _ := store.ImageAliasGet(d.db, req.Name, true)
 	if id > 0 {
 		return Conflict
 	}
 
-	id, _, err := dbImageAliasGet(d.db, name, true)
+	id, _, err := store.ImageAliasGet(d.db, name, true)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	err = dbImageAliasRename(d.db, id, req.Name)
+	err = store.ImageAliasRename(d.db, id, req.Name)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1503,7 +1504,7 @@ func imageExport(d *Daemon, r *http.Request) Response {
 	public := !d.isTrustedClient(r)
 	secret := r.FormValue("secret")
 
-	_, imgInfo, err := dbImageGet(d.db, fingerprint, false, false)
+	_, imgInfo, err := store.ImageGet(d.db, fingerprint, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1553,7 +1554,7 @@ func imageExport(d *Daemon, r *http.Request) Response {
 
 func imageSecret(d *Daemon, r *http.Request) Response {
 	fingerprint := mux.Vars(r)["fingerprint"]
-	_, imgInfo, err := dbImageGet(d.db, fingerprint, false, false)
+	_, imgInfo, err := store.ImageGet(d.db, fingerprint, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -1580,7 +1581,7 @@ func imageSecret(d *Daemon, r *http.Request) Response {
 
 func imageRefresh(d *Daemon, r *http.Request) Response {
 	fingerprint := mux.Vars(r)["fingerprint"]
-	imageId, imageInfo, err := dbImageGet(d.db, fingerprint, false, false)
+	imageId, imageInfo, err := store.ImageGet(d.db, fingerprint, false, false)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go
index 753d25dc8..f962a6517 100644
--- a/lxd/main_activateifneeded.go
+++ b/lxd/main_activateifneeded.go
@@ -5,6 +5,7 @@ import (
 	"os"
 
 	"github.com/lxc/lxd/client"
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -51,7 +52,7 @@ func cmdActivateIfNeeded() error {
 	}
 
 	// Look for auto-started or previously started containers
-	result, err := dbContainersList(d.db, cTypeRegular)
+	result, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/main_test.go b/lxd/main_test.go
index 4db9162a2..4eda4dacf 100644
--- a/lxd/main_test.go
+++ b/lxd/main_test.go
@@ -6,6 +6,7 @@ import (
 	"io/ioutil"
 	"os"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/stretchr/testify/require"
 	"github.com/stretchr/testify/suite"
 
@@ -87,7 +88,7 @@ func (suite *lxdTestSuite) SetupTest() {
 	mockStorage, _ := storageTypeToString(storageTypeMock)
 	// Create the database entry for the storage pool.
 	poolDescription := fmt.Sprintf("%s storage pool", lxdTestSuiteDefaultStoragePool)
-	_, err := dbStoragePoolCreate(suite.d.db, lxdTestSuiteDefaultStoragePool, poolDescription, mockStorage, poolConfig)
+	_, err := dbStoragePoolCreateAndUpdateCache(suite.d.db, lxdTestSuiteDefaultStoragePool, poolDescription, mockStorage, poolConfig)
 	if err != nil {
 		os.Exit(1)
 	}
@@ -99,17 +100,17 @@ func (suite *lxdTestSuite) SetupTest() {
 	devicesMap := map[string]map[string]string{}
 	devicesMap["root"] = rootDev
 
-	defaultID, _, err := dbProfileGet(suite.d.db, "default")
+	defaultID, _, err := store.ProfileGet(suite.d.db, "default")
 	if err != nil {
 		os.Exit(1)
 	}
 
-	tx, err := dbBegin(suite.d.db)
+	tx, err := store.Begin(suite.d.db)
 	if err != nil {
 		os.Exit(1)
 	}
 
-	err = dbDevicesAdd(tx, "profile", defaultID, devicesMap)
+	err = store.DevicesAdd(tx, "profile", defaultID, devicesMap)
 	if err != nil {
 		tx.Rollback()
 		os.Exit(1)
diff --git a/lxd/networks.go b/lxd/networks.go
index db25a2147..9e06b7324 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -14,6 +14,7 @@ import (
 	"github.com/gorilla/mux"
 	log "gopkg.in/inconshreveable/log15.v2"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -126,7 +127,7 @@ func networksPost(d *Daemon, r *http.Request) Response {
 	}
 
 	// Create the database entry
-	_, err = dbNetworkCreate(d.db, req.Name, req.Description, req.Config)
+	_, err = store.NetworkCreate(d.db, req.Name, req.Description, req.Config)
 	if err != nil {
 		return InternalError(
 			fmt.Errorf("Error inserting %s into database: %s", req.Name, err))
@@ -165,7 +166,7 @@ func networkGet(d *Daemon, r *http.Request) Response {
 func doNetworkGet(d *Daemon, name string) (api.Network, error) {
 	// Get some information
 	osInfo, _ := net.InterfaceByName(name)
-	_, dbInfo, _ := dbNetworkGet(d.db, name)
+	_, dbInfo, _ := store.NetworkGet(d.db, name)
 
 	// Sanity check
 	if osInfo == nil && dbInfo == nil {
@@ -179,7 +180,7 @@ func doNetworkGet(d *Daemon, name string) (api.Network, error) {
 	n.Config = map[string]string{}
 
 	// Look for containers using the interface
-	cts, err := dbContainersList(d.db, cTypeRegular)
+	cts, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return api.Network{}, err
 	}
@@ -296,7 +297,7 @@ func networkPut(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
 	// Get the existing network
-	_, dbInfo, err := dbNetworkGet(d.db, name)
+	_, dbInfo, err := store.NetworkGet(d.db, name)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -321,7 +322,7 @@ func networkPatch(d *Daemon, r *http.Request) Response {
 	name := mux.Vars(r)["name"]
 
 	// Get the existing network
-	_, dbInfo, err := dbNetworkGet(d.db, name)
+	_, dbInfo, err := store.NetworkGet(d.db, name)
 	if dbInfo != nil {
 		return SmartError(err)
 	}
@@ -386,7 +387,7 @@ var networkCmd = Command{name: "networks/{name}", get: networkGet, delete: netwo
 
 // The network structs and functions
 func networkLoadByName(d *Daemon, name string) (*network, error) {
-	id, dbInfo, err := dbNetworkGet(d.db, name)
+	id, dbInfo, err := store.NetworkGet(d.db, name)
 	if err != nil {
 		return nil, err
 	}
@@ -398,7 +399,7 @@ func networkLoadByName(d *Daemon, name string) (*network, error) {
 
 func networkStartup(d *Daemon) error {
 	// Get a list of managed networks
-	networks, err := dbNetworks(d.db)
+	networks, err := store.Networks(d.db)
 	if err != nil {
 		return err
 	}
@@ -422,7 +423,7 @@ func networkStartup(d *Daemon) error {
 
 func networkShutdown(d *Daemon) error {
 	// Get a list of managed networks
-	networks, err := dbNetworks(d.db)
+	networks, err := store.Networks(d.db)
 	if err != nil {
 		return err
 	}
@@ -468,7 +469,7 @@ func (n *network) IsRunning() bool {
 
 func (n *network) IsUsed() bool {
 	// Look for containers using the interface
-	cts, err := dbContainersList(n.daemon.db, cTypeRegular)
+	cts, err := store.ContainersList(n.daemon.db, store.CTypeRegular)
 	if err != nil {
 		return true
 	}
@@ -502,7 +503,7 @@ func (n *network) Delete() error {
 	}
 
 	// Remove the network from the database
-	err := dbNetworkDelete(n.daemon.db, n.name)
+	err := store.NetworkDelete(n.daemon.db, n.name)
 	if err != nil {
 		return err
 	}
@@ -537,7 +538,7 @@ func (n *network) Rename(name string) error {
 	}
 
 	// Rename the database entry
-	err := dbNetworkRename(n.daemon.db, n.name, name)
+	err := store.NetworkRename(n.daemon.db, n.name, name)
 	if err != nil {
 		return err
 	}
@@ -1393,7 +1394,7 @@ func (n *network) Update(newNetwork api.NetworkPut) error {
 	n.description = newNetwork.Description
 
 	// Update the database
-	err = dbNetworkUpdate(n.daemon.db, n.name, n.description, n.config)
+	err = store.NetworkUpdate(n.daemon.db, n.name, n.description, n.config)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 6aea6a528..e12d731d9 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -19,11 +19,12 @@ import (
 	"syscall"
 	"time"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 )
 
 func networkAutoAttach(d *Daemon, devName string) error {
-	_, dbInfo, err := dbNetworkGetInterface(d.db, devName)
+	_, dbInfo, err := store.NetworkGetInterface(d.db, devName)
 	if err != nil {
 		// No match found, move on
 		return nil
@@ -71,7 +72,7 @@ func networkDetachInterface(netName string, devName string) error {
 }
 
 func networkGetInterfaces(d *Daemon) ([]string, error) {
-	networks, err := dbNetworks(d.db)
+	networks, err := store.Networks(d.db)
 	if err != nil {
 		return nil, err
 	}
@@ -723,7 +724,7 @@ func networkKillDnsmasq(name string, reload bool) error {
 
 func networkUpdateStatic(d *Daemon, name string) error {
 	// Get all the containers
-	containers, err := dbContainersList(d.db, cTypeRegular)
+	containers, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
@@ -731,7 +732,7 @@ func networkUpdateStatic(d *Daemon, name string) error {
 	networks := []string{}
 	if name == "" {
 		// Get all the networks
-		networks, err = dbNetworks(d.db)
+		networks, err = store.Networks(d.db)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/patches.go b/lxd/patches.go
index b3d5af51a..49b4f8d4d 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -8,6 +8,7 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 
@@ -60,7 +61,7 @@ func (p *patch) apply(d *Daemon) error {
 		return err
 	}
 
-	err = dbPatchesMarkApplied(d.db, p.name)
+	err = store.PatchesMarkApplied(d.db, p.name)
 	if err != nil {
 		return err
 	}
@@ -68,8 +69,17 @@ func (p *patch) apply(d *Daemon) error {
 	return nil
 }
 
+// Return the names of all available patches.
+func patchesGetNames() []string {
+	names := make([]string, len(patches))
+	for i, patch := range patches {
+		names[i] = patch.name
+	}
+	return names
+}
+
 func patchesApplyAll(d *Daemon) error {
-	appliedPatches, err := dbPatches(d.db)
+	appliedPatches, err := store.Patches(d.db)
 	if err != nil {
 		return err
 	}
@@ -105,7 +115,7 @@ DELETE FROM profiles_devices_config WHERE profile_device_id NOT IN (SELECT id FR
 }
 
 func patchInvalidProfileNames(name string, d *Daemon) error {
-	profiles, err := dbProfiles(d.db)
+	profiles, err := store.Profiles(d.db)
 	if err != nil {
 		return err
 	}
@@ -113,7 +123,7 @@ func patchInvalidProfileNames(name string, d *Daemon) error {
 	for _, profile := range profiles {
 		if strings.Contains(profile, "/") || shared.StringInSlice(profile, []string{".", ".."}) {
 			logger.Info("Removing unreachable profile (invalid name)", log.Ctx{"name": profile})
-			err := dbProfileDelete(d.db, profile)
+			err := store.ProfileDelete(d.db, profile)
 			if err != nil {
 				return err
 			}
@@ -125,7 +135,7 @@ func patchInvalidProfileNames(name string, d *Daemon) error {
 
 func patchNetworkPermissions(name string, d *Daemon) error {
 	// Get the list of networks
-	networks, err := dbNetworks(d.db)
+	networks, err := store.Networks(d.db)
 	if err != nil {
 		return err
 	}
@@ -192,25 +202,25 @@ func patchStorageApi(name string, d *Daemon) error {
 	// Check if this LXD instace currently has any containers, snapshots, or
 	// images configured. If so, we create a default storage pool in the
 	// database. Otherwise, the user will have to run LXD init.
-	cRegular, err := dbContainersList(d.db, cTypeRegular)
+	cRegular, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
 
 	// Get list of existing snapshots.
-	cSnapshots, err := dbContainersList(d.db, cTypeSnapshot)
+	cSnapshots, err := store.ContainersList(d.db, store.CTypeSnapshot)
 	if err != nil {
 		return err
 	}
 
 	// Get list of existing public images.
-	imgPublic, err := dbImagesGet(d.db, true)
+	imgPublic, err := store.ImagesGet(d.db, true)
 	if err != nil {
 		return err
 	}
 
 	// Get list of existing private images.
-	imgPrivate, err := dbImagesGet(d.db, false)
+	imgPrivate, err := store.ImagesGet(d.db, false)
 	if err != nil {
 		return err
 	}
@@ -291,7 +301,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 	}
 
 	poolID := int64(-1)
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(defaultPoolName, pools) {
@@ -300,7 +310,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
-		tmp, pool, err := dbStoragePoolGet(d.db, defaultPoolName)
+		tmp, pool, err := store.StoragePoolGet(d.db, defaultPoolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s.", err)
 			return err
@@ -313,12 +323,12 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 		if pool.Config == nil {
 			pool.Config = poolConfig
 		}
-		err = dbStoragePoolUpdate(d.db, defaultPoolName, "", pool.Config)
+		err = store.StoragePoolUpdate(d.db, defaultPoolName, "", pool.Config)
 		if err != nil {
 			return err
 		}
-	} else if err == NoSuchObjectError { // Likely a pristine upgrade.
-		tmp, err := dbStoragePoolCreate(d.db, defaultPoolName, "", defaultStorageTypeName, poolConfig)
+	} else if err == store.NoSuchObjectError { // Likely a pristine upgrade.
+		tmp, err := dbStoragePoolCreateAndUpdateCache(d.db, defaultPoolName, "", defaultStorageTypeName, poolConfig)
 		if err != nil {
 			return err
 		}
@@ -350,7 +360,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 	}
 
 	// Get storage pool from the db after having updated it above.
-	_, defaultPool, err := dbStoragePoolGet(d.db, defaultPoolName)
+	_, defaultPool, err := store.StoragePoolGet(d.db, defaultPoolName)
 	if err != nil {
 		return err
 	}
@@ -364,16 +374,16 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the container.")
-			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
@@ -422,7 +432,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 		}
 
 		// Check if we need to account for snapshots for this container.
-		ctSnapshots, err := dbContainerGetSnapshots(d.db, ct)
+		ctSnapshots, err := store.ContainerGetSnapshots(d.db, ct)
 		if err != nil {
 			return err
 		}
@@ -452,16 +462,16 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 				return err
 			}
 
-			_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
+			_, err = store.StoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 			if err == nil {
 				logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
-				err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+				err := store.StoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
 				if err != nil {
 					return err
 				}
-			} else if err == NoSuchObjectError {
+			} else if err == store.NoSuchObjectError {
 				// Insert storage volumes for containers into the database.
-				_, err := dbStoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+				_, err := store.StoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 					return err
@@ -533,16 +543,16 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the image.")
-			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
@@ -588,7 +598,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 	}
 
 	poolID := int64(-1)
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(defaultPoolName, pools) {
@@ -597,7 +607,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
-		tmp, pool, err := dbStoragePoolGet(d.db, defaultPoolName)
+		tmp, pool, err := store.StoragePoolGet(d.db, defaultPoolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s.", err)
 			return err
@@ -610,12 +620,12 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 		if pool.Config == nil {
 			pool.Config = poolConfig
 		}
-		err = dbStoragePoolUpdate(d.db, defaultPoolName, pool.Description, pool.Config)
+		err = store.StoragePoolUpdate(d.db, defaultPoolName, pool.Description, pool.Config)
 		if err != nil {
 			return err
 		}
-	} else if err == NoSuchObjectError { // Likely a pristine upgrade.
-		tmp, err := dbStoragePoolCreate(d.db, defaultPoolName, "", defaultStorageTypeName, poolConfig)
+	} else if err == store.NoSuchObjectError { // Likely a pristine upgrade.
+		tmp, err := dbStoragePoolCreateAndUpdateCache(d.db, defaultPoolName, "", defaultStorageTypeName, poolConfig)
 		if err != nil {
 			return err
 		}
@@ -636,7 +646,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 	}
 
 	// Get storage pool from the db after having updated it above.
-	_, defaultPool, err := dbStoragePoolGet(d.db, defaultPoolName)
+	_, defaultPool, err := store.StoragePoolGet(d.db, defaultPoolName)
 	if err != nil {
 		return err
 	}
@@ -651,16 +661,16 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the container.")
-			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
@@ -768,16 +778,16 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
-			err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 				return err
@@ -798,16 +808,16 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the image.")
-			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
@@ -881,7 +891,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 	// are already configured. If so, we can assume that a partial upgrade
 	// has been performed and can skip the next steps.
 	poolID := int64(-1)
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(defaultPoolName, pools) {
@@ -890,7 +900,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
-		tmp, pool, err := dbStoragePoolGet(d.db, defaultPoolName)
+		tmp, pool, err := store.StoragePoolGet(d.db, defaultPoolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s.", err)
 			return err
@@ -903,12 +913,12 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		if pool.Config == nil {
 			pool.Config = poolConfig
 		}
-		err = dbStoragePoolUpdate(d.db, defaultPoolName, pool.Description, pool.Config)
+		err = store.StoragePoolUpdate(d.db, defaultPoolName, pool.Description, pool.Config)
 		if err != nil {
 			return err
 		}
-	} else if err == NoSuchObjectError { // Likely a pristine upgrade.
-		tmp, err := dbStoragePoolCreate(d.db, defaultPoolName, "", defaultStorageTypeName, poolConfig)
+	} else if err == store.NoSuchObjectError { // Likely a pristine upgrade.
+		tmp, err := dbStoragePoolCreateAndUpdateCache(d.db, defaultPoolName, "", defaultStorageTypeName, poolConfig)
 		if err != nil {
 			return err
 		}
@@ -939,7 +949,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 	}
 
 	// Get storage pool from the db after having updated it above.
-	_, defaultPool, err := dbStoragePoolGet(d.db, defaultPoolName)
+	_, defaultPool, err := store.StoragePoolGet(d.db, defaultPoolName)
 	if err != nil {
 		return err
 	}
@@ -954,16 +964,16 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the container.")
-			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
@@ -1092,7 +1102,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 		}
 
 		// Check if we need to account for snapshots for this container.
-		ctSnapshots, err := dbContainerGetSnapshots(d.db, ct)
+		ctSnapshots, err := store.ContainerGetSnapshots(d.db, ct)
 		if err != nil {
 			return err
 		}
@@ -1109,16 +1119,16 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 				return err
 			}
 
-			_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
+			_, err = store.StoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 			if err == nil {
 				logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
-				err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+				err := store.StoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
 				if err != nil {
 					return err
 				}
-			} else if err == NoSuchObjectError {
+			} else if err == store.NoSuchObjectError {
 				// Insert storage volumes for containers into the database.
-				_, err := dbStoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+				_, err := store.StoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 					return err
@@ -1280,16 +1290,16 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the image.")
-			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
@@ -1341,7 +1351,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
 			// This image didn't exist as a logical volume on the
 			// old LXD instance so we need to kick it from the
 			// storage volumes database for this pool.
-			err := dbStoragePoolVolumeDelete(d.db, img, storagePoolVolumeTypeImage, poolID)
+			err := store.StoragePoolVolumeDelete(d.db, img, storagePoolVolumeTypeImage, poolID)
 			if err != nil {
 				return err
 			}
@@ -1381,7 +1391,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 	// are already configured. If so, we can assume that a partial upgrade
 	// has been performed and can skip the next steps.
 	poolID := int64(-1)
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err == nil { // Already exist valid storage pools.
 		// Check if the storage pool already has a db entry.
 		if shared.StringInSlice(poolName, pools) {
@@ -1390,7 +1400,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 
 		// Get the pool ID as we need it for storage volume creation.
 		// (Use a tmp variable as Go's scoping is freaking me out.)
-		tmp, pool, err := dbStoragePoolGet(d.db, poolName)
+		tmp, pool, err := store.StoragePoolGet(d.db, poolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s.", err)
 			return err
@@ -1403,11 +1413,11 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		if pool.Config == nil {
 			pool.Config = poolConfig
 		}
-		err = dbStoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
+		err = store.StoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
 		if err != nil {
 			return err
 		}
-	} else if err == NoSuchObjectError { // Likely a pristine upgrade.
+	} else if err == store.NoSuchObjectError { // Likely a pristine upgrade.
 		if shared.PathExists(oldLoopFilePath) {
 			// This is a loop file pool.
 			poolConfig["source"] = shared.VarPath("disks", poolName+".img")
@@ -1435,7 +1445,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		}
 
 		// (Use a tmp variable as Go's scoping is freaking me out.)
-		tmp, err := dbStoragePoolCreate(d.db, poolName, "", defaultStorageTypeName, poolConfig)
+		tmp, err := dbStoragePoolCreateAndUpdateCache(d.db, poolName, "", defaultStorageTypeName, poolConfig)
 		if err != nil {
 			logger.Warnf("Storage pool already exists in the database. Proceeding...")
 		}
@@ -1446,7 +1456,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 	}
 
 	// Get storage pool from the db after having updated it above.
-	_, defaultPool, err := dbStoragePoolGet(d.db, poolName)
+	_, defaultPool, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return err
 	}
@@ -1471,16 +1481,16 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, ct, storagePoolVolumeTypeContainer, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the container.")
-			err := dbStoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, ct, "", storagePoolVolumeTypeContainer, poolID, containerPoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for container \"%s\".", ct)
 				return err
@@ -1538,7 +1548,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 		}
 
 		// Check if we need to account for snapshots for this container.
-		ctSnapshots, err := dbContainerGetSnapshots(d.db, ct)
+		ctSnapshots, err := store.ContainerGetSnapshots(d.db, ct)
 		if err != nil {
 			logger.Errorf("Failed to query database")
 			return err
@@ -1557,16 +1567,16 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 				return err
 			}
 
-			_, err = dbStoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
+			_, err = store.StoragePoolVolumeGetTypeID(d.db, cs, storagePoolVolumeTypeContainer, poolID)
 			if err == nil {
 				logger.Warnf("Storage volumes database already contains an entry for the snapshot.")
-				err := dbStoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+				err := store.StoragePoolVolumeUpdate(d.db, cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
 				if err != nil {
 					return err
 				}
-			} else if err == NoSuchObjectError {
+			} else if err == store.NoSuchObjectError {
 				// Insert storage volumes for containers into the database.
-				_, err := dbStoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
+				_, err := store.StoragePoolVolumeCreate(d.db, cs, "", storagePoolVolumeTypeContainer, poolID, snapshotPoolVolumeConfig)
 				if err != nil {
 					logger.Errorf("Could not insert a storage volume for snapshot \"%s\".", cs)
 					return err
@@ -1613,16 +1623,16 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
 			return err
 		}
 
-		_, err = dbStoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
+		_, err = store.StoragePoolVolumeGetTypeID(d.db, img, storagePoolVolumeTypeImage, poolID)
 		if err == nil {
 			logger.Warnf("Storage volumes database already contains an entry for the image.")
-			err := dbStoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+			err := store.StoragePoolVolumeUpdate(d.db, img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
 			if err != nil {
 				return err
 			}
-		} else if err == NoSuchObjectError {
+		} else if err == store.NoSuchObjectError {
 			// Insert storage volumes for containers into the database.
-			_, err := dbStoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
+			_, err := store.StoragePoolVolumeCreate(d.db, img, "", storagePoolVolumeTypeImage, poolID, imagePoolVolumeConfig)
 			if err != nil {
 				logger.Errorf("Could not insert a storage volume for image \"%s\".", img)
 				return err
@@ -1681,10 +1691,10 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 	// appropriate device including a pool is added to the default profile
 	// or the user explicitly passes the pool the container's storage volume
 	// is supposed to be created on.
-	profiles, err := dbProfiles(d.db)
+	profiles, err := store.Profiles(d.db)
 	if err == nil {
 		for _, pName := range profiles {
-			pID, p, err := dbProfileGet(d.db, pName)
+			pID, p, err := store.ProfileGet(d.db, pName)
 			if err != nil {
 				logger.Errorf("Could not query database: %s.", err)
 				return err
@@ -1725,26 +1735,26 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 			// This is nasty, but we need to clear the profiles config and
 			// devices in order to add the new root device including the
 			// newly added storage pool.
-			tx, err := dbBegin(d.db)
+			tx, err := store.Begin(d.db)
 			if err != nil {
 				return err
 			}
 
-			err = dbProfileConfigClear(tx, pID)
+			err = store.ProfileConfigClear(tx, pID)
 			if err != nil {
 				logger.Errorf("Failed to clear old profile configuration for profile %s: %s.", pName, err)
 				tx.Rollback()
 				continue
 			}
 
-			err = dbProfileConfigAdd(tx, pID, p.Config)
+			err = store.ProfileConfigAdd(tx, pID, p.Config)
 			if err != nil {
 				logger.Errorf("Failed to add new profile configuration: %s: %s.", pName, err)
 				tx.Rollback()
 				continue
 			}
 
-			err = dbDevicesAdd(tx, "profile", pID, p.Devices)
+			err = store.DevicesAdd(tx, "profile", pID, p.Devices)
 			if err != nil {
 				logger.Errorf("Failed to add new profile profile root disk device: %s: %s.", pName, err)
 				tx.Rollback()
@@ -1767,7 +1777,7 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 			continue
 		}
 
-		args := containerArgs{
+		args := store.ContainerArgs{
 			Architecture: c.Architecture(),
 			Config:       c.LocalConfig(),
 			Ephemeral:    c.IsEphemeral(),
@@ -1778,9 +1788,9 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 		}
 
 		if c.IsSnapshot() {
-			args.Ctype = cTypeSnapshot
+			args.Ctype = store.CTypeSnapshot
 		} else {
-			args.Ctype = cTypeRegular
+			args.Ctype = store.CTypeRegular
 		}
 
 		// Check if the container already has a valid root device entry (profile or previous upgrade)
@@ -1827,8 +1837,8 @@ func updatePoolPropertyForAllObjects(d *Daemon, poolName string, allcontainers [
 }
 
 func patchStorageApiV1(name string, d *Daemon) error {
-	pools, err := dbStoragePools(d.db)
-	if err != nil && err == NoSuchObjectError {
+	pools, err := store.StoragePools(d.db)
+	if err != nil && err == store.NoSuchObjectError {
 		// No pool was configured in the previous update. So we're on a
 		// pristine LXD instance.
 		return nil
@@ -1843,13 +1853,13 @@ func patchStorageApiV1(name string, d *Daemon) error {
 		return nil
 	}
 
-	cRegular, err := dbContainersList(d.db, cTypeRegular)
+	cRegular, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
 
 	// Get list of existing snapshots.
-	cSnapshots, err := dbContainersList(d.db, cTypeSnapshot)
+	cSnapshots, err := store.ContainersList(d.db, store.CTypeSnapshot)
 	if err != nil {
 		return err
 	}
@@ -1864,7 +1874,7 @@ func patchStorageApiV1(name string, d *Daemon) error {
 }
 
 func patchStorageApiDirCleanup(name string, d *Daemon) error {
-	_, err := dbExec(d.db, "DELETE FROM storage_volumes WHERE type=? AND name NOT IN (SELECT fingerprint FROM images);", storagePoolVolumeTypeImage)
+	_, err := store.Exec(d.db, "DELETE FROM storage_volumes WHERE type=? AND name NOT IN (SELECT fingerprint FROM images);", storagePoolVolumeTypeImage)
 	if err != nil {
 		return err
 	}
@@ -1873,12 +1883,12 @@ func patchStorageApiDirCleanup(name string, d *Daemon) error {
 }
 
 func patchStorageApiLvmKeys(name string, d *Daemon) error {
-	_, err := dbExec(d.db, "UPDATE storage_pools_config SET key='lvm.thinpool_name' WHERE key='volume.lvm.thinpool_name';")
+	_, err := store.Exec(d.db, "UPDATE storage_pools_config SET key='lvm.thinpool_name' WHERE key='volume.lvm.thinpool_name';")
 	if err != nil {
 		return err
 	}
 
-	_, err = dbExec(d.db, "DELETE FROM storage_volumes_config WHERE key='lvm.thinpool_name';")
+	_, err = store.Exec(d.db, "DELETE FROM storage_volumes_config WHERE key='lvm.thinpool_name';")
 	if err != nil {
 		return err
 	}
@@ -1887,8 +1897,8 @@ func patchStorageApiLvmKeys(name string, d *Daemon) error {
 }
 
 func patchStorageApiKeys(name string, d *Daemon) error {
-	pools, err := dbStoragePools(d.db)
-	if err != nil && err == NoSuchObjectError {
+	pools, err := store.StoragePools(d.db)
+	if err != nil && err == store.NoSuchObjectError {
 		// No pool was configured in the previous update. So we're on a
 		// pristine LXD instance.
 		return nil
@@ -1899,7 +1909,7 @@ func patchStorageApiKeys(name string, d *Daemon) error {
 	}
 
 	for _, poolName := range pools {
-		_, pool, err := dbStoragePoolGet(d.db, poolName)
+		_, pool, err := store.StoragePoolGet(d.db, poolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s", err)
 			return err
@@ -1932,7 +1942,7 @@ func patchStorageApiKeys(name string, d *Daemon) error {
 		}
 
 		// Update the config in the database.
-		err = dbStoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
+		err = store.StoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
 		if err != nil {
 			return err
 		}
@@ -1944,9 +1954,9 @@ func patchStorageApiKeys(name string, d *Daemon) error {
 // In case any of the objects images/containers/snapshots are missing storage
 // volume configuration entries, let's add the defaults.
 func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err != nil {
-		if err == NoSuchObjectError {
+		if err == store.NoSuchObjectError {
 			return nil
 		}
 		logger.Errorf("Failed to query database: %s", err)
@@ -1954,7 +1964,7 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 	}
 
 	for _, poolName := range pools {
-		poolID, pool, err := dbStoragePoolGet(d.db, poolName)
+		poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s", err)
 			return err
@@ -2020,15 +2030,15 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 		}
 
 		// Update the storage pool config.
-		err = dbStoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
+		err = store.StoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
 		if err != nil {
 			return err
 		}
 
 		// Get all storage volumes on the storage pool.
-		volumes, err := dbStoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes)
+		volumes, err := store.StoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes)
 		if err != nil {
-			if err == NoSuchObjectError {
+			if err == store.NoSuchObjectError {
 				continue
 			}
 			return err
@@ -2081,7 +2091,7 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 			// exist in the db, so it's safe to ignore the error.
 			volumeType, _ := storagePoolVolumeTypeNameToType(volume.Type)
 			// Update the volume config.
-			err = dbStoragePoolVolumeUpdate(d.db, volume.Name, volumeType, poolID, volume.Description, volume.Config)
+			err = store.StoragePoolVolumeUpdate(d.db, volume.Name, volumeType, poolID, volume.Description, volume.Config)
 			if err != nil {
 				return err
 			}
@@ -2092,9 +2102,9 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error {
 }
 
 func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error {
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err != nil {
-		if err == NoSuchObjectError {
+		if err == store.NoSuchObjectError {
 			return nil
 		}
 		logger.Errorf("Failed to query database: %s", err)
@@ -2102,7 +2112,7 @@ func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error {
 	}
 
 	for _, poolName := range pools {
-		_, pool, err := dbStoragePoolGet(d.db, poolName)
+		_, pool, err := store.StoragePoolGet(d.db, poolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s", err)
 			return err
@@ -2137,7 +2147,7 @@ func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error {
 		pool.Config["source"] = getStoragePoolMountPoint(poolName)
 
 		// Update the storage pool config.
-		err = dbStoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
+		err = store.StoragePoolUpdate(d.db, poolName, pool.Description, pool.Config)
 		if err != nil {
 			return err
 		}
@@ -2149,9 +2159,9 @@ func patchStorageApiLxdOnBtrfs(name string, d *Daemon) error {
 }
 
 func patchStorageApiDetectLVSize(name string, d *Daemon) error {
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err != nil {
-		if err == NoSuchObjectError {
+		if err == store.NoSuchObjectError {
 			return nil
 		}
 		logger.Errorf("Failed to query database: %s", err)
@@ -2159,7 +2169,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 	}
 
 	for _, poolName := range pools {
-		poolID, pool, err := dbStoragePoolGet(d.db, poolName)
+		poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s", err)
 			return err
@@ -2182,9 +2192,9 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 		}
 
 		// Get all storage volumes on the storage pool.
-		volumes, err := dbStoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes)
+		volumes, err := store.StoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes)
 		if err != nil {
-			if err == NoSuchObjectError {
+			if err == store.NoSuchObjectError {
 				continue
 			}
 			return err
@@ -2229,7 +2239,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 			// exist in the db, so it's safe to ignore the error.
 			volumeType, _ := storagePoolVolumeTypeNameToType(volume.Type)
 			// Update the volume config.
-			err = dbStoragePoolVolumeUpdate(d.db, volume.Name, volumeType, poolID, volume.Description, volume.Config)
+			err = store.StoragePoolVolumeUpdate(d.db, volume.Name, volumeType, poolID, volume.Description, volume.Config)
 			if err != nil {
 				return err
 			}
@@ -2240,7 +2250,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error {
 }
 
 func patchStorageApiInsertZfsDriver(name string, d *Daemon) error {
-	_, err := dbExec(d.db, "UPDATE storage_pools SET driver='zfs', description='' WHERE driver=''")
+	_, err := store.Exec(d.db, "UPDATE storage_pools SET driver='zfs', description='' WHERE driver=''")
 	if err != nil {
 		return err
 	}
@@ -2249,9 +2259,9 @@ func patchStorageApiInsertZfsDriver(name string, d *Daemon) error {
 }
 
 func patchStorageZFSnoauto(name string, d *Daemon) error {
-	pools, err := dbStoragePools(d.db)
+	pools, err := store.StoragePools(d.db)
 	if err != nil {
-		if err == NoSuchObjectError {
+		if err == store.NoSuchObjectError {
 			return nil
 		}
 		logger.Errorf("Failed to query database: %s", err)
@@ -2259,7 +2269,7 @@ func patchStorageZFSnoauto(name string, d *Daemon) error {
 	}
 
 	for _, poolName := range pools {
-		_, pool, err := dbStoragePoolGet(d.db, poolName)
+		_, pool, err := store.StoragePoolGet(d.db, poolName)
 		if err != nil {
 			logger.Errorf("Failed to query database: %s", err)
 			return err
@@ -2347,7 +2357,7 @@ func patchUpdateFromV10(d *Daemon) error {
 }
 
 func patchUpdateFromV11(d *Daemon) error {
-	cNames, err := dbContainersList(d.db, cTypeSnapshot)
+	cNames, err := store.ContainersList(d.db, store.CTypeSnapshot)
 	if err != nil {
 		return err
 	}
@@ -2418,7 +2428,7 @@ func patchUpdateFromV15(d *Daemon) error {
 	// munge all LVM-backed containers' LV names to match what is
 	// required for snapshot support
 
-	cNames, err := dbContainersList(d.db, cTypeRegular)
+	cNames, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/profiles.go b/lxd/profiles.go
index 75907e562..e229379c4 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -11,6 +11,7 @@ import (
 	"github.com/gorilla/mux"
 	_ "github.com/mattn/go-sqlite3"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -21,7 +22,7 @@ import (
 
 /* This is used for both profiles post and profile put */
 func profilesGet(d *Daemon, r *http.Request) Response {
-	results, err := dbProfiles(d.db)
+	results, err := store.Profiles(d.db)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -64,7 +65,7 @@ func profilesPost(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("No name provided"))
 	}
 
-	_, profile, _ := dbProfileGet(d.db, req.Name)
+	_, profile, _ := store.ProfileGet(d.db, req.Name)
 	if profile != nil {
 		return BadRequest(fmt.Errorf("The profile already exists"))
 	}
@@ -88,7 +89,7 @@ func profilesPost(d *Daemon, r *http.Request) Response {
 	}
 
 	// Update DB entry
-	_, err = dbProfileCreate(d.db, req.Name, req.Description, req.Config, req.Devices)
+	_, err = store.ProfileCreate(d.db, req.Name, req.Description, req.Config, req.Devices)
 	if err != nil {
 		return SmartError(
 			fmt.Errorf("Error inserting %s into database: %s", req.Name, err))
@@ -103,12 +104,12 @@ var profilesCmd = Command{
 	post: profilesPost}
 
 func doProfileGet(d *Daemon, name string) (*api.Profile, error) {
-	_, profile, err := dbProfileGet(d.db, name)
+	_, profile, err := store.ProfileGet(d.db, name)
 	if err != nil {
 		return nil, err
 	}
 
-	cts, err := dbProfileContainersGet(d.db, name)
+	cts, err := store.ProfileContainersGet(d.db, name)
 	if err != nil {
 		return nil, err
 	}
@@ -137,7 +138,7 @@ func profileGet(d *Daemon, r *http.Request) Response {
 func getContainersWithProfile(d *Daemon, profile string) []container {
 	results := []container{}
 
-	output, err := dbProfileContainersGet(d.db, profile)
+	output, err := store.ProfileContainersGet(d.db, profile)
 	if err != nil {
 		return results
 	}
@@ -157,7 +158,7 @@ func getContainersWithProfile(d *Daemon, profile string) []container {
 func profilePut(d *Daemon, r *http.Request) Response {
 	// Get the profile
 	name := mux.Vars(r)["name"]
-	id, profile, err := dbProfileGet(d.db, name)
+	id, profile, err := store.ProfileGet(d.db, name)
 	if err != nil {
 		return SmartError(fmt.Errorf("Failed to retrieve profile='%s'", name))
 	}
@@ -180,7 +181,7 @@ func profilePut(d *Daemon, r *http.Request) Response {
 func profilePatch(d *Daemon, r *http.Request) Response {
 	// Get the profile
 	name := mux.Vars(r)["name"]
-	id, profile, err := dbProfileGet(d.db, name)
+	id, profile, err := store.ProfileGet(d.db, name)
 	if err != nil {
 		return SmartError(fmt.Errorf("Failed to retrieve profile='%s'", name))
 	}
@@ -258,7 +259,7 @@ func profilePost(d *Daemon, r *http.Request) Response {
 	}
 
 	// Check that the name isn't already in use
-	id, _, _ := dbProfileGet(d.db, req.Name)
+	id, _, _ := store.ProfileGet(d.db, req.Name)
 	if id > 0 {
 		return Conflict
 	}
@@ -271,7 +272,7 @@ func profilePost(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("Invalid profile name '%s'", req.Name))
 	}
 
-	err := dbProfileUpdate(d.db, name, req.Name)
+	err := store.ProfileUpdate(d.db, name, req.Name)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -293,7 +294,7 @@ func profileDelete(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("Profile is currently in use"))
 	}
 
-	err = dbProfileDelete(d.db, name)
+	err = store.ProfileDelete(d.db, name)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/profiles_test.go b/lxd/profiles_test.go
index 34d375684..01b211f94 100644
--- a/lxd/profiles_test.go
+++ b/lxd/profiles_test.go
@@ -3,6 +3,8 @@ package main
 import (
 	"database/sql"
 	"testing"
+
+	"github.com/lxc/lxd/lxd/store"
 )
 
 func Test_removing_a_profile_deletes_associated_configuration_entries(t *testing.T) {
@@ -28,14 +30,14 @@ func Test_removing_a_profile_deletes_associated_configuration_entries(t *testing
 		t.Fatal(err)
 	}
 
-	// Delete the profile we just created with dbProfileDelete
-	err = dbProfileDelete(db, "theprofile")
+	// Delete the profile we just created with store.ProfileDelete
+	err = store.ProfileDelete(db, "theprofile")
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	// Make sure there are 0 profiles_devices entries left.
-	devices, err := dbDevices(d.db, "theprofile", true)
+	devices, err := store.Devices(d.db, "theprofile", true)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -44,7 +46,7 @@ func Test_removing_a_profile_deletes_associated_configuration_entries(t *testing
 	}
 
 	// Make sure there are 0 profiles_config entries left.
-	config, err := dbProfileConfig(d.db, "theprofile")
+	config, err := store.ProfileConfig(d.db, "theprofile")
 	if err == nil {
 		t.Fatal("found the profile!")
 	}
diff --git a/lxd/profiles_utils.go b/lxd/profiles_utils.go
index d63bdb7f1..86f68e533 100644
--- a/lxd/profiles_utils.go
+++ b/lxd/profiles_utils.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"reflect"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared/api"
 )
 
@@ -41,7 +42,7 @@ func doProfileUpdate(d *Daemon, name string, id int64, profile *api.Profile, req
 			// Check what profile the device comes from
 			profiles := container.Profiles()
 			for i := len(profiles) - 1; i >= 0; i-- {
-				_, profile, err := dbProfileGet(d.db, profiles[i])
+				_, profile, err := store.ProfileGet(d.db, profiles[i])
 				if err != nil {
 					return SmartError(err)
 				}
@@ -63,13 +64,13 @@ func doProfileUpdate(d *Daemon, name string, id int64, profile *api.Profile, req
 	}
 
 	// Update the database
-	tx, err := dbBegin(d.db)
+	tx, err := store.Begin(d.db)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	if profile.Description != req.Description {
-		err = dbProfileDescriptionUpdate(tx, id, req.Description)
+		err = store.ProfileDescriptionUpdate(tx, id, req.Description)
 		if err != nil {
 			tx.Rollback()
 			return SmartError(err)
@@ -78,7 +79,7 @@ func doProfileUpdate(d *Daemon, name string, id int64, profile *api.Profile, req
 
 	// Optimize for description-only changes
 	if reflect.DeepEqual(profile.Config, req.Config) && reflect.DeepEqual(profile.Devices, req.Devices) {
-		err = txCommit(tx)
+		err = store.TxCommit(tx)
 		if err != nil {
 			return SmartError(err)
 		}
@@ -86,33 +87,33 @@ func doProfileUpdate(d *Daemon, name string, id int64, profile *api.Profile, req
 		return EmptySyncResponse
 	}
 
-	err = dbProfileConfigClear(tx, id)
+	err = store.ProfileConfigClear(tx, id)
 	if err != nil {
 		tx.Rollback()
 		return SmartError(err)
 	}
 
-	err = dbProfileConfigAdd(tx, id, req.Config)
+	err = store.ProfileConfigAdd(tx, id, req.Config)
 	if err != nil {
 		tx.Rollback()
 		return SmartError(err)
 	}
 
-	err = dbDevicesAdd(tx, "profile", id, req.Devices)
+	err = store.DevicesAdd(tx, "profile", id, req.Devices)
 	if err != nil {
 		tx.Rollback()
 		return SmartError(err)
 	}
 
-	err = txCommit(tx)
+	err = store.TxCommit(tx)
 	if err != nil {
 		return SmartError(err)
 	}
 
-	// Update all the containers using the profile. Must be done after txCommit due to DB lock.
+	// Update all the containers using the profile. Must be done after db.TxCommit due to DB lock.
 	failures := map[string]error{}
 	for _, c := range containers {
-		err = c.Update(containerArgs{
+		err = c.Update(store.ContainerArgs{
 			Architecture: c.Architecture(),
 			Ephemeral:    c.IsEphemeral(),
 			Config:       c.LocalConfig(),
diff --git a/lxd/response.go b/lxd/response.go
index b423bdf9c..f0fce2ae1 100644
--- a/lxd/response.go
+++ b/lxd/response.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/mattn/go-sqlite3"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 )
@@ -320,11 +321,11 @@ func SmartError(err error) Response {
 		return NotFound
 	case sql.ErrNoRows:
 		return NotFound
-	case NoSuchObjectError:
+	case store.NoSuchObjectError:
 		return NotFound
 	case os.ErrPermission:
 		return Forbidden
-	case DbErrAlreadyDefined:
+	case store.DbErrAlreadyDefined:
 		return Conflict
 	case sqlite3.ErrConstraintUnique:
 		return Conflict
diff --git a/lxd/storage.go b/lxd/storage.go
index 321c0967a..5891eb2bb 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -12,6 +12,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
@@ -317,7 +318,7 @@ func storageCoreInit(driver string) (storage, error) {
 
 func storageInit(d *Daemon, poolName string, volumeName string, volumeType int) (storage, error) {
 	// Load the storage pool.
-	poolID, pool, err := dbStoragePoolGet(d.db, poolName)
+	poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return nil, err
 	}
@@ -332,7 +333,7 @@ func storageInit(d *Daemon, poolName string, volumeName string, volumeType int)
 	// Load the storage volume.
 	volume := &api.StorageVolume{}
 	if volumeName != "" && volumeType >= 0 {
-		_, volume, err = dbStoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
+		_, volume, err = store.StoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
 		if err != nil {
 			return nil, err
 		}
@@ -545,11 +546,11 @@ func storagePoolVolumeAttachInit(d *Daemon, poolName string, volumeName string,
 
 	st.SetStoragePoolVolumeWritable(&poolVolumePut)
 
-	poolID, err := dbStoragePoolGetID(d.db, poolName)
+	poolID, err := store.StoragePoolGetID(d.db, poolName)
 	if err != nil {
 		return nil, err
 	}
-	err = dbStoragePoolVolumeUpdate(d.db, volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config)
+	err = store.StoragePoolVolumeUpdate(d.db, volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config)
 	if err != nil {
 		return nil, err
 	}
@@ -572,7 +573,7 @@ func storagePoolVolumeContainerCreateInit(d *Daemon, poolName string, containerN
 
 func storagePoolVolumeContainerLoadInit(d *Daemon, containerName string) (storage, error) {
 	// Get the storage pool of a given container.
-	poolName, err := dbContainerPool(d.db, containerName)
+	poolName, err := store.ContainerPool(d.db, containerName)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 626c4fe02..95107111d 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -15,6 +15,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -562,7 +563,7 @@ func (s *storageBtrfs) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	err = dbStoragePoolVolumeDelete(
+	err = store.StoragePoolVolumeDelete(
 		s.d.db,
 		s.volume.Name,
 		storagePoolVolumeTypeCustom,
@@ -1463,7 +1464,7 @@ func btrfsSubVolumeQGroup(subvol string) (string, error) {
 		"-f")
 
 	if err != nil {
-		return "", NoSuchObjectError
+		return "", store.NoSuchObjectError
 	}
 
 	var qgroup string
@@ -2159,7 +2160,7 @@ func (s *storageBtrfs) StorageEntitySetQuota(volumeType int, size int64, data in
 
 	_, err := btrfsSubVolumeQGroup(subvol)
 	if err != nil {
-		if err != NoSuchObjectError {
+		if err != store.NoSuchObjectError {
 			return err
 		}
 
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 99b42592a..338b3b279 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -6,6 +6,7 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -487,7 +488,7 @@ func (s *storageCeph) StoragePoolVolumeDelete() error {
 	logger.Debugf(`Deleted RBD storage volume "%s" on storage pool "%s"`,
 		s.volume.Name, s.pool.Name)
 
-	err = dbStoragePoolVolumeDelete(
+	err = store.StoragePoolVolumeDelete(
 		s.d.db,
 		s.volume.Name,
 		storagePoolVolumeTypeCustom,
@@ -2321,7 +2322,7 @@ func (s *storageCeph) ImageDelete(fingerprint string) error {
 		fingerprint, storagePoolVolumeTypeNameImage, "readonly",
 		s.UserName)
 	if err != nil {
-		if err != NoSuchObjectError {
+		if err != store.NoSuchObjectError {
 			logger.Errorf(`Failed to list clones of RBD storage `+
 				`volume for image "%s" on storage pool "%s":
 				%s`, fingerprint, s.pool.Name, err)
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index f15bd5075..33638b810 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -7,6 +7,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -160,7 +161,7 @@ func (s *storageCeph) MigrationSource(c container, containerOnly bool) (Migratio
 		s.OSDPoolName, containerName,
 		storagePoolVolumeTypeNameContainer, s.UserName)
 	if err != nil {
-		if err != NoSuchObjectError {
+		if err != store.NoSuchObjectError {
 			logger.Errorf(`Failed to list snapshots for RBD storage volume "%s" on storage pool "%s": %s`, containerName, s.pool.Name, err)
 			return nil, err
 		}
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 31020b573..b55c461a4 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -10,6 +10,7 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 
@@ -356,7 +357,7 @@ func cephRBDSnapshotListClones(clusterName string, poolName string,
 	msg = strings.TrimSpace(msg)
 	clones := strings.Fields(msg)
 	if len(clones) == 0 {
-		return nil, NoSuchObjectError
+		return nil, store.NoSuchObjectError
 	}
 
 	return clones, nil
@@ -462,7 +463,7 @@ func cephRBDVolumeSnapshotRename(clusterName string, poolName string,
 // cephRBDVolumeGetParent will return the snapshot the RBD clone was created
 // from
 // - If the RBD storage volume is not a clone then this function will return
-//   NoSuchObjectError.
+//   store.NoSuchObjectError.
 // - The snapshot will be returned as
 //   <osd-pool-name>/<rbd-volume-name>@<rbd-snapshot-name>
 //   The caller will usually want to parse this according to its needs. This
@@ -482,7 +483,7 @@ func cephRBDVolumeGetParent(clusterName string, poolName string,
 
 	idx := strings.Index(msg, "parent: ")
 	if idx == -1 {
-		return "", NoSuchObjectError
+		return "", store.NoSuchObjectError
 	}
 
 	msg = msg[(idx + len("parent: ")):]
@@ -585,7 +586,7 @@ func cephRBDVolumeListSnapshots(clusterName string, poolName string,
 	}
 
 	if len(snapshots) == 0 {
-		return []string{}, NoSuchObjectError
+		return []string{}, store.NoSuchObjectError
 	}
 
 	return snapshots, nil
@@ -958,7 +959,7 @@ func cephContainerDelete(clusterName string, poolName string, volumeName string,
 			return 1
 		}
 	} else {
-		if err != NoSuchObjectError {
+		if err != store.NoSuchObjectError {
 			logger.Errorf(`Failed to retrieve snapshots of RBD `+
 				`storage volume: %s`, err)
 			return -1
@@ -1026,7 +1027,7 @@ func cephContainerDelete(clusterName string, poolName string, volumeName string,
 
 			return 0
 		} else {
-			if err != NoSuchObjectError {
+			if err != store.NoSuchObjectError {
 				logger.Errorf(`Failed to retrieve parent of `+
 					`RBD storage volume "%s"`, logEntry)
 				return -1
@@ -1088,7 +1089,7 @@ func cephContainerSnapshotDelete(clusterName string, poolName string,
 	clones, err := cephRBDSnapshotListClones(clusterName, poolName,
 		volumeName, volumeType, snapshotName, userName)
 	if err != nil {
-		if err != NoSuchObjectError {
+		if err != store.NoSuchObjectError {
 			logger.Errorf(`Failed to list clones of RBD `+
 				`snapshot "%s" of RBD storage volume "%s": %s`,
 				logSnapshotEntry, logImageEntry, err)
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 13776b2eb..4601e98af 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -205,7 +206,7 @@ func (s *storageDir) StoragePoolVolumeDelete() error {
 		return err
 	}
 
-	err = dbStoragePoolVolumeDelete(
+	err = store.StoragePoolVolumeDelete(
 		s.d.db,
 		s.volume.Name,
 		storagePoolVolumeTypeCustom,
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 79845615d..3c632c171 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -543,7 +544,7 @@ func (s *storageLvm) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	err = dbStoragePoolVolumeDelete(
+	err = store.StoragePoolVolumeDelete(
 		s.d.db,
 		s.volume.Name,
 		storagePoolVolumeTypeCustom,
@@ -1708,7 +1709,7 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte
 
 	// Update the database
 	s.volume.Config["size"] = shared.GetByteSizeString(size, 0)
-	err = dbStoragePoolVolumeUpdate(
+	err = store.StoragePoolVolumeUpdate(
 		s.d.db,
 		s.volume.Name,
 		volumeType,
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 5f7dbbf24..dbabd2c7d 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -7,6 +7,7 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
 )
@@ -671,7 +672,7 @@ func storageLVMThinpoolExists(vgName string, poolName string) (bool, error) {
 func storageLVMGetThinPoolUsers(d *Daemon) ([]string, error) {
 	results := []string{}
 
-	cNames, err := dbContainersList(d.db, cTypeRegular)
+	cNames, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return results, err
 	}
@@ -689,7 +690,7 @@ func storageLVMGetThinPoolUsers(d *Daemon) ([]string, error) {
 		}
 	}
 
-	imageNames, err := dbImagesGet(d.db, false)
+	imageNames, err := store.ImagesGet(d.db, false)
 	if err != nil {
 		return results, err
 	}
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index c49f2b373..ddab0f20b 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 )
@@ -91,7 +92,7 @@ func rsyncMigrationSource(c container, containerOnly bool) (MigrationStorageSour
 	return rsyncStorageSourceDriver{c, snapshots}, nil
 }
 
-func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) containerArgs {
+func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) store.ContainerArgs {
 	config := map[string]string{}
 
 	for _, ent := range snap.LocalConfig {
@@ -109,9 +110,9 @@ func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) conta
 	}
 
 	name := containerName + shared.SnapshotDelimiter + snap.GetName()
-	return containerArgs{
+	return store.ContainerArgs{
 		Name:         name,
-		Ctype:        cTypeSnapshot,
+		Ctype:        store.CTypeSnapshot,
 		Config:       config,
 		Profiles:     snap.Profiles,
 		Ephemeral:    snap.GetEphemeral(),
diff --git a/lxd/storage_pools.go b/lxd/storage_pools.go
index 59872bae9..521b2e001 100644
--- a/lxd/storage_pools.go
+++ b/lxd/storage_pools.go
@@ -8,6 +8,7 @@ import (
 	"strings"
 
 	"github.com/gorilla/mux"
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/version"
 )
@@ -21,8 +22,8 @@ func storagePoolsGet(d *Daemon, r *http.Request) Response {
 		recursion = 0
 	}
 
-	pools, err := dbStoragePools(d.db)
-	if err != nil && err != NoSuchObjectError {
+	pools, err := store.StoragePools(d.db)
+	if err != nil && err != store.NoSuchObjectError {
 		return SmartError(err)
 	}
 
@@ -32,7 +33,7 @@ func storagePoolsGet(d *Daemon, r *http.Request) Response {
 		if recursion == 0 {
 			resultString = append(resultString, fmt.Sprintf("/%s/storage-pools/%s", version.APIVersion, pool))
 		} else {
-			plID, pl, err := dbStoragePoolGet(d.db, pool)
+			plID, pl, err := store.StoragePoolGet(d.db, pool)
 			if err != nil {
 				continue
 			}
@@ -91,14 +92,14 @@ func storagePoolGet(d *Daemon, r *http.Request) Response {
 	poolName := mux.Vars(r)["name"]
 
 	// Get the existing storage pool.
-	poolID, pool, err := dbStoragePoolGet(d.db, poolName)
+	poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	// Get all users of the storage pool.
 	poolUsedBy, err := storagePoolUsedByGet(d.db, poolID, poolName)
-	if err != nil && err != NoSuchObjectError {
+	if err != nil && err != store.NoSuchObjectError {
 		return SmartError(err)
 	}
 	pool.UsedBy = poolUsedBy
@@ -114,7 +115,7 @@ func storagePoolPut(d *Daemon, r *http.Request) Response {
 	poolName := mux.Vars(r)["name"]
 
 	// Get the existing storage pool.
-	_, dbInfo, err := dbStoragePoolGet(d.db, poolName)
+	_, dbInfo, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -152,7 +153,7 @@ func storagePoolPatch(d *Daemon, r *http.Request) Response {
 	poolName := mux.Vars(r)["name"]
 
 	// Get the existing network
-	_, dbInfo, err := dbStoragePoolGet(d.db, poolName)
+	_, dbInfo, err := store.StoragePoolGet(d.db, poolName)
 	if dbInfo != nil {
 		return SmartError(err)
 	}
@@ -201,14 +202,14 @@ func storagePoolPatch(d *Daemon, r *http.Request) Response {
 func storagePoolDelete(d *Daemon, r *http.Request) Response {
 	poolName := mux.Vars(r)["name"]
 
-	poolID, err := dbStoragePoolGetID(d.db, poolName)
+	poolID, err := store.StoragePoolGetID(d.db, poolName)
 	if err != nil {
 		return NotFound
 	}
 
 	// Check if the storage pool has any volumes associated with it, if so
 	// error out.
-	volumeCount, err := dbStoragePoolVolumesGetNames(d.db, poolID)
+	volumeCount, err := store.StoragePoolVolumesGetNames(d.db, poolID)
 	if volumeCount > 0 {
 		return BadRequest(fmt.Errorf("storage pool \"%s\" has volumes attached to it", poolName))
 	}
@@ -232,7 +233,7 @@ func storagePoolDelete(d *Daemon, r *http.Request) Response {
 		return InternalError(err)
 	}
 
-	err = dbStoragePoolDelete(d.db, poolName)
+	err = dbStoragePoolDeleteAndUpdateCache(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index e1f3100ec..af1e0f5c6 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/version"
 )
@@ -61,7 +62,7 @@ func storagePoolUpdate(d *Daemon, name, newDescription string, newConfig map[str
 
 	// Update the database if something changed
 	if len(changedConfig) != 0 || newDescription != oldDescription {
-		err = dbStoragePoolUpdate(d.db, name, newDescription, newConfig)
+		err = store.StoragePoolUpdate(d.db, name, newDescription, newConfig)
 		if err != nil {
 			return err
 		}
@@ -81,13 +82,14 @@ func storagePoolUpdate(d *Daemon, name, newDescription string, newConfig map[str
 // /1.0/profiles/default
 func storagePoolUsedByGet(db *sql.DB, poolID int64, poolName string) ([]string, error) {
 	// Retrieve all non-custom volumes that exist on this storage pool.
-	volumes, err := dbStoragePoolVolumesGet(db, poolID, []int{storagePoolVolumeTypeContainer, storagePoolVolumeTypeImage, storagePoolVolumeTypeCustom})
-	if err != nil && err != NoSuchObjectError {
+	volumes, err := store.StoragePoolVolumesGet(db, poolID, []int{storagePoolVolumeTypeContainer, storagePoolVolumeTypeImage, storagePoolVolumeTypeCustom})
+	if err != nil && err != store.NoSuchObjectError {
 		return []string{}, err
 	}
 
 	// Retrieve all profiles that exist on this storage pool.
 	profiles, err := profilesUsingPoolGetNames(db, poolName)
+
 	if err != nil {
 		return []string{}, err
 	}
@@ -129,13 +131,13 @@ func storagePoolUsedByGet(db *sql.DB, poolID int64, poolName string) ([]string,
 func profilesUsingPoolGetNames(db *sql.DB, poolName string) ([]string, error) {
 	usedBy := []string{}
 
-	profiles, err := dbProfiles(db)
+	profiles, err := store.Profiles(db)
 	if err != nil {
 		return usedBy, err
 	}
 
 	for _, pName := range profiles {
-		_, profile, err := dbProfileGet(db, pName)
+		_, profile, err := store.ProfileGet(db, pName)
 		if err != nil {
 			return usedBy, err
 		}
@@ -162,7 +164,7 @@ func storagePoolDBCreate(d *Daemon, poolName, poolDescription string, driver str
 	}
 
 	// Check that the storage pool does not already exist.
-	_, err = dbStoragePoolGetID(d.db, poolName)
+	_, err = store.StoragePoolGetID(d.db, poolName)
 	if err == nil {
 		return fmt.Errorf("The storage pool already exists")
 	}
@@ -185,7 +187,7 @@ func storagePoolDBCreate(d *Daemon, poolName, poolDescription string, driver str
 	}
 
 	// Create the database entry for the storage pool.
-	_, err = dbStoragePoolCreate(d.db, poolName, poolDescription, driver, config)
+	_, err = dbStoragePoolCreateAndUpdateCache(d.db, poolName, poolDescription, driver, config)
 	if err != nil {
 		return fmt.Errorf("Error inserting %s into database: %s", poolName, err)
 	}
@@ -207,7 +209,7 @@ func storagePoolCreateInternal(d *Daemon, poolName, poolDescription string, driv
 		if !tryUndo {
 			return
 		}
-		dbStoragePoolDelete(d.db, poolName)
+		dbStoragePoolDeleteAndUpdateCache(d.db, poolName)
 	}()
 
 	s, err := storagePoolInit(d, poolName)
@@ -236,7 +238,7 @@ func storagePoolCreateInternal(d *Daemon, poolName, poolDescription string, driv
 	configDiff, _ := storageConfigDiff(config, postCreateConfig)
 	if len(configDiff) > 0 {
 		// Create the database entry for the storage pool.
-		err = dbStoragePoolUpdate(d.db, poolName, poolDescription, postCreateConfig)
+		err = store.StoragePoolUpdate(d.db, poolName, poolDescription, postCreateConfig)
 		if err != nil {
 			return fmt.Errorf("Error inserting %s into database: %s", poolName, err)
 		}
@@ -247,3 +249,48 @@ func storagePoolCreateInternal(d *Daemon, poolName, poolDescription string, driv
 
 	return nil
 }
+
+// Helper around the low-level DB API, which also updates the driver names
+// cache.
+func dbStoragePoolCreateAndUpdateCache(db *sql.DB, poolName string, poolDescription string, poolDriver string, poolConfig map[string]string) (int64, error) {
+	id, err := store.StoragePoolCreate(db, poolName, poolDescription, poolDriver, poolConfig)
+	if err != nil {
+		return id, err
+	}
+
+	// Update the storage drivers cache in api_1.0.go.
+	storagePoolDriversCacheLock.Lock()
+	drivers := readStoragePoolDriversCache()
+	if !shared.StringInSlice(poolDriver, drivers) {
+		drivers = append(drivers, poolDriver)
+	}
+	storagePoolDriversCacheVal.Store(drivers)
+	storagePoolDriversCacheLock.Unlock()
+
+	return id, nil
+}
+
+// Helper around the low-level DB API, which also updates the driver names
+// cache.
+func dbStoragePoolDeleteAndUpdateCache(db *sql.DB, poolName string) error {
+	pool, err := store.StoragePoolDelete(db, poolName)
+	if err != nil {
+		return err
+	}
+
+	// Update the storage drivers cache in api_1.0.go.
+	storagePoolDriversCacheLock.Lock()
+	drivers := readStoragePoolDriversCache()
+	for i := 0; i < len(drivers); i++ {
+		if drivers[i] == pool.Driver {
+			drivers[i] = drivers[len(drivers)-1]
+			drivers[len(drivers)-1] = ""
+			drivers = drivers[:len(drivers)-1]
+			break
+		}
+	}
+	storagePoolDriversCacheVal.Store(drivers)
+	storagePoolDriversCacheLock.Unlock()
+
+	return err
+}
diff --git a/lxd/storage_shared.go b/lxd/storage_shared.go
index fd5f1c6ba..a559f0c36 100644
--- a/lxd/storage_shared.go
+++ b/lxd/storage_shared.go
@@ -3,6 +3,7 @@ package main
 import (
 	"fmt"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -106,7 +107,7 @@ func (s *storageShared) createImageDbPoolVolume(fingerprint string) error {
 	}
 
 	// Create a db entry for the storage volume of the image.
-	_, err = dbStoragePoolVolumeCreate(s.d.db, fingerprint, "", storagePoolVolumeTypeImage, s.poolID, volumeConfig)
+	_, err = store.StoragePoolVolumeCreate(s.d.db, fingerprint, "", storagePoolVolumeTypeImage, s.poolID, volumeConfig)
 	if err != nil {
 		// Try to delete the db entry on error.
 		s.deleteImageDbPoolVolume(fingerprint)
@@ -117,7 +118,7 @@ func (s *storageShared) createImageDbPoolVolume(fingerprint string) error {
 }
 
 func (s *storageShared) deleteImageDbPoolVolume(fingerprint string) error {
-	err := dbStoragePoolVolumeDelete(s.d.db, fingerprint, storagePoolVolumeTypeImage, s.poolID)
+	err := store.StoragePoolVolumeDelete(s.d.db, fingerprint, storagePoolVolumeTypeImage, s.poolID)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/storage_utils.go b/lxd/storage_utils.go
index dbb901550..b11940f37 100644
--- a/lxd/storage_utils.go
+++ b/lxd/storage_utils.go
@@ -7,6 +7,7 @@ import (
 	"syscall"
 	"time"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 )
 
@@ -157,13 +158,13 @@ const snapshotsDirMode os.FileMode = 0700
 
 // Detect whether LXD already uses the given storage pool.
 func lxdUsesPool(db *sql.DB, onDiskPoolName string, driver string, onDiskProperty string) (bool, string, error) {
-	pools, err := dbStoragePools(db)
-	if err != nil && err != NoSuchObjectError {
+	pools, err := store.StoragePools(db)
+	if err != nil && err != store.NoSuchObjectError {
 		return false, "", err
 	}
 
 	for _, pool := range pools {
-		_, pl, err := dbStoragePoolGet(db, pool)
+		_, pl, err := store.StoragePoolGet(db, pool)
 		if err != nil {
 			continue
 		}
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index fc7596088..235b99bce 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -7,6 +7,7 @@ import (
 	"strconv"
 
 	"github.com/gorilla/mux"
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/version"
@@ -25,15 +26,15 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) Response {
 
 	// Retrieve ID of the storage pool (and check if the storage pool
 	// exists).
-	poolID, err := dbStoragePoolGetID(d.db, poolName)
+	poolID, err := store.StoragePoolGetID(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	// Get all volumes currently attached to the storage pool by ID of the
 	// pool.
-	volumes, err := dbStoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes)
-	if err != nil && err != NoSuchObjectError {
+	volumes, err := store.StoragePoolVolumesGet(d.db, poolID, supportedVolumeTypes)
+	if err != nil && err != store.NoSuchObjectError {
 		return SmartError(err)
 	}
 
@@ -92,14 +93,14 @@ func storagePoolVolumesTypeGet(d *Daemon, r *http.Request) Response {
 
 	// Retrieve ID of the storage pool (and check if the storage pool
 	// exists).
-	poolID, err := dbStoragePoolGetID(d.db, poolName)
+	poolID, err := store.StoragePoolGetID(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	// Get the names of all storage volumes of a given volume type currently
 	// attached to the storage pool.
-	volumes, err := dbStoragePoolVolumesGetType(d.db, volumeType, poolID)
+	volumes, err := store.StoragePoolVolumesGetType(d.db, volumeType, poolID)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -114,7 +115,7 @@ func storagePoolVolumesTypeGet(d *Daemon, r *http.Request) Response {
 			}
 			resultString = append(resultString, fmt.Sprintf("/%s/storage-pools/%s/volumes/%s/%s", version.APIVersion, poolName, apiEndpoint, volume))
 		} else {
-			_, vol, err := dbStoragePoolVolumeGetType(d.db, volume, volumeType, poolID)
+			_, vol, err := store.StoragePoolVolumeGetType(d.db, volume, volumeType, poolID)
 			if err != nil {
 				continue
 			}
@@ -202,13 +203,13 @@ func storagePoolVolumeTypeGet(d *Daemon, r *http.Request) Response {
 
 	// Get the ID of the storage pool the storage volume is supposed to be
 	// attached to.
-	poolID, err := dbStoragePoolGetID(d.db, poolName)
+	poolID, err := store.StoragePoolGetID(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	// Get the storage volume.
-	_, volume, err := dbStoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
+	_, volume, err := store.StoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -246,13 +247,13 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request) Response {
 		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
 	}
 
-	poolID, pool, err := dbStoragePoolGet(d.db, poolName)
+	poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	// Get the existing storage volume.
-	_, volume, err := dbStoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
+	_, volume, err := store.StoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
 	if err != nil {
 		return SmartError(err)
 	}
@@ -308,13 +309,13 @@ func storagePoolVolumeTypePatch(d *Daemon, r *http.Request) Response {
 
 	// Get the ID of the storage pool the storage volume is supposed to be
 	// attached to.
-	poolID, pool, err := dbStoragePoolGet(d.db, poolName)
+	poolID, pool, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return SmartError(err)
 	}
 
 	// Get the existing storage volume.
-	_, volume, err := dbStoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
+	_, volume, err := store.StoragePoolVolumeGetType(d.db, volumeName, volumeType, poolID)
 	if err != nil {
 		return SmartError(err)
 	}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 4e7fe48ff..2e32373cd 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -6,23 +6,23 @@ import (
 	"path/filepath"
 	"strings"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/version"
 )
 
+// XXX: backward compatible declarations, introduced when the db code was
+//      extracted to its own package. We should eventually clean this up.
 const (
-	storagePoolVolumeTypeContainer = iota
-	storagePoolVolumeTypeImage
-	storagePoolVolumeTypeCustom
+	storagePoolVolumeTypeContainer = store.StoragePoolVolumeTypeContainer
+	storagePoolVolumeTypeImage     = store.StoragePoolVolumeTypeImage
+	storagePoolVolumeTypeCustom    = store.StoragePoolVolumeTypeCustom
 )
 
-// Leave the string type in here! This guarantees that go treats this is as a
-// typed string constant. Removing it causes go to treat these as untyped string
-// constants which is not what we want.
 const (
-	storagePoolVolumeTypeNameContainer string = "container"
-	storagePoolVolumeTypeNameImage     string = "image"
-	storagePoolVolumeTypeNameCustom    string = "custom"
+	storagePoolVolumeTypeNameContainer = store.StoragePoolVolumeTypeNameContainer
+	storagePoolVolumeTypeNameImage     = store.StoragePoolVolumeTypeNameImage
+	storagePoolVolumeTypeNameCustom    = store.StoragePoolVolumeTypeNameCustom
 )
 
 // Leave the string type in here! This guarantees that go treats this is as a
@@ -63,16 +63,7 @@ func storagePoolVolumeTypeNameToAPIEndpoint(volumeTypeName string) (string, erro
 }
 
 func storagePoolVolumeTypeToName(volumeType int) (string, error) {
-	switch volumeType {
-	case storagePoolVolumeTypeContainer:
-		return storagePoolVolumeTypeNameContainer, nil
-	case storagePoolVolumeTypeImage:
-		return storagePoolVolumeTypeNameImage, nil
-	case storagePoolVolumeTypeCustom:
-		return storagePoolVolumeTypeNameCustom, nil
-	}
-
-	return "", fmt.Errorf("invalid storage volume type")
+	return store.StoragePoolVolumeTypeToName(volumeType)
 }
 
 func storagePoolVolumeTypeToAPIEndpoint(volumeType int) (string, error) {
@@ -160,14 +151,14 @@ func storagePoolVolumeUpdate(d *Daemon, poolName string, volumeName string, volu
 		s.SetStoragePoolVolumeWritable(&newWritable)
 	}
 
-	poolID, err := dbStoragePoolGetID(d.db, poolName)
+	poolID, err := store.StoragePoolGetID(d.db, poolName)
 	if err != nil {
 		return err
 	}
 
 	// Update the database if something changed
 	if len(changedConfig) != 0 || newDescription != oldDescription {
-		err = dbStoragePoolVolumeUpdate(d.db, volumeName, volumeType, poolID, newDescription, newConfig)
+		err = store.StoragePoolVolumeUpdate(d.db, volumeName, volumeType, poolID, newDescription, newConfig)
 		if err != nil {
 			return err
 		}
@@ -181,7 +172,7 @@ func storagePoolVolumeUpdate(d *Daemon, poolName string, volumeName string, volu
 
 func storagePoolVolumeUsedByContainersGet(d *Daemon, volumeName string,
 	volumeTypeName string) ([]string, error) {
-	cts, err := dbContainersList(d.db, cTypeRegular)
+	cts, err := store.ContainersList(d.db, store.CTypeRegular)
 	if err != nil {
 		return []string{}, err
 	}
@@ -261,13 +252,13 @@ func storagePoolVolumeUsedByGet(d *Daemon, volumeName string, volumeTypeName str
 func profilesUsingPoolVolumeGetNames(db *sql.DB, volumeName string, volumeType string) ([]string, error) {
 	usedBy := []string{}
 
-	profiles, err := dbProfiles(db)
+	profiles, err := store.Profiles(db)
 	if err != nil {
 		return usedBy, err
 	}
 
 	for _, pName := range profiles {
-		_, profile, err := dbProfileGet(db, pName)
+		_, profile, err := store.ProfileGet(db, pName)
 		if err != nil {
 			return usedBy, err
 		}
@@ -318,14 +309,14 @@ func storagePoolVolumeDBCreate(d *Daemon, poolName string, volumeName, volumeDes
 	}
 
 	// Load storage pool the volume will be attached to.
-	poolID, poolStruct, err := dbStoragePoolGet(d.db, poolName)
+	poolID, poolStruct, err := store.StoragePoolGet(d.db, poolName)
 	if err != nil {
 		return err
 	}
 
 	// Check that a storage volume of the same storage volume type does not
 	// already exist.
-	volumeID, _ := dbStoragePoolVolumeGetTypeID(d.db, volumeName, volumeType, poolID)
+	volumeID, _ := store.StoragePoolVolumeGetTypeID(d.db, volumeName, volumeType, poolID)
 	if volumeID > 0 {
 		return fmt.Errorf("a storage volume of type %s does already exist", volumeTypeName)
 	}
@@ -347,7 +338,7 @@ func storagePoolVolumeDBCreate(d *Daemon, poolName string, volumeName, volumeDes
 	}
 
 	// Create the database entry for the storage volume.
-	_, err = dbStoragePoolVolumeCreate(d.db, volumeName, volumeDescription, volumeType, poolID, volumeConfig)
+	_, err = store.StoragePoolVolumeCreate(d.db, volumeName, volumeDescription, volumeType, poolID, volumeConfig)
 	if err != nil {
 		return fmt.Errorf("Error inserting %s of type %s into database: %s", poolName, volumeTypeName, err)
 	}
@@ -377,7 +368,7 @@ func storagePoolVolumeCreateInternal(d *Daemon, poolName string, volumeName, vol
 	// Create storage volume.
 	err = s.StoragePoolVolumeCreate()
 	if err != nil {
-		dbStoragePoolVolumeDelete(d.db, volumeName, volumeType, poolID)
+		store.StoragePoolVolumeDelete(d.db, volumeName, volumeType, poolID)
 		return err
 	}
 
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 652ee6f91..c86e2b7d1 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/store"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
@@ -409,7 +410,7 @@ func (s *storageZfs) StoragePoolVolumeDelete() error {
 		}
 	}
 
-	err = dbStoragePoolVolumeDelete(
+	err = store.StoragePoolVolumeDelete(
 		s.d.db,
 		s.volume.Name,
 		storagePoolVolumeTypeCustom,
diff --git a/lxd/db_certificates.go b/lxd/store/certificates.go
similarity index 65%
rename from lxd/db_certificates.go
rename to lxd/store/certificates.go
index 1f0c0b2be..0a4e3460b 100644
--- a/lxd/db_certificates.go
+++ b/lxd/store/certificates.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -6,9 +6,9 @@ import (
 	_ "github.com/mattn/go-sqlite3"
 )
 
-// dbCertInfo is here to pass the certificates content
+// CertInfo is here to pass the certificates content
 // from the database around
-type dbCertInfo struct {
+type CertInfo struct {
 	ID          int
 	Fingerprint string
 	Type        int
@@ -16,8 +16,8 @@ type dbCertInfo struct {
 	Certificate string
 }
 
-// dbCertsGet returns all certificates from the DB as CertBaseInfo objects.
-func dbCertsGet(db *sql.DB) (certs []*dbCertInfo, err error) {
+// CertsGet returns all certificates from the DB as CertBaseInfo objects.
+func CertsGet(db *sql.DB) (certs []*CertInfo, err error) {
 	rows, err := dbQuery(
 		db,
 		"SELECT id, fingerprint, type, name, certificate FROM certificates",
@@ -29,7 +29,7 @@ func dbCertsGet(db *sql.DB) (certs []*dbCertInfo, err error) {
 	defer rows.Close()
 
 	for rows.Next() {
-		cert := new(dbCertInfo)
+		cert := new(CertInfo)
 		rows.Scan(
 			&cert.ID,
 			&cert.Fingerprint,
@@ -43,13 +43,13 @@ func dbCertsGet(db *sql.DB) (certs []*dbCertInfo, err error) {
 	return certs, nil
 }
 
-// dbCertGet gets an CertBaseInfo object from the database.
+// CertGet gets an CertBaseInfo object from the database.
 // The argument fingerprint will be queried with a LIKE query, means you can
 // pass a shortform and will get the full fingerprint.
 // There can never be more than one image with a given fingerprint, as it is
 // enforced by a UNIQUE constraint in the schema.
-func dbCertGet(db *sql.DB, fingerprint string) (cert *dbCertInfo, err error) {
-	cert = new(dbCertInfo)
+func CertGet(db *sql.DB, fingerprint string) (cert *CertInfo, err error) {
+	cert = new(CertInfo)
 
 	inargs := []interface{}{fingerprint + "%"}
 	outfmt := []interface{}{
@@ -74,10 +74,10 @@ func dbCertGet(db *sql.DB, fingerprint string) (cert *dbCertInfo, err error) {
 	return cert, err
 }
 
-// dbCertSave stores a CertBaseInfo object in the db,
-// it will ignore the ID field from the dbCertInfo.
-func dbCertSave(db *sql.DB, cert *dbCertInfo) error {
-	tx, err := dbBegin(db)
+// CertSave stores a CertBaseInfo object in the db,
+// it will ignore the ID field from the CertInfo.
+func CertSave(db *sql.DB, cert *CertInfo) error {
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -105,12 +105,12 @@ func dbCertSave(db *sql.DB, cert *dbCertInfo) error {
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
-// dbCertDelete deletes a certificate from the db.
-func dbCertDelete(db *sql.DB, fingerprint string) error {
-	_, err := dbExec(db, "DELETE FROM certificates WHERE fingerprint=?", fingerprint)
+// CertDelete deletes a certificate from the db.
+func CertDelete(db *sql.DB, fingerprint string) error {
+	_, err := Exec(db, "DELETE FROM certificates WHERE fingerprint=?", fingerprint)
 	if err != nil {
 		return err
 	}
@@ -118,8 +118,8 @@ func dbCertDelete(db *sql.DB, fingerprint string) error {
 	return nil
 }
 
-func dbCertUpdate(db *sql.DB, fingerprint string, certName string, certType int) error {
-	tx, err := dbBegin(db)
+func CertUpdate(db *sql.DB, fingerprint string, certName string, certType int) error {
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -130,7 +130,7 @@ func dbCertUpdate(db *sql.DB, fingerprint string, certName string, certType int)
 		return err
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 
 	return err
 }
diff --git a/lxd/db_config.go b/lxd/store/config.go
similarity index 81%
rename from lxd/db_config.go
rename to lxd/store/config.go
index d61395e60..6f17cfd18 100644
--- a/lxd/db_config.go
+++ b/lxd/store/config.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -6,7 +6,7 @@ import (
 	_ "github.com/mattn/go-sqlite3"
 )
 
-func dbConfigValuesGet(db *sql.DB) (map[string]string, error) {
+func ConfigValuesGet(db *sql.DB) (map[string]string, error) {
 	q := "SELECT key, value FROM config"
 	rows, err := dbQuery(db, q)
 	if err != nil {
@@ -25,8 +25,8 @@ func dbConfigValuesGet(db *sql.DB) (map[string]string, error) {
 	return results, nil
 }
 
-func dbConfigValueSet(db *sql.DB, key string, value string) error {
-	tx, err := dbBegin(db)
+func ConfigValueSet(db *sql.DB, key string, value string) error {
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -52,7 +52,7 @@ func dbConfigValueSet(db *sql.DB, key string, value string) error {
 		}
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 	if err != nil {
 		return err
 	}
diff --git a/lxd/db_containers.go b/lxd/store/containers.go
similarity index 72%
rename from lxd/db_containers.go
rename to lxd/store/containers.go
index 87cc98868..c52e3cb90 100644
--- a/lxd/db_containers.go
+++ b/lxd/store/containers.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -12,20 +12,41 @@ import (
 	log "gopkg.in/inconshreveable/log15.v2"
 )
 
-type containerType int
+// ContainerArgs is a value object holding all db-related details about a
+// container.
+type ContainerArgs struct {
+	// Don't set manually
+	Id int
+
+	Description  string
+	Architecture int
+	BaseImage    string
+	Config       map[string]string
+	CreationDate time.Time
+	LastUsedDate time.Time
+	Ctype        ContainerType
+	Devices      types.Devices
+	Ephemeral    bool
+	Name         string
+	Profiles     []string
+	Stateful     bool
+}
+
+// ContainerType encodes the type of container (either regular or snapshot).
+type ContainerType int
 
 const (
-	cTypeRegular  containerType = 0
-	cTypeSnapshot containerType = 1
+	CTypeRegular  ContainerType = 0
+	CTypeSnapshot ContainerType = 1
 )
 
-func dbContainerRemove(db *sql.DB, name string) error {
-	id, err := dbContainerId(db, name)
+func ContainerRemove(db *sql.DB, name string) error {
+	id, err := ContainerId(db, name)
 	if err != nil {
 		return err
 	}
 
-	_, err = dbExec(db, "DELETE FROM containers WHERE id=?", id)
+	_, err = Exec(db, "DELETE FROM containers WHERE id=?", id)
 	if err != nil {
 		return err
 	}
@@ -33,7 +54,7 @@ func dbContainerRemove(db *sql.DB, name string) error {
 	return nil
 }
 
-func dbContainerName(db *sql.DB, id int) (string, error) {
+func ContainerName(db *sql.DB, id int) (string, error) {
 	q := "SELECT name FROM containers WHERE id=?"
 	name := ""
 	arg1 := []interface{}{id}
@@ -42,7 +63,7 @@ func dbContainerName(db *sql.DB, id int) (string, error) {
 	return name, err
 }
 
-func dbContainerId(db *sql.DB, name string) (int, error) {
+func ContainerId(db *sql.DB, name string) (int, error) {
 	q := "SELECT id FROM containers WHERE name=?"
 	id := -1
 	arg1 := []interface{}{name}
@@ -51,11 +72,11 @@ func dbContainerId(db *sql.DB, name string) (int, error) {
 	return id, err
 }
 
-func dbContainerGet(db *sql.DB, name string) (containerArgs, error) {
+func ContainerGet(db *sql.DB, name string) (ContainerArgs, error) {
 	var used *time.Time // Hold the db-returned time
 	description := sql.NullString{}
 
-	args := containerArgs{}
+	args := ContainerArgs{}
 	args.Name = name
 
 	ephemInt := -1
@@ -88,13 +109,13 @@ func dbContainerGet(db *sql.DB, name string) (containerArgs, error) {
 		args.LastUsedDate = time.Unix(0, 0).UTC()
 	}
 
-	config, err := dbContainerConfig(db, args.Id)
+	config, err := ContainerConfig(db, args.Id)
 	if err != nil {
 		return args, err
 	}
 	args.Config = config
 
-	profiles, err := dbContainerProfiles(db, args.Id)
+	profiles, err := ContainerProfiles(db, args.Id)
 	if err != nil {
 		return args, err
 	}
@@ -102,7 +123,7 @@ func dbContainerGet(db *sql.DB, name string) (containerArgs, error) {
 
 	/* get container_devices */
 	args.Devices = types.Devices{}
-	newdevs, err := dbDevices(db, name, false)
+	newdevs, err := Devices(db, name, false)
 	if err != nil {
 		return args, err
 	}
@@ -114,13 +135,13 @@ func dbContainerGet(db *sql.DB, name string) (containerArgs, error) {
 	return args, nil
 }
 
-func dbContainerCreate(db *sql.DB, args containerArgs) (int, error) {
-	id, err := dbContainerId(db, args.Name)
+func ContainerCreate(db *sql.DB, args ContainerArgs) (int, error) {
+	id, err := ContainerId(db, args.Name)
 	if err == nil {
 		return 0, DbErrAlreadyDefined
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return 0, err
 	}
@@ -158,25 +179,25 @@ func dbContainerCreate(db *sql.DB, args containerArgs) (int, error) {
 	}
 	// TODO: is this really int64? we should fix it everywhere if so
 	id = int(id64)
-	if err := dbContainerConfigInsert(tx, id, args.Config); err != nil {
+	if err := ContainerConfigInsert(tx, id, args.Config); err != nil {
 		tx.Rollback()
 		return 0, err
 	}
 
-	if err := dbContainerProfilesInsert(tx, id, args.Profiles); err != nil {
+	if err := ContainerProfilesInsert(tx, id, args.Profiles); err != nil {
 		tx.Rollback()
 		return 0, err
 	}
 
-	if err := dbDevicesAdd(tx, "container", int64(id), args.Devices); err != nil {
+	if err := DevicesAdd(tx, "container", int64(id), args.Devices); err != nil {
 		tx.Rollback()
 		return 0, err
 	}
 
-	return id, txCommit(tx)
+	return id, TxCommit(tx)
 }
 
-func dbContainerConfigClear(tx *sql.Tx, id int) error {
+func ContainerConfigClear(tx *sql.Tx, id int) error {
 	_, err := tx.Exec("DELETE FROM containers_config WHERE container_id=?", id)
 	if err != nil {
 		return err
@@ -197,7 +218,7 @@ func dbContainerConfigClear(tx *sql.Tx, id int) error {
 	return err
 }
 
-func dbContainerConfigInsert(tx *sql.Tx, id int, config map[string]string) error {
+func ContainerConfigInsert(tx *sql.Tx, id int, config map[string]string) error {
 	str := "INSERT INTO containers_config (container_id, key, value) values (?, ?, ?)"
 	stmt, err := tx.Prepare(str)
 	if err != nil {
@@ -217,7 +238,7 @@ func dbContainerConfigInsert(tx *sql.Tx, id int, config map[string]string) error
 	return nil
 }
 
-func dbContainerConfigGet(db *sql.DB, id int, key string) (string, error) {
+func ContainerConfigGet(db *sql.DB, id int, key string) (string, error) {
 	q := "SELECT value FROM containers_config WHERE container_id=? AND key=?"
 	value := ""
 	arg1 := []interface{}{id, key}
@@ -226,22 +247,22 @@ func dbContainerConfigGet(db *sql.DB, id int, key string) (string, error) {
 	return value, err
 }
 
-func dbContainerConfigRemove(db *sql.DB, id int, name string) error {
-	_, err := dbExec(db, "DELETE FROM containers_config WHERE key=? AND container_id=?", name, id)
+func ContainerConfigRemove(db *sql.DB, id int, name string) error {
+	_, err := Exec(db, "DELETE FROM containers_config WHERE key=? AND container_id=?", name, id)
 	return err
 }
 
-func dbContainerSetStateful(db *sql.DB, id int, stateful bool) error {
+func ContainerSetStateful(db *sql.DB, id int, stateful bool) error {
 	statefulInt := 0
 	if stateful {
 		statefulInt = 1
 	}
 
-	_, err := dbExec(db, "UPDATE containers SET stateful=? WHERE id=?", statefulInt, id)
+	_, err := Exec(db, "UPDATE containers SET stateful=? WHERE id=?", statefulInt, id)
 	return err
 }
 
-func dbContainerProfilesInsert(tx *sql.Tx, id int, profiles []string) error {
+func ContainerProfilesInsert(tx *sql.Tx, id int, profiles []string) error {
 	applyOrder := 1
 	str := `INSERT INTO containers_profiles (container_id, profile_id, apply_order) VALUES
 		(?, (SELECT id FROM profiles WHERE name=?), ?);`
@@ -264,7 +285,7 @@ func dbContainerProfilesInsert(tx *sql.Tx, id int, profiles []string) error {
 }
 
 // Get a list of profiles for a given container id.
-func dbContainerProfiles(db *sql.DB, containerId int) ([]string, error) {
+func ContainerProfiles(db *sql.DB, containerId int) ([]string, error) {
 	var name string
 	var profiles []string
 
@@ -276,7 +297,7 @@ func dbContainerProfiles(db *sql.DB, containerId int) ([]string, error) {
 	inargs := []interface{}{containerId}
 	outfmt := []interface{}{name}
 
-	results, err := dbQueryScan(db, query, inargs, outfmt)
+	results, err := QueryScan(db, query, inargs, outfmt)
 	if err != nil {
 		return nil, err
 	}
@@ -290,8 +311,8 @@ func dbContainerProfiles(db *sql.DB, containerId int) ([]string, error) {
 	return profiles, nil
 }
 
-// dbContainerConfig gets the container configuration map from the DB
-func dbContainerConfig(db *sql.DB, containerId int) (map[string]string, error) {
+// ContainerConfig gets the container configuration map from the DB
+func ContainerConfig(db *sql.DB, containerId int) (map[string]string, error) {
 	var key, value string
 	q := `SELECT key, value FROM containers_config WHERE container_id=?`
 
@@ -299,7 +320,7 @@ func dbContainerConfig(db *sql.DB, containerId int) (map[string]string, error) {
 	outfmt := []interface{}{key, value}
 
 	// Results is already a slice here, not db Rows anymore.
-	results, err := dbQueryScan(db, q, inargs, outfmt)
+	results, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return nil, err //SmartError will wrap this and make "not found" errors pretty
 	}
@@ -316,12 +337,12 @@ func dbContainerConfig(db *sql.DB, containerId int) (map[string]string, error) {
 	return config, nil
 }
 
-func dbContainersList(db *sql.DB, cType containerType) ([]string, error) {
+func ContainersList(db *sql.DB, cType ContainerType) ([]string, error) {
 	q := fmt.Sprintf("SELECT name FROM containers WHERE type=? ORDER BY name")
 	inargs := []interface{}{cType}
 	var container string
 	outfmt := []interface{}{container}
-	result, err := dbQueryScan(db, q, inargs, outfmt)
+	result, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return nil, err
 	}
@@ -334,8 +355,8 @@ func dbContainersList(db *sql.DB, cType containerType) ([]string, error) {
 	return ret, nil
 }
 
-func dbContainerSetState(db *sql.DB, id int, state string) error {
-	tx, err := dbBegin(db)
+func ContainerSetState(db *sql.DB, id int, state string) error {
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -368,11 +389,11 @@ func dbContainerSetState(db *sql.DB, id int, state string) error {
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
-func dbContainerRename(db *sql.DB, oldName string, newName string) error {
-	tx, err := dbBegin(db)
+func ContainerRename(db *sql.DB, oldName string, newName string) error {
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -396,10 +417,10 @@ func dbContainerRename(db *sql.DB, oldName string, newName string) error {
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
-func dbContainerUpdate(tx *sql.Tx, id int, description string, architecture int, ephemeral bool) error {
+func ContainerUpdate(tx *sql.Tx, id int, description string, architecture int, ephemeral bool) error {
 	str := fmt.Sprintf("UPDATE containers SET description=?, architecture=?, ephemeral=? WHERE id=?")
 	stmt, err := tx.Prepare(str)
 	if err != nil {
@@ -419,21 +440,21 @@ func dbContainerUpdate(tx *sql.Tx, id int, description string, architecture int,
 	return nil
 }
 
-func dbContainerLastUsedUpdate(db *sql.DB, id int, date time.Time) error {
+func ContainerLastUsedUpdate(db *sql.DB, id int, date time.Time) error {
 	stmt := `UPDATE containers SET last_use_date=? WHERE id=?`
-	_, err := dbExec(db, stmt, date, id)
+	_, err := Exec(db, stmt, date, id)
 	return err
 }
 
-func dbContainerGetSnapshots(db *sql.DB, name string) ([]string, error) {
+func ContainerGetSnapshots(db *sql.DB, name string) ([]string, error) {
 	result := []string{}
 
 	regexp := name + shared.SnapshotDelimiter
 	length := len(regexp)
 	q := "SELECT name FROM containers WHERE type=? AND SUBSTR(name,1,?)=?"
-	inargs := []interface{}{cTypeSnapshot, length, regexp}
+	inargs := []interface{}{CTypeSnapshot, length, regexp}
 	outfmt := []interface{}{name}
-	dbResults, err := dbQueryScan(db, q, inargs, outfmt)
+	dbResults, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return result, err
 	}
@@ -446,7 +467,7 @@ func dbContainerGetSnapshots(db *sql.DB, name string) ([]string, error) {
 }
 
 // Get the storage pool of a given container.
-func dbContainerPool(db *sql.DB, containerName string) (string, error) {
+func ContainerPool(db *sql.DB, containerName string) (string, error) {
 	// Get container storage volume. Since container names are globally
 	// unique, and their storage volumes carry the same name, their storage
 	// volumes are unique too.
@@ -454,7 +475,7 @@ func dbContainerPool(db *sql.DB, containerName string) (string, error) {
 	query := `SELECT storage_pools.name FROM storage_pools
 JOIN storage_volumes ON storage_pools.id=storage_volumes.storage_pool_id
 WHERE storage_volumes.name=? AND storage_volumes.type=?`
-	inargs := []interface{}{containerName, storagePoolVolumeTypeContainer}
+	inargs := []interface{}{containerName, StoragePoolVolumeTypeContainer}
 	outargs := []interface{}{&poolName}
 
 	err := dbQueryRowScan(db, query, inargs, outargs)
diff --git a/lxd/db.go b/lxd/store/db.go
similarity index 93%
rename from lxd/db.go
rename to lxd/store/db.go
index a0978bd1b..426b59cce 100644
--- a/lxd/db.go
+++ b/lxd/store/db.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -224,8 +224,8 @@ func init() {
 	sql.Register("sqlite3_with_fk", &sqlite3.SQLiteDriver{ConnectHook: enableForeignKeys})
 }
 
-// Open the database with the correct parameters for LXD.
-func openDb(path string) (*sql.DB, error) {
+// OpenDb opens the database with the correct parameters for LXD.
+func OpenDb(path string) (*sql.DB, error) {
 	timeout := 5 // TODO - make this command-line configurable?
 
 	// These are used to tune the transaction BEGIN behavior instead of using the
@@ -237,8 +237,8 @@ func openDb(path string) (*sql.DB, error) {
 }
 
 // Create the initial (current) schema for a given SQLite DB connection.
-func createDb(db *sql.DB) (err error) {
-	latestVersion := dbGetSchema(db)
+func CreateDb(db *sql.DB, patchNames []string) (err error) {
+	latestVersion := GetSchema(db)
 
 	if latestVersion != 0 {
 		return nil
@@ -251,17 +251,17 @@ func createDb(db *sql.DB) (err error) {
 
 	// There isn't an entry for schema version, let's put it in.
 	insertStmt := `INSERT INTO schema (version, updated_at) values (?, strftime("%s"));`
-	_, err = db.Exec(insertStmt, dbGetLatestSchema())
+	_, err = db.Exec(insertStmt, GetLatestSchema())
 	if err != nil {
 		return err
 	}
 
 	// Mark all existing patches as applied
-	for _, p := range patches {
-		dbPatchesMarkApplied(db, p.name)
+	for _, patchName := range patchNames {
+		PatchesMarkApplied(db, patchName)
 	}
 
-	err = dbProfileCreateDefault(db)
+	err = ProfileCreateDefault(db)
 	if err != nil {
 		return err
 	}
@@ -269,7 +269,7 @@ func createDb(db *sql.DB) (err error) {
 	return nil
 }
 
-func dbGetSchema(db *sql.DB) (v int) {
+func GetSchema(db *sql.DB) (v int) {
 	arg1 := []interface{}{}
 	arg2 := []interface{}{&v}
 	q := "SELECT max(version) FROM schema"
@@ -280,7 +280,7 @@ func dbGetSchema(db *sql.DB) (v int) {
 	return v
 }
 
-func dbGetLatestSchema() int {
+func GetLatestSchema() int {
 	if len(dbUpdates) == 0 {
 		return 0
 	}
@@ -288,7 +288,7 @@ func dbGetLatestSchema() int {
 	return dbUpdates[len(dbUpdates)-1].version
 }
 
-func isDbLockedError(err error) bool {
+func IsDbLockedError(err error) bool {
 	if err == nil {
 		return false
 	}
@@ -311,13 +311,13 @@ func isNoMatchError(err error) bool {
 	return false
 }
 
-func dbBegin(db *sql.DB) (*sql.Tx, error) {
+func Begin(db *sql.DB) (*sql.Tx, error) {
 	for i := 0; i < 1000; i++ {
 		tx, err := db.Begin()
 		if err == nil {
 			return tx, nil
 		}
-		if !isDbLockedError(err) {
+		if !IsDbLockedError(err) {
 			logger.Debugf("DbBegin: error %q", err)
 			return nil, err
 		}
@@ -329,13 +329,13 @@ func dbBegin(db *sql.DB) (*sql.Tx, error) {
 	return nil, fmt.Errorf("DB is locked")
 }
 
-func txCommit(tx *sql.Tx) error {
+func TxCommit(tx *sql.Tx) error {
 	for i := 0; i < 1000; i++ {
 		err := tx.Commit()
 		if err == nil {
 			return nil
 		}
-		if !isDbLockedError(err) {
+		if !IsDbLockedError(err) {
 			logger.Debugf("Txcommit: error %q", err)
 			return err
 		}
@@ -356,7 +356,7 @@ func dbQueryRowScan(db *sql.DB, q string, args []interface{}, outargs []interfac
 		if isNoMatchError(err) {
 			return err
 		}
-		if !isDbLockedError(err) {
+		if !IsDbLockedError(err) {
 			return err
 		}
 		time.Sleep(30 * time.Millisecond)
@@ -373,7 +373,7 @@ func dbQuery(db *sql.DB, q string, args ...interface{}) (*sql.Rows, error) {
 		if err == nil {
 			return result, nil
 		}
-		if !isDbLockedError(err) {
+		if !IsDbLockedError(err) {
 			logger.Debugf("DbQuery: query %q error %q", q, err)
 			return nil, err
 		}
@@ -447,13 +447,13 @@ func doDbQueryScan(db *sql.DB, q string, args []interface{}, outargs []interface
  * The result will be an array (one per output row) of arrays (one per output argument)
  * of interfaces, containing pointers to the actual output arguments.
  */
-func dbQueryScan(db *sql.DB, q string, inargs []interface{}, outfmt []interface{}) ([][]interface{}, error) {
+func QueryScan(db *sql.DB, q string, inargs []interface{}, outfmt []interface{}) ([][]interface{}, error) {
 	for i := 0; i < 1000; i++ {
 		result, err := doDbQueryScan(db, q, inargs, outfmt)
 		if err == nil {
 			return result, nil
 		}
-		if !isDbLockedError(err) {
+		if !IsDbLockedError(err) {
 			logger.Debugf("DbQuery: query %q error %q", q, err)
 			return nil, err
 		}
@@ -465,13 +465,13 @@ func dbQueryScan(db *sql.DB, q string, inargs []interface{}, outfmt []interface{
 	return nil, fmt.Errorf("DB is locked")
 }
 
-func dbExec(db *sql.DB, q string, args ...interface{}) (sql.Result, error) {
+func Exec(db *sql.DB, q string, args ...interface{}) (sql.Result, error) {
 	for i := 0; i < 1000; i++ {
 		result, err := db.Exec(q, args...)
 		if err == nil {
 			return result, nil
 		}
-		if !isDbLockedError(err) {
+		if !IsDbLockedError(err) {
 			logger.Debugf("DbExec: query %q error %q", q, err)
 			return nil, err
 		}
diff --git a/lxd/db_test.go b/lxd/store/db_test.go
similarity index 85%
rename from lxd/db_test.go
rename to lxd/store/db_test.go
index fd55c32b3..01cfca8a1 100644
--- a/lxd/db_test.go
+++ b/lxd/store/db_test.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -54,10 +54,10 @@ func (s *dbTestSuite) CreateTestDb() *sql.DB {
 		s.Nil(err)
 	}
 
-	db, err := openDb(":memory:")
+	db, err := OpenDb(":memory:")
 	s.Nil(err)
-	s.Nil(createDb(db))
-	s.Nil(dbUpdatesApplyAll(db, false, nil))
+	s.Nil(CreateDb(db, []string{}))
+	s.Nil(UpdatesApplyAll(db, false, nil))
 	return db
 
 }
@@ -161,12 +161,12 @@ func (s *dbTestSuite) Test_deleting_an_image_cascades_on_related_tables() {
 }
 
 func (s *dbTestSuite) Test_initializing_db_is_idempotent() {
-	// This calls "createDb" once already.
+	// This calls "CreateDb" once already.
 	db := s.CreateTestDb()
 	defer db.Close()
 
 	// Let's call it a second time.
-	s.Nil(createDb(db))
+	s.Nil(CreateDb(db, []string{}))
 }
 
 func (s *dbTestSuite) Test_get_schema_returns_0_on_uninitialized_db() {
@@ -175,11 +175,11 @@ func (s *dbTestSuite) Test_get_schema_returns_0_on_uninitialized_db() {
 
 	db, err = sql.Open("sqlite3", ":memory:")
 	s.Nil(err)
-	result := dbGetSchema(db)
+	result := GetSchema(db)
 	s.Equal(0, result, "getSchema should return 0 on uninitialized db!")
 }
 
-func (s *dbTestSuite) Test_running_dbUpdateFromV6_adds_on_delete_cascade() {
+func (s *dbTestSuite) Test_running_UpdateFromV6_adds_on_delete_cascade() {
 	// Upgrading the database schema with updateFromV6 adds ON DELETE CASCADE
 	// to sqlite tables that require it, and conserve the data.
 
@@ -313,11 +313,11 @@ INSERT INTO containers_config (container_id, key, value) VALUES (1, 'thekey', 't
 
 	// The "foreign key" on containers_config now points to nothing.
 	// Let's run the schema upgrades.
-	err = dbUpdatesApplyAll(db, false, nil)
+	err = UpdatesApplyAll(db, false, nil)
 	s.Nil(err)
 
-	result := dbGetSchema(db)
-	s.Equal(result, dbGetLatestSchema(), "The schema is not at the latest version after update!")
+	result := GetSchema(db)
+	s.Equal(result, GetLatestSchema(), "The schema is not at the latest version after update!")
 
 	// Make sure there are 0 containers_config entries left.
 	statements = `SELECT count(*) FROM containers_config;`
@@ -326,11 +326,11 @@ INSERT INTO containers_config (container_id, key, value) VALUES (1, 'thekey', 't
 	s.Equal(count, 0, "updateDb did not delete orphaned child entries after adding ON DELETE CASCADE!")
 }
 
-func (s *dbTestSuite) Test_dbImageGet_finds_image_for_fingerprint() {
+func (s *dbTestSuite) Test_ImageGet_finds_image_for_fingerprint() {
 	var err error
 	var result *api.Image
 
-	_, result, err = dbImageGet(s.db, "fingerprint", false, false)
+	_, result, err = ImageGet(s.db, "fingerprint", false, false)
 	s.Nil(err)
 	s.NotNil(result)
 	s.Equal(result.Filename, "filename")
@@ -339,79 +339,79 @@ func (s *dbTestSuite) Test_dbImageGet_finds_image_for_fingerprint() {
 	s.Equal(result.UploadedAt.UTC(), time.Unix(1431547176, 0).UTC())
 }
 
-func (s *dbTestSuite) Test_dbImageGet_for_missing_fingerprint() {
+func (s *dbTestSuite) Test_ImageGet_for_missing_fingerprint() {
 	var err error
 
-	_, _, err = dbImageGet(s.db, "unknown", false, false)
+	_, _, err = ImageGet(s.db, "unknown", false, false)
 	s.Equal(err, sql.ErrNoRows)
 }
 
-func (s *dbTestSuite) Test_dbImageExists_true() {
+func (s *dbTestSuite) Test_ImageExists_true() {
 	var err error
 
-	exists, err := dbImageExists(s.db, "fingerprint")
+	exists, err := ImageExists(s.db, "fingerprint")
 	s.Nil(err)
 	s.True(exists)
 }
 
-func (s *dbTestSuite) Test_dbImageExists_false() {
+func (s *dbTestSuite) Test_ImageExists_false() {
 	var err error
 
-	exists, err := dbImageExists(s.db, "foobar")
+	exists, err := ImageExists(s.db, "foobar")
 	s.Nil(err)
 	s.False(exists)
 }
 
-func (s *dbTestSuite) Test_dbImageAliasGet_alias_exists() {
+func (s *dbTestSuite) Test_ImageAliasGet_alias_exists() {
 	var err error
 
-	_, alias, err := dbImageAliasGet(s.db, "somealias", true)
+	_, alias, err := ImageAliasGet(s.db, "somealias", true)
 	s.Nil(err)
 	s.Equal(alias.Target, "fingerprint")
 }
 
-func (s *dbTestSuite) Test_dbImageAliasGet_alias_does_not_exists() {
+func (s *dbTestSuite) Test_ImageAliasGet_alias_does_not_exists() {
 	var err error
 
-	_, _, err = dbImageAliasGet(s.db, "whatever", true)
+	_, _, err = ImageAliasGet(s.db, "whatever", true)
 	s.Equal(err, NoSuchObjectError)
 }
 
-func (s *dbTestSuite) Test_dbImageAliasAdd() {
+func (s *dbTestSuite) Test_ImageAliasAdd() {
 	var err error
 
-	err = dbImageAliasAdd(s.db, "Chaosphere", 1, "Someone will like the name")
+	err = ImageAliasAdd(s.db, "Chaosphere", 1, "Someone will like the name")
 	s.Nil(err)
 
-	_, alias, err := dbImageAliasGet(s.db, "Chaosphere", true)
+	_, alias, err := ImageAliasGet(s.db, "Chaosphere", true)
 	s.Nil(err)
 	s.Equal(alias.Target, "fingerprint")
 }
 
-func (s *dbTestSuite) Test_dbImageSourceGetCachedFingerprint() {
-	imageID, _, err := dbImageGet(s.db, "fingerprint", false, false)
+func (s *dbTestSuite) Test_ImageSourceGetCachedFingerprint() {
+	imageID, _, err := ImageGet(s.db, "fingerprint", false, false)
 	s.Nil(err)
 
-	err = dbImageSourceInsert(s.db, imageID, "server.remote", "simplestreams", "", "test")
+	err = ImageSourceInsert(s.db, imageID, "server.remote", "simplestreams", "", "test")
 	s.Nil(err)
 
-	fingerprint, err := dbImageSourceGetCachedFingerprint(s.db, "server.remote", "simplestreams", "test")
+	fingerprint, err := ImageSourceGetCachedFingerprint(s.db, "server.remote", "simplestreams", "test")
 	s.Nil(err)
 	s.Equal(fingerprint, "fingerprint")
 }
 
-func (s *dbTestSuite) Test_dbImageSourceGetCachedFingerprint_no_match() {
-	imageID, _, err := dbImageGet(s.db, "fingerprint", false, false)
+func (s *dbTestSuite) Test_ImageSourceGetCachedFingerprint_no_match() {
+	imageID, _, err := ImageGet(s.db, "fingerprint", false, false)
 	s.Nil(err)
 
-	err = dbImageSourceInsert(s.db, imageID, "server.remote", "simplestreams", "", "test")
+	err = ImageSourceInsert(s.db, imageID, "server.remote", "simplestreams", "", "test")
 	s.Nil(err)
 
-	_, err = dbImageSourceGetCachedFingerprint(s.db, "server.remote", "lxd", "test")
+	_, err = ImageSourceGetCachedFingerprint(s.db, "server.remote", "lxd", "test")
 	s.Equal(err, NoSuchObjectError)
 }
 
-func (s *dbTestSuite) Test_dbContainerConfig() {
+func (s *dbTestSuite) Test_ContainerConfig() {
 	var err error
 	var result map[string]string
 	var expected map[string]string
@@ -419,7 +419,7 @@ func (s *dbTestSuite) Test_dbContainerConfig() {
 	_, err = s.db.Exec("INSERT INTO containers_config (container_id, key, value) VALUES (1, 'something', 'something else');")
 	s.Nil(err)
 
-	result, err = dbContainerConfig(s.db, 1)
+	result, err = ContainerConfig(s.db, 1)
 	s.Nil(err)
 
 	expected = map[string]string{"thekey": "thevalue", "something": "something else"}
@@ -438,7 +438,7 @@ func (s *dbTestSuite) Test_dbProfileConfig() {
 	_, err = s.db.Exec("INSERT INTO profiles_config (profile_id, key, value) VALUES (2, 'something', 'something else');")
 	s.Nil(err)
 
-	result, err = dbProfileConfig(s.db, "theprofile")
+	result, err = ProfileConfig(s.db, "theprofile")
 	s.Nil(err)
 
 	expected = map[string]string{"thekey": "thevalue", "something": "something else"}
@@ -449,13 +449,13 @@ func (s *dbTestSuite) Test_dbProfileConfig() {
 	}
 }
 
-func (s *dbTestSuite) Test_dbContainerProfiles() {
+func (s *dbTestSuite) Test_ContainerProfiles() {
 	var err error
 	var result []string
 	var expected []string
 
 	expected = []string{"theprofile"}
-	result, err = dbContainerProfiles(s.db, 1)
+	result, err = ContainerProfiles(s.db, 1)
 	s.Nil(err)
 
 	for i := range expected {
@@ -470,7 +470,7 @@ func (s *dbTestSuite) Test_dbDevices_profiles() {
 	var subresult types.Device
 	var expected types.Device
 
-	result, err = dbDevices(s.db, "theprofile", true)
+	result, err = Devices(s.db, "theprofile", true)
 	s.Nil(err)
 
 	expected = types.Device{"type": "nic", "devicekey": "devicevalue"}
@@ -488,7 +488,7 @@ func (s *dbTestSuite) Test_dbDevices_containers() {
 	var subresult types.Device
 	var expected types.Device
 
-	result, err = dbDevices(s.db, "thename", false)
+	result, err = Devices(s.db, "thename", false)
 	s.Nil(err)
 
 	expected = types.Device{"type": "nic", "configkey": "configvalue"}
diff --git a/lxd/db_devices.go b/lxd/store/devices.go
similarity index 92%
rename from lxd/db_devices.go
rename to lxd/store/devices.go
index 941bad8c2..7f59b4734 100644
--- a/lxd/db_devices.go
+++ b/lxd/store/devices.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -51,7 +51,7 @@ func dbDeviceTypeToInt(t string) (int, error) {
 	}
 }
 
-func dbDevicesAdd(tx *sql.Tx, w string, cID int64, devices types.Devices) error {
+func DevicesAdd(tx *sql.Tx, w string, cID int64, devices types.Devices) error {
 	// Prepare the devices entry SQL
 	str1 := fmt.Sprintf("INSERT INTO %ss_devices (%s_id, name, type) VALUES (?, ?, ?)", w, w)
 	stmt1, err := tx.Prepare(str1)
@@ -115,7 +115,7 @@ func dbDeviceConfig(db *sql.DB, id int, isprofile bool) (types.Device, error) {
 		query = `SELECT key, value FROM containers_devices_config WHERE container_device_id=?`
 	}
 
-	results, err := dbQueryScan(db, query, inargs, outfmt)
+	results, err := QueryScan(db, query, inargs, outfmt)
 
 	if err != nil {
 		return newdev, err
@@ -130,7 +130,7 @@ func dbDeviceConfig(db *sql.DB, id int, isprofile bool) (types.Device, error) {
 	return newdev, nil
 }
 
-func dbDevices(db *sql.DB, qName string, isprofile bool) (types.Devices, error) {
+func Devices(db *sql.DB, qName string, isprofile bool) (types.Devices, error) {
 	var q string
 	if isprofile {
 		q = `SELECT profiles_devices.id, profiles_devices.name, profiles_devices.type
@@ -147,7 +147,7 @@ func dbDevices(db *sql.DB, qName string, isprofile bool) (types.Devices, error)
 	var name, stype string
 	inargs := []interface{}{qName}
 	outfmt := []interface{}{id, name, dtype}
-	results, err := dbQueryScan(db, q, inargs, outfmt)
+	results, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return nil, err
 	}
diff --git a/lxd/db_images.go b/lxd/store/images.go
similarity index 76%
rename from lxd/db_images.go
rename to lxd/store/images.go
index 0606fe86b..49c0ad0bf 100644
--- a/lxd/db_images.go
+++ b/lxd/store/images.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -11,13 +11,13 @@ import (
 	"github.com/lxc/lxd/shared/osarch"
 )
 
-var dbImageSourceProtocol = map[int]string{
+var ImageSourceProtocol = map[int]string{
 	0: "lxd",
 	1: "direct",
 	2: "simplestreams",
 }
 
-func dbImagesGet(db *sql.DB, public bool) ([]string, error) {
+func ImagesGet(db *sql.DB, public bool) ([]string, error) {
 	q := "SELECT fingerprint FROM images"
 	if public == true {
 		q = "SELECT fingerprint FROM images WHERE public=1"
@@ -26,7 +26,7 @@ func dbImagesGet(db *sql.DB, public bool) ([]string, error) {
 	var fp string
 	inargs := []interface{}{}
 	outfmt := []interface{}{fp}
-	dbResults, err := dbQueryScan(db, q, inargs, outfmt)
+	dbResults, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return []string{}, err
 	}
@@ -39,13 +39,13 @@ func dbImagesGet(db *sql.DB, public bool) ([]string, error) {
 	return results, nil
 }
 
-func dbImagesGetExpired(db *sql.DB, expiry int64) ([]string, error) {
+func ImagesGetExpired(db *sql.DB, expiry int64) ([]string, error) {
 	q := `SELECT fingerprint FROM images WHERE cached=1 AND creation_date<=strftime('%s', date('now', '-` + fmt.Sprintf("%d", expiry) + ` day'))`
 
 	var fp string
 	inargs := []interface{}{}
 	outfmt := []interface{}{fp}
-	dbResults, err := dbQueryScan(db, q, inargs, outfmt)
+	dbResults, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return []string{}, err
 	}
@@ -58,11 +58,11 @@ func dbImagesGetExpired(db *sql.DB, expiry int64) ([]string, error) {
 	return results, nil
 }
 
-func dbImageSourceInsert(db *sql.DB, imageId int, server string, protocol string, certificate string, alias string) error {
+func ImageSourceInsert(db *sql.DB, imageId int, server string, protocol string, certificate string, alias string) error {
 	stmt := `INSERT INTO images_source (image_id, server, protocol, certificate, alias) values (?, ?, ?, ?, ?)`
 
 	protocolInt := -1
-	for protoInt, protoString := range dbImageSourceProtocol {
+	for protoInt, protoString := range ImageSourceProtocol {
 		if protoString == protocol {
 			protocolInt = protoInt
 		}
@@ -72,11 +72,11 @@ func dbImageSourceInsert(db *sql.DB, imageId int, server string, protocol string
 		return fmt.Errorf("Invalid protocol: %s", protocol)
 	}
 
-	_, err := dbExec(db, stmt, imageId, server, protocolInt, certificate, alias)
+	_, err := Exec(db, stmt, imageId, server, protocolInt, certificate, alias)
 	return err
 }
 
-func dbImageSourceGet(db *sql.DB, imageId int) (int, api.ImageSource, error) {
+func ImageSourceGet(db *sql.DB, imageId int) (int, api.ImageSource, error) {
 	q := `SELECT id, server, protocol, certificate, alias FROM images_source WHERE image_id=?`
 
 	id := 0
@@ -94,7 +94,7 @@ func dbImageSourceGet(db *sql.DB, imageId int) (int, api.ImageSource, error) {
 		return -1, api.ImageSource{}, err
 	}
 
-	protocol, found := dbImageSourceProtocol[protocolInt]
+	protocol, found := ImageSourceProtocol[protocolInt]
 	if !found {
 		return -1, api.ImageSource{}, fmt.Errorf("Invalid protocol: %d", protocolInt)
 	}
@@ -108,9 +108,9 @@ func dbImageSourceGet(db *sql.DB, imageId int) (int, api.ImageSource, error) {
 // Try to find a source entry of a locally cached image that matches
 // the given remote details (server, protocol and alias). Return the
 // fingerprint linked to the matching entry, if any.
-func dbImageSourceGetCachedFingerprint(db *sql.DB, server string, protocol string, alias string) (string, error) {
+func ImageSourceGetCachedFingerprint(db *sql.DB, server string, protocol string, alias string) (string, error) {
 	protocolInt := -1
-	for protoInt, protoString := range dbImageSourceProtocol {
+	for protoInt, protoString := range ImageSourceProtocol {
 		if protoString == protocol {
 			protocolInt = protoInt
 		}
@@ -144,7 +144,7 @@ func dbImageSourceGetCachedFingerprint(db *sql.DB, server string, protocol strin
 }
 
 // Whether an image with the given fingerprint exists.
-func dbImageExists(db *sql.DB, fingerprint string) (bool, error) {
+func ImageExists(db *sql.DB, fingerprint string) (bool, error) {
 	var exists bool
 	var err error
 	query := "SELECT COUNT(*) > 0 FROM images WHERE fingerprint=?"
@@ -154,12 +154,12 @@ func dbImageExists(db *sql.DB, fingerprint string) (bool, error) {
 	return exists, err
 }
 
-// dbImageGet gets an Image object from the database.
+// ImageGet gets an Image object from the database.
 // If strictMatching is false, The fingerprint argument will be queried with a LIKE query, means you can
 // pass a shortform and will get the full fingerprint.
 // There can never be more than one image with a given fingerprint, as it is
 // enforced by a UNIQUE constraint in the schema.
-func dbImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool) (int, *api.Image, error) {
+func ImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool) (int, *api.Image, error) {
 	var err error
 	var create, expire, used, upload *time.Time // These hold the db-returned times
 
@@ -241,7 +241,7 @@ func dbImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool
 	var key, value, name, desc string
 	inargs = []interface{}{id}
 	outfmt = []interface{}{key, value}
-	results, err := dbQueryScan(db, q, inargs, outfmt)
+	results, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -259,7 +259,7 @@ func dbImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool
 	q = "SELECT name, description FROM images_aliases WHERE image_id=?"
 	inargs = []interface{}{id}
 	outfmt = []interface{}{name, desc}
-	results, err = dbQueryScan(db, q, inargs, outfmt)
+	results, err = QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -274,7 +274,7 @@ func dbImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool
 
 	image.Aliases = aliases
 
-	_, source, err := dbImageSourceGet(db, id)
+	_, source, err := ImageSourceGet(db, id)
 	if err == nil {
 		image.UpdateSource = &source
 	}
@@ -282,8 +282,8 @@ func dbImageGet(db *sql.DB, fingerprint string, public bool, strictMatching bool
 	return id, &image, nil
 }
 
-func dbImageDelete(db *sql.DB, id int) error {
-	_, err := dbExec(db, "DELETE FROM images WHERE id=?", id)
+func ImageDelete(db *sql.DB, id int) error {
+	_, err := Exec(db, "DELETE FROM images WHERE id=?", id)
 	if err != nil {
 		return err
 	}
@@ -291,7 +291,7 @@ func dbImageDelete(db *sql.DB, id int) error {
 	return nil
 }
 
-func dbImageAliasGet(db *sql.DB, name string, isTrustedClient bool) (int, api.ImageAliasesEntry, error) {
+func ImageAliasGet(db *sql.DB, name string, isTrustedClient bool) (int, api.ImageAliasesEntry, error) {
 	q := `SELECT images_aliases.id, images.fingerprint, images_aliases.description
 			 FROM images_aliases
 			 INNER JOIN images
@@ -323,53 +323,53 @@ func dbImageAliasGet(db *sql.DB, name string, isTrustedClient bool) (int, api.Im
 	return id, entry, nil
 }
 
-func dbImageAliasRename(db *sql.DB, id int, name string) error {
-	_, err := dbExec(db, "UPDATE images_aliases SET name=? WHERE id=?", name, id)
+func ImageAliasRename(db *sql.DB, id int, name string) error {
+	_, err := Exec(db, "UPDATE images_aliases SET name=? WHERE id=?", name, id)
 	return err
 }
 
-func dbImageAliasDelete(db *sql.DB, name string) error {
-	_, err := dbExec(db, "DELETE FROM images_aliases WHERE name=?", name)
+func ImageAliasDelete(db *sql.DB, name string) error {
+	_, err := Exec(db, "DELETE FROM images_aliases WHERE name=?", name)
 	return err
 }
 
-func dbImageAliasesMove(db *sql.DB, source int, destination int) error {
-	_, err := dbExec(db, "UPDATE images_aliases SET image_id=? WHERE image_id=?", destination, source)
+func ImageAliasesMove(db *sql.DB, source int, destination int) error {
+	_, err := Exec(db, "UPDATE images_aliases SET image_id=? WHERE image_id=?", destination, source)
 	return err
 }
 
 // Insert an alias ento the database.
-func dbImageAliasAdd(db *sql.DB, name string, imageID int, desc string) error {
+func ImageAliasAdd(db *sql.DB, name string, imageID int, desc string) error {
 	stmt := `INSERT INTO images_aliases (name, image_id, description) values (?, ?, ?)`
-	_, err := dbExec(db, stmt, name, imageID, desc)
+	_, err := Exec(db, stmt, name, imageID, desc)
 	return err
 }
 
-func dbImageAliasUpdate(db *sql.DB, id int, imageID int, desc string) error {
+func ImageAliasUpdate(db *sql.DB, id int, imageID int, desc string) error {
 	stmt := `UPDATE images_aliases SET image_id=?, description=? WHERE id=?`
-	_, err := dbExec(db, stmt, imageID, desc, id)
+	_, err := Exec(db, stmt, imageID, desc, id)
 	return err
 }
 
-func dbImageLastAccessUpdate(db *sql.DB, fingerprint string, date time.Time) error {
+func ImageLastAccessUpdate(db *sql.DB, fingerprint string, date time.Time) error {
 	stmt := `UPDATE images SET last_use_date=? WHERE fingerprint=?`
-	_, err := dbExec(db, stmt, date, fingerprint)
+	_, err := Exec(db, stmt, date, fingerprint)
 	return err
 }
 
-func dbImageLastAccessInit(db *sql.DB, fingerprint string) error {
+func ImageLastAccessInit(db *sql.DB, fingerprint string) error {
 	stmt := `UPDATE images SET cached=1, last_use_date=strftime("%s") WHERE fingerprint=?`
-	_, err := dbExec(db, stmt, fingerprint)
+	_, err := Exec(db, stmt, fingerprint)
 	return err
 }
 
-func dbImageUpdate(db *sql.DB, id int, fname string, sz int64, public bool, autoUpdate bool, architecture string, createdAt time.Time, expiresAt time.Time, properties map[string]string) error {
+func ImageUpdate(db *sql.DB, id int, fname string, sz int64, public bool, autoUpdate bool, architecture string, createdAt time.Time, expiresAt time.Time, properties map[string]string) error {
 	arch, err := osarch.ArchitectureId(architecture)
 	if err != nil {
 		arch = 0
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -413,20 +413,20 @@ func dbImageUpdate(db *sql.DB, id int, fname string, sz int64, public bool, auto
 		}
 	}
 
-	if err := txCommit(tx); err != nil {
+	if err := TxCommit(tx); err != nil {
 		return err
 	}
 
 	return nil
 }
 
-func dbImageInsert(db *sql.DB, fp string, fname string, sz int64, public bool, autoUpdate bool, architecture string, createdAt time.Time, expiresAt time.Time, properties map[string]string) error {
+func ImageInsert(db *sql.DB, fp string, fname string, sz int64, public bool, autoUpdate bool, architecture string, createdAt time.Time, expiresAt time.Time, properties map[string]string) error {
 	arch, err := osarch.ArchitectureId(architecture)
 	if err != nil {
 		arch = 0
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -482,7 +482,7 @@ func dbImageInsert(db *sql.DB, fp string, fname string, sz int64, public bool, a
 
 	}
 
-	if err := txCommit(tx); err != nil {
+	if err := TxCommit(tx); err != nil {
 		return err
 	}
 
@@ -490,13 +490,13 @@ func dbImageInsert(db *sql.DB, fp string, fname string, sz int64, public bool, a
 }
 
 // Get the names of all storage pools on which a given image exists.
-func dbImageGetPools(db *sql.DB, imageFingerprint string) ([]int64, error) {
+func ImageGetPools(db *sql.DB, imageFingerprint string) ([]int64, error) {
 	poolID := int64(-1)
 	query := "SELECT storage_pool_id FROM storage_volumes WHERE name=? AND type=?"
-	inargs := []interface{}{imageFingerprint, storagePoolVolumeTypeImage}
+	inargs := []interface{}{imageFingerprint, StoragePoolVolumeTypeImage}
 	outargs := []interface{}{poolID}
 
-	result, err := dbQueryScan(db, query, inargs, outargs)
+	result, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return []int64{}, err
 	}
@@ -510,7 +510,7 @@ func dbImageGetPools(db *sql.DB, imageFingerprint string) ([]int64, error) {
 }
 
 // Get the names of all storage pools on which a given image exists.
-func dbImageGetPoolNamesFromIDs(db *sql.DB, poolIDs []int64) ([]string, error) {
+func ImageGetPoolNamesFromIDs(db *sql.DB, poolIDs []int64) ([]string, error) {
 	var poolName string
 	query := "SELECT name FROM storage_pools WHERE id=?"
 
@@ -519,7 +519,7 @@ func dbImageGetPoolNamesFromIDs(db *sql.DB, poolIDs []int64) ([]string, error) {
 		inargs := []interface{}{poolID}
 		outargs := []interface{}{poolName}
 
-		result, err := dbQueryScan(db, query, inargs, outargs)
+		result, err := QueryScan(db, query, inargs, outargs)
 		if err != nil {
 			return []string{}, err
 		}
diff --git a/lxd/db_networks.go b/lxd/store/networks.go
similarity index 70%
rename from lxd/db_networks.go
rename to lxd/store/networks.go
index 425edf660..7777e7568 100644
--- a/lxd/db_networks.go
+++ b/lxd/store/networks.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -10,12 +10,12 @@ import (
 	"github.com/lxc/lxd/shared/api"
 )
 
-func dbNetworks(db *sql.DB) ([]string, error) {
+func Networks(db *sql.DB) ([]string, error) {
 	q := fmt.Sprintf("SELECT name FROM networks")
 	inargs := []interface{}{}
 	var name string
 	outfmt := []interface{}{name}
-	result, err := dbQueryScan(db, q, inargs, outfmt)
+	result, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return []string{}, err
 	}
@@ -28,7 +28,7 @@ func dbNetworks(db *sql.DB) ([]string, error) {
 	return response, nil
 }
 
-func dbNetworkGet(db *sql.DB, name string) (int64, *api.Network, error) {
+func NetworkGet(db *sql.DB, name string) (int64, *api.Network, error) {
 	description := sql.NullString{}
 	id := int64(-1)
 
@@ -40,7 +40,7 @@ func dbNetworkGet(db *sql.DB, name string) (int64, *api.Network, error) {
 		return -1, nil, err
 	}
 
-	config, err := dbNetworkConfigGet(db, id)
+	config, err := NetworkConfigGet(db, id)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -56,7 +56,7 @@ func dbNetworkGet(db *sql.DB, name string) (int64, *api.Network, error) {
 	return id, &network, nil
 }
 
-func dbNetworkGetInterface(db *sql.DB, devName string) (int64, *api.Network, error) {
+func NetworkGetInterface(db *sql.DB, devName string) (int64, *api.Network, error) {
 	id := int64(-1)
 	name := ""
 	value := ""
@@ -64,7 +64,7 @@ func dbNetworkGetInterface(db *sql.DB, devName string) (int64, *api.Network, err
 	q := "SELECT networks.id, networks.name, networks_config.value FROM networks LEFT JOIN networks_config ON networks.id=networks_config.network_id WHERE networks_config.key=\"bridge.external_interfaces\""
 	arg1 := []interface{}{}
 	arg2 := []interface{}{id, name, value}
-	result, err := dbQueryScan(db, q, arg1, arg2)
+	result, err := QueryScan(db, q, arg1, arg2)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -84,7 +84,7 @@ func dbNetworkGetInterface(db *sql.DB, devName string) (int64, *api.Network, err
 		return -1, nil, fmt.Errorf("No network found for interface: %s", devName)
 	}
 
-	config, err := dbNetworkConfigGet(db, id)
+	config, err := NetworkConfigGet(db, id)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -99,7 +99,7 @@ func dbNetworkGetInterface(db *sql.DB, devName string) (int64, *api.Network, err
 	return id, &network, nil
 }
 
-func dbNetworkConfigGet(db *sql.DB, id int64) (map[string]string, error) {
+func NetworkConfigGet(db *sql.DB, id int64) (map[string]string, error) {
 	var key, value string
 	query := `
         SELECT
@@ -108,7 +108,7 @@ func dbNetworkConfigGet(db *sql.DB, id int64) (map[string]string, error) {
 		WHERE network_id=?`
 	inargs := []interface{}{id}
 	outfmt := []interface{}{key, value}
-	results, err := dbQueryScan(db, query, inargs, outfmt)
+	results, err := QueryScan(db, query, inargs, outfmt)
 	if err != nil {
 		return nil, fmt.Errorf("Failed to get network '%d'", id)
 	}
@@ -120,7 +120,7 @@ func dbNetworkConfigGet(db *sql.DB, id int64) (map[string]string, error) {
 		 */
 		query := "SELECT id FROM networks WHERE id=?"
 		var r int
-		results, err := dbQueryScan(db, query, []interface{}{id}, []interface{}{r})
+		results, err := QueryScan(db, query, []interface{}{id}, []interface{}{r})
 		if err != nil {
 			return nil, err
 		}
@@ -142,8 +142,8 @@ func dbNetworkConfigGet(db *sql.DB, id int64) (map[string]string, error) {
 	return config, nil
 }
 
-func dbNetworkCreate(db *sql.DB, name, description string, config map[string]string) (int64, error) {
-	tx, err := dbBegin(db)
+func NetworkCreate(db *sql.DB, name, description string, config map[string]string) (int64, error) {
+	tx, err := Begin(db)
 	if err != nil {
 		return -1, err
 	}
@@ -160,13 +160,13 @@ func dbNetworkCreate(db *sql.DB, name, description string, config map[string]str
 		return -1, err
 	}
 
-	err = dbNetworkConfigAdd(tx, id, config)
+	err = NetworkConfigAdd(tx, id, config)
 	if err != nil {
 		tx.Rollback()
 		return -1, err
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 	if err != nil {
 		return -1, err
 	}
@@ -174,44 +174,44 @@ func dbNetworkCreate(db *sql.DB, name, description string, config map[string]str
 	return id, nil
 }
 
-func dbNetworkUpdate(db *sql.DB, name, description string, config map[string]string) error {
-	id, _, err := dbNetworkGet(db, name)
+func NetworkUpdate(db *sql.DB, name, description string, config map[string]string) error {
+	id, _, err := NetworkGet(db, name)
 	if err != nil {
 		return err
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
 
-	err = dbNetworkUpdateDescription(tx, id, description)
+	err = NetworkUpdateDescription(tx, id, description)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbNetworkConfigClear(tx, id)
+	err = NetworkConfigClear(tx, id)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbNetworkConfigAdd(tx, id, config)
+	err = NetworkConfigAdd(tx, id, config)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
-func dbNetworkUpdateDescription(tx *sql.Tx, id int64, description string) error {
+func NetworkUpdateDescription(tx *sql.Tx, id int64, description string) error {
 	_, err := tx.Exec("UPDATE networks SET description=? WHERE id=?", description, id)
 	return err
 }
 
-func dbNetworkConfigAdd(tx *sql.Tx, id int64, config map[string]string) error {
+func NetworkConfigAdd(tx *sql.Tx, id int64, config map[string]string) error {
 	str := fmt.Sprintf("INSERT INTO networks_config (network_id, key, value) VALUES(?, ?, ?)")
 	stmt, err := tx.Prepare(str)
 	defer stmt.Close()
@@ -230,7 +230,7 @@ func dbNetworkConfigAdd(tx *sql.Tx, id int64, config map[string]string) error {
 	return nil
 }
 
-func dbNetworkConfigClear(tx *sql.Tx, id int64) error {
+func NetworkConfigClear(tx *sql.Tx, id int64) error {
 	_, err := tx.Exec("DELETE FROM networks_config WHERE network_id=?", id)
 	if err != nil {
 		return err
@@ -239,13 +239,13 @@ func dbNetworkConfigClear(tx *sql.Tx, id int64) error {
 	return nil
 }
 
-func dbNetworkDelete(db *sql.DB, name string) error {
-	id, _, err := dbNetworkGet(db, name)
+func NetworkDelete(db *sql.DB, name string) error {
+	id, _, err := NetworkGet(db, name)
 	if err != nil {
 		return err
 	}
 
-	_, err = dbExec(db, "DELETE FROM networks WHERE id=?", id)
+	_, err = Exec(db, "DELETE FROM networks WHERE id=?", id)
 	if err != nil {
 		return err
 	}
@@ -253,13 +253,13 @@ func dbNetworkDelete(db *sql.DB, name string) error {
 	return nil
 }
 
-func dbNetworkRename(db *sql.DB, oldName string, newName string) error {
-	id, _, err := dbNetworkGet(db, oldName)
+func NetworkRename(db *sql.DB, oldName string, newName string) error {
+	id, _, err := NetworkGet(db, oldName)
 	if err != nil {
 		return err
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -270,5 +270,5 @@ func dbNetworkRename(db *sql.DB, oldName string, newName string) error {
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
diff --git a/lxd/db_patches.go b/lxd/store/patches.go
similarity index 71%
rename from lxd/db_patches.go
rename to lxd/store/patches.go
index cd2876aac..dc5d5fa67 100644
--- a/lxd/db_patches.go
+++ b/lxd/store/patches.go
@@ -1,16 +1,16 @@
-package main
+package store
 
 import (
 	"database/sql"
 	"fmt"
 )
 
-func dbPatches(db *sql.DB) ([]string, error) {
+func Patches(db *sql.DB) ([]string, error) {
 	inargs := []interface{}{}
 	outfmt := []interface{}{""}
 
 	query := fmt.Sprintf("SELECT name FROM patches")
-	result, err := dbQueryScan(db, query, inargs, outfmt)
+	result, err := QueryScan(db, query, inargs, outfmt)
 	if err != nil {
 		return []string{}, err
 	}
@@ -23,7 +23,7 @@ func dbPatches(db *sql.DB) ([]string, error) {
 	return response, nil
 }
 
-func dbPatchesMarkApplied(db *sql.DB, patch string) error {
+func PatchesMarkApplied(db *sql.DB, patch string) error {
 	stmt := `INSERT INTO patches (name, applied_at) VALUES (?, strftime("%s"));`
 	_, err := db.Exec(stmt, patch)
 	return err
diff --git a/lxd/db_profiles.go b/lxd/store/profiles.go
similarity index 72%
rename from lxd/db_profiles.go
rename to lxd/store/profiles.go
index 1fb21fb20..d91474905 100644
--- a/lxd/db_profiles.go
+++ b/lxd/store/profiles.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -10,13 +10,13 @@ import (
 	"github.com/lxc/lxd/shared/api"
 )
 
-// dbProfiles returns a string list of profiles.
-func dbProfiles(db *sql.DB) ([]string, error) {
+// Profiles returns a string list of profiles.
+func Profiles(db *sql.DB) ([]string, error) {
 	q := fmt.Sprintf("SELECT name FROM profiles")
 	inargs := []interface{}{}
 	var name string
 	outfmt := []interface{}{name}
-	result, err := dbQueryScan(db, q, inargs, outfmt)
+	result, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return []string{}, err
 	}
@@ -29,7 +29,7 @@ func dbProfiles(db *sql.DB) ([]string, error) {
 	return response, nil
 }
 
-func dbProfileGet(db *sql.DB, name string) (int64, *api.Profile, error) {
+func ProfileGet(db *sql.DB, name string) (int64, *api.Profile, error) {
 	id := int64(-1)
 	description := sql.NullString{}
 
@@ -41,12 +41,12 @@ func dbProfileGet(db *sql.DB, name string) (int64, *api.Profile, error) {
 		return -1, nil, err
 	}
 
-	config, err := dbProfileConfig(db, name)
+	config, err := ProfileConfig(db, name)
 	if err != nil {
 		return -1, nil, err
 	}
 
-	devices, err := dbDevices(db, name, true)
+	devices, err := Devices(db, name, true)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -62,10 +62,10 @@ func dbProfileGet(db *sql.DB, name string) (int64, *api.Profile, error) {
 	return id, &profile, nil
 }
 
-func dbProfileCreate(db *sql.DB, profile string, description string, config map[string]string,
+func ProfileCreate(db *sql.DB, profile string, description string, config map[string]string,
 	devices types.Devices) (int64, error) {
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return -1, err
 	}
@@ -80,19 +80,19 @@ func dbProfileCreate(db *sql.DB, profile string, description string, config map[
 		return -1, err
 	}
 
-	err = dbProfileConfigAdd(tx, id, config)
+	err = ProfileConfigAdd(tx, id, config)
 	if err != nil {
 		tx.Rollback()
 		return -1, err
 	}
 
-	err = dbDevicesAdd(tx, "profile", id, devices)
+	err = DevicesAdd(tx, "profile", id, devices)
 	if err != nil {
 		tx.Rollback()
 		return -1, err
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 	if err != nil {
 		return -1, err
 	}
@@ -100,15 +100,15 @@ func dbProfileCreate(db *sql.DB, profile string, description string, config map[
 	return id, nil
 }
 
-func dbProfileCreateDefault(db *sql.DB) error {
-	id, _, _ := dbProfileGet(db, "default")
+func ProfileCreateDefault(db *sql.DB) error {
+	id, _, _ := ProfileGet(db, "default")
 
 	if id != -1 {
 		// default profile already exists
 		return nil
 	}
 
-	_, err := dbProfileCreate(db, "default", "Default LXD profile", map[string]string{}, types.Devices{})
+	_, err := ProfileCreate(db, "default", "Default LXD profile", map[string]string{}, types.Devices{})
 	if err != nil {
 		return err
 	}
@@ -117,7 +117,7 @@ func dbProfileCreateDefault(db *sql.DB) error {
 }
 
 // Get the profile configuration map from the DB
-func dbProfileConfig(db *sql.DB, name string) (map[string]string, error) {
+func ProfileConfig(db *sql.DB, name string) (map[string]string, error) {
 	var key, value string
 	query := `
         SELECT
@@ -127,7 +127,7 @@ func dbProfileConfig(db *sql.DB, name string) (map[string]string, error) {
 		WHERE name=?`
 	inargs := []interface{}{name}
 	outfmt := []interface{}{key, value}
-	results, err := dbQueryScan(db, query, inargs, outfmt)
+	results, err := QueryScan(db, query, inargs, outfmt)
 	if err != nil {
 		return nil, fmt.Errorf("Failed to get profile '%s'", name)
 	}
@@ -139,7 +139,7 @@ func dbProfileConfig(db *sql.DB, name string) (map[string]string, error) {
 		 */
 		query := "SELECT id FROM profiles WHERE name=?"
 		var id int
-		results, err := dbQueryScan(db, query, []interface{}{name}, []interface{}{id})
+		results, err := QueryScan(db, query, []interface{}{name}, []interface{}{id})
 		if err != nil {
 			return nil, err
 		}
@@ -161,13 +161,13 @@ func dbProfileConfig(db *sql.DB, name string) (map[string]string, error) {
 	return config, nil
 }
 
-func dbProfileDelete(db *sql.DB, name string) error {
-	id, _, err := dbProfileGet(db, name)
+func ProfileDelete(db *sql.DB, name string) error {
+	id, _, err := ProfileGet(db, name)
 	if err != nil {
 		return err
 	}
 
-	_, err = dbExec(db, "DELETE FROM profiles WHERE id=?", id)
+	_, err = Exec(db, "DELETE FROM profiles WHERE id=?", id)
 	if err != nil {
 		return err
 	}
@@ -175,8 +175,8 @@ func dbProfileDelete(db *sql.DB, name string) error {
 	return nil
 }
 
-func dbProfileUpdate(db *sql.DB, name string, newName string) error {
-	tx, err := dbBegin(db)
+func ProfileUpdate(db *sql.DB, name string, newName string) error {
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -187,17 +187,17 @@ func dbProfileUpdate(db *sql.DB, name string, newName string) error {
 		return err
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 
 	return err
 }
 
-func dbProfileDescriptionUpdate(tx *sql.Tx, id int64, description string) error {
+func ProfileDescriptionUpdate(tx *sql.Tx, id int64, description string) error {
 	_, err := tx.Exec("UPDATE profiles SET description=? WHERE id=?", description, id)
 	return err
 }
 
-func dbProfileConfigClear(tx *sql.Tx, id int64) error {
+func ProfileConfigClear(tx *sql.Tx, id int64) error {
 	_, err := tx.Exec("DELETE FROM profiles_config WHERE profile_id=?", id)
 	if err != nil {
 		return err
@@ -218,7 +218,7 @@ func dbProfileConfigClear(tx *sql.Tx, id int64) error {
 	return nil
 }
 
-func dbProfileConfigAdd(tx *sql.Tx, id int64, config map[string]string) error {
+func ProfileConfigAdd(tx *sql.Tx, id int64, config map[string]string) error {
 	str := fmt.Sprintf("INSERT INTO profiles_config (profile_id, key, value) VALUES(?, ?, ?)")
 	stmt, err := tx.Prepare(str)
 	defer stmt.Close()
@@ -233,7 +233,7 @@ func dbProfileConfigAdd(tx *sql.Tx, id int64, config map[string]string) error {
 	return nil
 }
 
-func dbProfileContainersGet(db *sql.DB, profile string) ([]string, error) {
+func ProfileContainersGet(db *sql.DB, profile string) ([]string, error) {
 	q := `SELECT containers.name FROM containers JOIN containers_profiles
 		ON containers.id == containers_profiles.container_id
 		JOIN profiles ON containers_profiles.profile_id == profiles.id
@@ -244,7 +244,7 @@ func dbProfileContainersGet(db *sql.DB, profile string) ([]string, error) {
 	var name string
 	outfmt := []interface{}{name}
 
-	output, err := dbQueryScan(db, q, inargs, outfmt)
+	output, err := QueryScan(db, q, inargs, outfmt)
 	if err != nil {
 		return results, err
 	}
diff --git a/lxd/db_storage_pools.go b/lxd/store/storage_pools.go
similarity index 59%
rename from lxd/db_storage_pools.go
rename to lxd/store/storage_pools.go
index f340c7cbf..b44197a05 100644
--- a/lxd/db_storage_pools.go
+++ b/lxd/store/storage_pools.go
@@ -1,22 +1,22 @@
-package main
+package store
 
 import (
 	"database/sql"
+	"fmt"
 
 	_ "github.com/mattn/go-sqlite3"
 
-	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 )
 
 // Get all storage pools.
-func dbStoragePools(db *sql.DB) ([]string, error) {
+func StoragePools(db *sql.DB) ([]string, error) {
 	var name string
 	query := "SELECT name FROM storage_pools"
 	inargs := []interface{}{}
 	outargs := []interface{}{name}
 
-	result, err := dbQueryScan(db, query, inargs, outargs)
+	result, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return []string{}, err
 	}
@@ -34,13 +34,13 @@ func dbStoragePools(db *sql.DB) ([]string, error) {
 }
 
 // Get the names of all storage volumes attached to a given storage pool.
-func dbStoragePoolsGetDrivers(db *sql.DB) ([]string, error) {
+func StoragePoolsGetDrivers(db *sql.DB) ([]string, error) {
 	var poolDriver string
 	query := "SELECT DISTINCT driver FROM storage_pools"
 	inargs := []interface{}{}
 	outargs := []interface{}{poolDriver}
 
-	result, err := dbQueryScan(db, query, inargs, outargs)
+	result, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return []string{}, err
 	}
@@ -58,7 +58,7 @@ func dbStoragePoolsGetDrivers(db *sql.DB) ([]string, error) {
 }
 
 // Get id of a single storage pool.
-func dbStoragePoolGetID(db *sql.DB, poolName string) (int64, error) {
+func StoragePoolGetID(db *sql.DB, poolName string) (int64, error) {
 	poolID := int64(-1)
 	query := "SELECT id FROM storage_pools WHERE name=?"
 	inargs := []interface{}{poolName}
@@ -75,7 +75,7 @@ func dbStoragePoolGetID(db *sql.DB, poolName string) (int64, error) {
 }
 
 // Get a single storage pool.
-func dbStoragePoolGet(db *sql.DB, poolName string) (int64, *api.StoragePool, error) {
+func StoragePoolGet(db *sql.DB, poolName string) (int64, *api.StoragePool, error) {
 	var poolDriver string
 	poolID := int64(-1)
 	description := sql.NullString{}
@@ -92,7 +92,7 @@ func dbStoragePoolGet(db *sql.DB, poolName string) (int64, *api.StoragePool, err
 		return -1, nil, err
 	}
 
-	config, err := dbStoragePoolConfigGet(db, poolID)
+	config, err := StoragePoolConfigGet(db, poolID)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -108,13 +108,13 @@ func dbStoragePoolGet(db *sql.DB, poolName string) (int64, *api.StoragePool, err
 }
 
 // Get config of a storage pool.
-func dbStoragePoolConfigGet(db *sql.DB, poolID int64) (map[string]string, error) {
+func StoragePoolConfigGet(db *sql.DB, poolID int64) (map[string]string, error) {
 	var key, value string
 	query := "SELECT key, value FROM storage_pools_config WHERE storage_pool_id=?"
 	inargs := []interface{}{poolID}
 	outargs := []interface{}{key, value}
 
-	results, err := dbQueryScan(db, query, inargs, outargs)
+	results, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return nil, err
 	}
@@ -132,8 +132,8 @@ func dbStoragePoolConfigGet(db *sql.DB, poolID int64) (map[string]string, error)
 }
 
 // Create new storage pool.
-func dbStoragePoolCreate(db *sql.DB, poolName string, poolDescription string, poolDriver string, poolConfig map[string]string) (int64, error) {
-	tx, err := dbBegin(db)
+func StoragePoolCreate(db *sql.DB, poolName string, poolDescription string, poolDriver string, poolConfig map[string]string) (int64, error) {
+	tx, err := Begin(db)
 	if err != nil {
 		return -1, err
 	}
@@ -150,31 +150,22 @@ func dbStoragePoolCreate(db *sql.DB, poolName string, poolDescription string, po
 		return -1, err
 	}
 
-	err = dbStoragePoolConfigAdd(tx, id, poolConfig)
+	err = StoragePoolConfigAdd(tx, id, poolConfig)
 	if err != nil {
 		tx.Rollback()
 		return -1, err
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 	if err != nil {
 		return -1, err
 	}
 
-	// Update the storage drivers cache in api_1.0.go.
-	storagePoolDriversCacheLock.Lock()
-	drivers := readStoragePoolDriversCache()
-	if !shared.StringInSlice(poolDriver, drivers) {
-		drivers = append(drivers, poolDriver)
-	}
-	storagePoolDriversCacheVal.Store(drivers)
-	storagePoolDriversCacheLock.Unlock()
-
 	return id, nil
 }
 
 // Add new storage pool config.
-func dbStoragePoolConfigAdd(tx *sql.Tx, poolID int64, poolConfig map[string]string) error {
+func StoragePoolConfigAdd(tx *sql.Tx, poolID int64, poolConfig map[string]string) error {
 	str := "INSERT INTO storage_pools_config (storage_pool_id, key, value) VALUES(?, ?, ?)"
 	stmt, err := tx.Prepare(str)
 	defer stmt.Close()
@@ -194,46 +185,46 @@ func dbStoragePoolConfigAdd(tx *sql.Tx, poolID int64, poolConfig map[string]stri
 }
 
 // Update storage pool.
-func dbStoragePoolUpdate(db *sql.DB, poolName, description string, poolConfig map[string]string) error {
-	poolID, _, err := dbStoragePoolGet(db, poolName)
+func StoragePoolUpdate(db *sql.DB, poolName, description string, poolConfig map[string]string) error {
+	poolID, _, err := StoragePoolGet(db, poolName)
 	if err != nil {
 		return err
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
 
-	err = dbStoragePoolUpdateDescription(tx, poolID, description)
+	err = StoragePoolUpdateDescription(tx, poolID, description)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbStoragePoolConfigClear(tx, poolID)
+	err = StoragePoolConfigClear(tx, poolID)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbStoragePoolConfigAdd(tx, poolID, poolConfig)
+	err = StoragePoolConfigAdd(tx, poolID, poolConfig)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
 // Update the storage pool description.
-func dbStoragePoolUpdateDescription(tx *sql.Tx, id int64, description string) error {
+func StoragePoolUpdateDescription(tx *sql.Tx, id int64, description string) error {
 	_, err := tx.Exec("UPDATE storage_pools SET description=? WHERE id=?", description, id)
 	return err
 }
 
 // Delete storage pool config.
-func dbStoragePoolConfigClear(tx *sql.Tx, poolID int64) error {
+func StoragePoolConfigClear(tx *sql.Tx, poolID int64) error {
 	_, err := tx.Exec("DELETE FROM storage_pools_config WHERE storage_pool_id=?", poolID)
 	if err != nil {
 		return err
@@ -243,42 +234,28 @@ func dbStoragePoolConfigClear(tx *sql.Tx, poolID int64) error {
 }
 
 // Delete storage pool.
-func dbStoragePoolDelete(db *sql.DB, poolName string) error {
-	poolID, pool, err := dbStoragePoolGet(db, poolName)
+func StoragePoolDelete(db *sql.DB, poolName string) (*api.StoragePool, error) {
+	poolID, pool, err := StoragePoolGet(db, poolName)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
-	_, err = dbExec(db, "DELETE FROM storage_pools WHERE id=?", poolID)
+	_, err = Exec(db, "DELETE FROM storage_pools WHERE id=?", poolID)
 	if err != nil {
-		return err
-	}
-
-	// Update the storage drivers cache in api_1.0.go.
-	storagePoolDriversCacheLock.Lock()
-	drivers := readStoragePoolDriversCache()
-	for i := 0; i < len(drivers); i++ {
-		if drivers[i] == pool.Driver {
-			drivers[i] = drivers[len(drivers)-1]
-			drivers[len(drivers)-1] = ""
-			drivers = drivers[:len(drivers)-1]
-			break
-		}
+		return nil, err
 	}
-	storagePoolDriversCacheVal.Store(drivers)
-	storagePoolDriversCacheLock.Unlock()
 
-	return nil
+	return pool, nil
 }
 
 // Get the names of all storage volumes attached to a given storage pool.
-func dbStoragePoolVolumesGetNames(db *sql.DB, poolID int64) (int, error) {
+func StoragePoolVolumesGetNames(db *sql.DB, poolID int64) (int, error) {
 	var volumeName string
 	query := "SELECT name FROM storage_volumes WHERE storage_pool_id=?"
 	inargs := []interface{}{poolID}
 	outargs := []interface{}{volumeName}
 
-	result, err := dbQueryScan(db, query, inargs, outargs)
+	result, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return -1, err
 	}
@@ -291,17 +268,17 @@ func dbStoragePoolVolumesGetNames(db *sql.DB, poolID int64) (int, error) {
 }
 
 // Get all storage volumes attached to a given storage pool.
-func dbStoragePoolVolumesGet(db *sql.DB, poolID int64, volumeTypes []int) ([]*api.StorageVolume, error) {
+func StoragePoolVolumesGet(db *sql.DB, poolID int64, volumeTypes []int) ([]*api.StorageVolume, error) {
 	// Get all storage volumes of all types attached to a given storage
 	// pool.
 	result := []*api.StorageVolume{}
 	for _, volumeType := range volumeTypes {
-		volumeNames, err := dbStoragePoolVolumesGetType(db, volumeType, poolID)
+		volumeNames, err := StoragePoolVolumesGetType(db, volumeType, poolID)
 		if err != nil && err != sql.ErrNoRows {
 			return nil, err
 		}
 		for _, volumeName := range volumeNames {
-			_, volume, err := dbStoragePoolVolumeGetType(db, volumeName, volumeType, poolID)
+			_, volume, err := StoragePoolVolumeGetType(db, volumeName, volumeType, poolID)
 			if err != nil {
 				return nil, err
 			}
@@ -318,13 +295,13 @@ func dbStoragePoolVolumesGet(db *sql.DB, poolID int64, volumeTypes []int) ([]*ap
 
 // Get all storage volumes attached to a given storage pool of a given volume
 // type.
-func dbStoragePoolVolumesGetType(db *sql.DB, volumeType int, poolID int64) ([]string, error) {
+func StoragePoolVolumesGetType(db *sql.DB, volumeType int, poolID int64) ([]string, error) {
 	var poolName string
 	query := "SELECT name FROM storage_volumes WHERE storage_pool_id=? AND type=?"
 	inargs := []interface{}{poolID, volumeType}
 	outargs := []interface{}{poolName}
 
-	result, err := dbQueryScan(db, query, inargs, outargs)
+	result, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return []string{}, err
 	}
@@ -338,23 +315,23 @@ func dbStoragePoolVolumesGetType(db *sql.DB, volumeType int, poolID int64) ([]st
 }
 
 // Get a single storage volume attached to a given storage pool of a given type.
-func dbStoragePoolVolumeGetType(db *sql.DB, volumeName string, volumeType int, poolID int64) (int64, *api.StorageVolume, error) {
-	volumeID, err := dbStoragePoolVolumeGetTypeID(db, volumeName, volumeType, poolID)
+func StoragePoolVolumeGetType(db *sql.DB, volumeName string, volumeType int, poolID int64) (int64, *api.StorageVolume, error) {
+	volumeID, err := StoragePoolVolumeGetTypeID(db, volumeName, volumeType, poolID)
 	if err != nil {
 		return -1, nil, err
 	}
 
-	volumeConfig, err := dbStorageVolumeConfigGet(db, volumeID)
+	volumeConfig, err := StorageVolumeConfigGet(db, volumeID)
 	if err != nil {
 		return -1, nil, err
 	}
 
-	volumeDescription, err := dbStorageVolumeDescriptionGet(db, volumeID)
+	volumeDescription, err := StorageVolumeDescriptionGet(db, volumeID)
 	if err != nil {
 		return -1, nil, err
 	}
 
-	volumeTypeName, err := storagePoolVolumeTypeToName(volumeType)
+	volumeTypeName, err := StoragePoolVolumeTypeToName(volumeType)
 	if err != nil {
 		return -1, nil, err
 	}
@@ -370,46 +347,46 @@ func dbStoragePoolVolumeGetType(db *sql.DB, volumeName string, volumeType int, p
 }
 
 // Update storage volume attached to a given storage pool.
-func dbStoragePoolVolumeUpdate(db *sql.DB, volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string) error {
-	volumeID, _, err := dbStoragePoolVolumeGetType(db, volumeName, volumeType, poolID)
+func StoragePoolVolumeUpdate(db *sql.DB, volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string) error {
+	volumeID, _, err := StoragePoolVolumeGetType(db, volumeName, volumeType, poolID)
 	if err != nil {
 		return err
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
 
-	err = dbStorageVolumeConfigClear(tx, volumeID)
+	err = StorageVolumeConfigClear(tx, volumeID)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbStorageVolumeConfigAdd(tx, volumeID, volumeConfig)
+	err = StorageVolumeConfigAdd(tx, volumeID, volumeConfig)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	err = dbStorageVolumeDescriptionUpdate(tx, volumeID, volumeDescription)
+	err = StorageVolumeDescriptionUpdate(tx, volumeID, volumeDescription)
 	if err != nil {
 		tx.Rollback()
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
 // Delete storage volume attached to a given storage pool.
-func dbStoragePoolVolumeDelete(db *sql.DB, volumeName string, volumeType int, poolID int64) error {
-	volumeID, _, err := dbStoragePoolVolumeGetType(db, volumeName, volumeType, poolID)
+func StoragePoolVolumeDelete(db *sql.DB, volumeName string, volumeType int, poolID int64) error {
+	volumeID, _, err := StoragePoolVolumeGetType(db, volumeName, volumeType, poolID)
 	if err != nil {
 		return err
 	}
 
-	_, err = dbExec(db, "DELETE FROM storage_volumes WHERE id=?", volumeID)
+	_, err = Exec(db, "DELETE FROM storage_volumes WHERE id=?", volumeID)
 	if err != nil {
 		return err
 	}
@@ -418,13 +395,13 @@ func dbStoragePoolVolumeDelete(db *sql.DB, volumeName string, volumeType int, po
 }
 
 // Rename storage volume attached to a given storage pool.
-func dbStoragePoolVolumeRename(db *sql.DB, oldVolumeName string, newVolumeName string, volumeType int, poolID int64) error {
-	volumeID, _, err := dbStoragePoolVolumeGetType(db, oldVolumeName, volumeType, poolID)
+func StoragePoolVolumeRename(db *sql.DB, oldVolumeName string, newVolumeName string, volumeType int, poolID int64) error {
+	volumeID, _, err := StoragePoolVolumeGetType(db, oldVolumeName, volumeType, poolID)
 	if err != nil {
 		return err
 	}
 
-	tx, err := dbBegin(db)
+	tx, err := Begin(db)
 	if err != nil {
 		return err
 	}
@@ -435,12 +412,12 @@ func dbStoragePoolVolumeRename(db *sql.DB, oldVolumeName string, newVolumeName s
 		return err
 	}
 
-	return txCommit(tx)
+	return TxCommit(tx)
 }
 
 // Create new storage volume attached to a given storage pool.
-func dbStoragePoolVolumeCreate(db *sql.DB, volumeName, volumeDescription string, volumeType int, poolID int64, volumeConfig map[string]string) (int64, error) {
-	tx, err := dbBegin(db)
+func StoragePoolVolumeCreate(db *sql.DB, volumeName, volumeDescription string, volumeType int, poolID int64, volumeConfig map[string]string) (int64, error) {
+	tx, err := Begin(db)
 	if err != nil {
 		return -1, err
 	}
@@ -458,13 +435,13 @@ func dbStoragePoolVolumeCreate(db *sql.DB, volumeName, volumeDescription string,
 		return -1, err
 	}
 
-	err = dbStorageVolumeConfigAdd(tx, volumeID, volumeConfig)
+	err = StorageVolumeConfigAdd(tx, volumeID, volumeConfig)
 	if err != nil {
 		tx.Rollback()
 		return -1, err
 	}
 
-	err = txCommit(tx)
+	err = TxCommit(tx)
 	if err != nil {
 		return -1, err
 	}
@@ -474,7 +451,7 @@ func dbStoragePoolVolumeCreate(db *sql.DB, volumeName, volumeDescription string,
 
 // Get ID of a storage volume on a given storage pool of a given storage volume
 // type.
-func dbStoragePoolVolumeGetTypeID(db *sql.DB, volumeName string, volumeType int, poolID int64) (int64, error) {
+func StoragePoolVolumeGetTypeID(db *sql.DB, volumeName string, volumeType int, poolID int64) (int64, error) {
 	volumeID := int64(-1)
 	query := `SELECT storage_volumes.id
 FROM storage_volumes
@@ -492,3 +469,35 @@ AND storage_volumes.name=? AND storage_volumes.type=?`
 
 	return volumeID, nil
 }
+
+// XXX: this was extracted from lxd/storage_volume_utils.go, we find a way to
+//      factor it independently from both the db and main packages.
+const (
+	StoragePoolVolumeTypeContainer = iota
+	StoragePoolVolumeTypeImage
+	StoragePoolVolumeTypeCustom
+)
+
+// Leave the string type in here! This guarantees that go treats this is as a
+// typed string constant. Removing it causes go to treat these as untyped string
+// constants which is not what we want.
+const (
+	StoragePoolVolumeTypeNameContainer string = "container"
+	StoragePoolVolumeTypeNameImage     string = "image"
+	StoragePoolVolumeTypeNameCustom    string = "custom"
+)
+
+// StoragePoolVolumeTypeToName converts a volume integer type code to its
+// human-readable name.
+func StoragePoolVolumeTypeToName(volumeType int) (string, error) {
+	switch volumeType {
+	case StoragePoolVolumeTypeContainer:
+		return StoragePoolVolumeTypeNameContainer, nil
+	case StoragePoolVolumeTypeImage:
+		return StoragePoolVolumeTypeNameImage, nil
+	case StoragePoolVolumeTypeCustom:
+		return StoragePoolVolumeTypeNameCustom, nil
+	}
+
+	return "", fmt.Errorf("invalid storage volume type")
+}
diff --git a/lxd/db_storage_volumes.go b/lxd/store/storage_volumes.go
similarity index 75%
rename from lxd/db_storage_volumes.go
rename to lxd/store/storage_volumes.go
index 9cce35fcb..95069c30c 100644
--- a/lxd/db_storage_volumes.go
+++ b/lxd/store/storage_volumes.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -7,13 +7,13 @@ import (
 )
 
 // Get config of a storage volume.
-func dbStorageVolumeConfigGet(db *sql.DB, volumeID int64) (map[string]string, error) {
+func StorageVolumeConfigGet(db *sql.DB, volumeID int64) (map[string]string, error) {
 	var key, value string
 	query := "SELECT key, value FROM storage_volumes_config WHERE storage_volume_id=?"
 	inargs := []interface{}{volumeID}
 	outargs := []interface{}{key, value}
 
-	results, err := dbQueryScan(db, query, inargs, outargs)
+	results, err := QueryScan(db, query, inargs, outargs)
 	if err != nil {
 		return nil, err
 	}
@@ -31,7 +31,7 @@ func dbStorageVolumeConfigGet(db *sql.DB, volumeID int64) (map[string]string, er
 }
 
 // Get the description of a storage volume.
-func dbStorageVolumeDescriptionGet(db *sql.DB, volumeID int64) (string, error) {
+func StorageVolumeDescriptionGet(db *sql.DB, volumeID int64) (string, error) {
 	description := sql.NullString{}
 	query := "SELECT description FROM storage_volumes WHERE id=?"
 	inargs := []interface{}{volumeID}
@@ -48,13 +48,13 @@ func dbStorageVolumeDescriptionGet(db *sql.DB, volumeID int64) (string, error) {
 }
 
 // Update description of a storage volume.
-func dbStorageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string) error {
+func StorageVolumeDescriptionUpdate(tx *sql.Tx, volumeID int64, description string) error {
 	_, err := tx.Exec("UPDATE storage_volumes SET description=? WHERE id=?", description, volumeID)
 	return err
 }
 
 // Add new storage volume config into database.
-func dbStorageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string) error {
+func StorageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[string]string) error {
 	str := "INSERT INTO storage_volumes_config (storage_volume_id, key, value) VALUES(?, ?, ?)"
 	stmt, err := tx.Prepare(str)
 	defer stmt.Close()
@@ -74,7 +74,7 @@ func dbStorageVolumeConfigAdd(tx *sql.Tx, volumeID int64, volumeConfig map[strin
 }
 
 // Delete storage volume config.
-func dbStorageVolumeConfigClear(tx *sql.Tx, volumeID int64) error {
+func StorageVolumeConfigClear(tx *sql.Tx, volumeID int64) error {
 	_, err := tx.Exec("DELETE FROM storage_volumes_config WHERE storage_volume_id=?", volumeID)
 	if err != nil {
 		return err
diff --git a/lxd/db_update.go b/lxd/store/update.go
similarity index 98%
rename from lxd/db_update.go
rename to lxd/store/update.go
index 68f5c401a..9fc6cbe75 100644
--- a/lxd/db_update.go
+++ b/lxd/store/update.go
@@ -1,4 +1,4 @@
-package main
+package store
 
 import (
 	"database/sql"
@@ -98,8 +98,8 @@ func (u *dbUpdate) apply(currentVersion int, db *sql.DB) error {
 // of now "postApply" is only used by the daemon as a mean to apply
 // the legacy V10 and V15 non-db updates during the database upgrade
 // sequence to, avoid changing semantics see PR #3322).
-func dbUpdatesApplyAll(db *sql.DB, doBackup bool, postApply func(int) error) error {
-	currentVersion := dbGetSchema(db)
+func UpdatesApplyAll(db *sql.DB, doBackup bool, postApply func(int) error) error {
+	currentVersion := GetSchema(db)
 
 	backup := false
 	for _, update := range dbUpdates {
@@ -344,7 +344,7 @@ func dbUpdateFromV18(currentVersion int, version int, db *sql.DB) error {
 	var value string
 
 	// Update container config
-	rows, err := dbQueryScan(db, "SELECT id, value FROM containers_config WHERE key='limits.memory'", nil, []interface{}{id, value})
+	rows, err := QueryScan(db, "SELECT id, value FROM containers_config WHERE key='limits.memory'", nil, []interface{}{id, value})
 	if err != nil {
 		return err
 	}
@@ -381,7 +381,7 @@ func dbUpdateFromV18(currentVersion int, version int, db *sql.DB) error {
 	}
 
 	// Update profiles config
-	rows, err = dbQueryScan(db, "SELECT id, value FROM profiles_config WHERE key='limits.memory'", nil, []interface{}{id, value})
+	rows, err = QueryScan(db, "SELECT id, value FROM profiles_config WHERE key='limits.memory'", nil, []interface{}{id, value})
 	if err != nil {
 		return err
 	}


More information about the lxc-devel mailing list