mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 05:56:39 +00:00 
			
		
		
		
	components/detournavigator/navmeshdb.cpp:183:43: warning: Division by zero [clang-analyzer-core.DivideZero]
        setMaxPageCount(*mDb, maxFileSize / dbPageSize + static_cast<std::uint64_t>((maxFileSize % dbPageSize) != 0));
                              ~~~~~~~~~~~~^~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:182:33: note: Calling 'getPageSize'
        const auto dbPageSize = getPageSize(*mDb);
                                ^~~~~~~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:144:13: note: 'value' initialized to 0
            std::uint64_t value = 0;
            ^~~~~~~~~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:145:13: note: Calling 'request<DetourNavigator::(anonymous namespace)::GetPageSize, unsigned long *, >'
            request(db, statement, &value, 1);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
components/sqlite3/request.hpp:254:64: note: Left side of '&&' is false
            for (std::size_t i = 0; executeStep(db, statement) && i < max; ++i)
                                                               ^
components/detournavigator/navmeshdb.cpp:145:13: note: Returning from 'request<DetourNavigator::(anonymous namespace)::GetPageSize, unsigned long *, >'
            request(db, statement, &value, 1);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:146:13: note: Returning zero (loaded from 'value')
            return value;
            ^~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:182:33: note: Returning from 'getPageSize'
        const auto dbPageSize = getPageSize(*mDb);
                                ^~~~~~~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:182:9: note: 'dbPageSize' initialized to 0
        const auto dbPageSize = getPageSize(*mDb);
        ^~~~~~~~~~~~~~~~~~~~~
components/detournavigator/navmeshdb.cpp:183:43: note: Division by zero
        setMaxPageCount(*mDb, maxFileSize / dbPageSize + static_cast<std::uint64_t>((maxFileSize % dbPageSize) != 0));
                              ~~~~~~~~~~~~^~~~~~~~~~~~
		
	
			
		
			
				
	
	
		
			424 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			424 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include "navmeshdb.hpp"
 | 
						|
 | 
						|
#include <components/debug/debuglog.hpp>
 | 
						|
#include <components/misc/compression.hpp>
 | 
						|
#include <components/sqlite3/db.hpp>
 | 
						|
#include <components/sqlite3/request.hpp>
 | 
						|
#include <components/misc/stringops.hpp>
 | 
						|
 | 
						|
#include <DetourAlloc.h>
 | 
						|
 | 
						|
#include <sqlite3.h>
 | 
						|
 | 
						|
#include <cstddef>
 | 
						|
#include <string_view>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
namespace DetourNavigator
 | 
						|
{
 | 
						|
    namespace
 | 
						|
    {
 | 
						|
        constexpr const char schema[] = R"(
 | 
						|
            BEGIN TRANSACTION;
 | 
						|
 | 
						|
            CREATE TABLE IF NOT EXISTS tiles (
 | 
						|
                tile_id INTEGER PRIMARY KEY,
 | 
						|
                revision INTEGER NOT NULL DEFAULT 1,
 | 
						|
                worldspace TEXT NOT NULL,
 | 
						|
                tile_position_x INTEGER NOT NULL,
 | 
						|
                tile_position_y INTEGER NOT NULL,
 | 
						|
                version INTEGER NOT NULL,
 | 
						|
                input BLOB,
 | 
						|
                data BLOB
 | 
						|
            );
 | 
						|
 | 
						|
            CREATE UNIQUE INDEX IF NOT EXISTS index_unique_tiles_by_worldspace_and_tile_position_and_input
 | 
						|
                ON tiles (worldspace, tile_position_x, tile_position_y, input);
 | 
						|
 | 
						|
            CREATE INDEX IF NOT EXISTS index_tiles_by_worldspace_and_tile_position
 | 
						|
                ON tiles (worldspace, tile_position_x, tile_position_y);
 | 
						|
 | 
						|
            CREATE TABLE IF NOT EXISTS shapes (
 | 
						|
                shape_id INTEGER PRIMARY KEY,
 | 
						|
                name TEXT NOT NULL,
 | 
						|
                type INTEGER NOT NULL,
 | 
						|
                hash BLOB NOT NULL
 | 
						|
            );
 | 
						|
 | 
						|
            CREATE UNIQUE INDEX IF NOT EXISTS index_unique_shapes_by_name_and_type_and_hash
 | 
						|
                ON shapes (name, type, hash);
 | 
						|
 | 
						|
            COMMIT;
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view getMaxTileIdQuery = R"(
 | 
						|
            SELECT max(tile_id) FROM tiles
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view findTileQuery = R"(
 | 
						|
            SELECT tile_id, version
 | 
						|
              FROM tiles
 | 
						|
             WHERE worldspace = :worldspace
 | 
						|
               AND tile_position_x = :tile_position_x
 | 
						|
               AND tile_position_y = :tile_position_y
 | 
						|
               AND input = :input
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view getTileDataQuery = R"(
 | 
						|
            SELECT tile_id, version, data
 | 
						|
              FROM tiles
 | 
						|
             WHERE worldspace = :worldspace
 | 
						|
               AND tile_position_x = :tile_position_x
 | 
						|
               AND tile_position_y = :tile_position_y
 | 
						|
               AND input = :input
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view insertTileQuery = R"(
 | 
						|
            INSERT INTO tiles ( tile_id,  worldspace,  version,  tile_position_x,  tile_position_y,  input,  data)
 | 
						|
                   VALUES     (:tile_id, :worldspace, :version, :tile_position_x, :tile_position_y, :input, :data)
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view updateTileQuery = R"(
 | 
						|
            UPDATE tiles
 | 
						|
               SET version = :version,
 | 
						|
                   data = :data,
 | 
						|
                   revision = revision + 1
 | 
						|
             WHERE tile_id = :tile_id
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view deleteTilesAtQuery = R"(
 | 
						|
            DELETE FROM tiles
 | 
						|
             WHERE worldspace = :worldspace
 | 
						|
               AND tile_position_x = :tile_position_x
 | 
						|
               AND tile_position_y = :tile_position_y
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view deleteTilesAtExceptQuery = R"(
 | 
						|
            DELETE FROM tiles
 | 
						|
             WHERE worldspace = :worldspace
 | 
						|
               AND tile_position_x = :tile_position_x
 | 
						|
               AND tile_position_y = :tile_position_y
 | 
						|
               AND tile_id != :exclude_tile_id
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view deleteTilesOutsideRangeQuery = R"(
 | 
						|
            DELETE FROM tiles
 | 
						|
             WHERE worldspace = :worldspace
 | 
						|
               AND (   tile_position_x < :begin_tile_position_x
 | 
						|
                    OR tile_position_y < :begin_tile_position_y
 | 
						|
                    OR tile_position_x >= :end_tile_position_x
 | 
						|
                    OR tile_position_y >= :end_tile_position_y
 | 
						|
                   )
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view getMaxShapeIdQuery = R"(
 | 
						|
            SELECT max(shape_id) FROM shapes
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view findShapeIdQuery = R"(
 | 
						|
            SELECT shape_id
 | 
						|
              FROM shapes
 | 
						|
             WHERE name = :name
 | 
						|
               AND type = :type
 | 
						|
               AND hash = :hash
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view insertShapeQuery = R"(
 | 
						|
            INSERT INTO shapes ( shape_id,  name,  type,  hash)
 | 
						|
                   VALUES      (:shape_id, :name, :type, :hash)
 | 
						|
        )";
 | 
						|
 | 
						|
        constexpr std::string_view vacuumQuery = R"(
 | 
						|
            VACUUM;
 | 
						|
        )";
 | 
						|
 | 
						|
        struct GetPageSize
 | 
						|
        {
 | 
						|
            static std::string_view text() noexcept { return "pragma page_size;"; }
 | 
						|
            static void bind(sqlite3&, sqlite3_stmt&) {}
 | 
						|
        };
 | 
						|
 | 
						|
        std::uint64_t getPageSize(sqlite3& db)
 | 
						|
        {
 | 
						|
            Sqlite3::Statement<GetPageSize> statement(db);
 | 
						|
            std::uint64_t value = 0;
 | 
						|
            request(db, statement, &value, 1);
 | 
						|
            return value;
 | 
						|
        }
 | 
						|
 | 
						|
        void setMaxPageCount(sqlite3& db, std::uint64_t value)
 | 
						|
        {
 | 
						|
            const auto query = Misc::StringUtils::format("pragma max_page_count = %lu;", value);
 | 
						|
            if (const int ec = sqlite3_exec(&db, query.c_str(), nullptr, nullptr, nullptr); ec != SQLITE_OK)
 | 
						|
                throw std::runtime_error("Failed set max page count: " + std::string(sqlite3_errmsg(&db)));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    std::ostream& operator<<(std::ostream& stream, ShapeType value)
 | 
						|
    {
 | 
						|
        switch (value)
 | 
						|
        {
 | 
						|
            case ShapeType::Collision: return stream << "collision";
 | 
						|
            case ShapeType::Avoid: return stream << "avoid";
 | 
						|
        }
 | 
						|
        return stream << "unknown shape type (" << static_cast<std::underlying_type_t<ShapeType>>(value) << ")";
 | 
						|
    }
 | 
						|
 | 
						|
    NavMeshDb::NavMeshDb(std::string_view path, std::uint64_t maxFileSize)
 | 
						|
        : mDb(Sqlite3::makeDb(path, schema))
 | 
						|
        , mGetMaxTileId(*mDb, DbQueries::GetMaxTileId {})
 | 
						|
        , mFindTile(*mDb, DbQueries::FindTile {})
 | 
						|
        , mGetTileData(*mDb, DbQueries::GetTileData {})
 | 
						|
        , mInsertTile(*mDb, DbQueries::InsertTile {})
 | 
						|
        , mUpdateTile(*mDb, DbQueries::UpdateTile {})
 | 
						|
        , mDeleteTilesAt(*mDb, DbQueries::DeleteTilesAt {})
 | 
						|
        , mDeleteTilesAtExcept(*mDb, DbQueries::DeleteTilesAtExcept {})
 | 
						|
        , mDeleteTilesOutsideRange(*mDb, DbQueries::DeleteTilesOutsideRange {})
 | 
						|
        , mGetMaxShapeId(*mDb, DbQueries::GetMaxShapeId {})
 | 
						|
        , mFindShapeId(*mDb, DbQueries::FindShapeId {})
 | 
						|
        , mInsertShape(*mDb, DbQueries::InsertShape {})
 | 
						|
        , mVacuum(*mDb, DbQueries::Vacuum {})
 | 
						|
    {
 | 
						|
        const std::uint64_t dbPageSize = getPageSize(*mDb);
 | 
						|
        if (dbPageSize == 0)
 | 
						|
            throw std::runtime_error("NavMeshDb page size is zero");
 | 
						|
        setMaxPageCount(*mDb, maxFileSize / dbPageSize + static_cast<std::uint64_t>((maxFileSize % dbPageSize) != 0));
 | 
						|
    }
 | 
						|
 | 
						|
    Sqlite3::Transaction NavMeshDb::startTransaction(Sqlite3::TransactionMode mode)
 | 
						|
    {
 | 
						|
        return Sqlite3::Transaction(*mDb, mode);
 | 
						|
    }
 | 
						|
 | 
						|
    TileId NavMeshDb::getMaxTileId()
 | 
						|
    {
 | 
						|
        TileId tileId {0};
 | 
						|
        request(*mDb, mGetMaxTileId, &tileId, 1);
 | 
						|
        return tileId;
 | 
						|
    }
 | 
						|
 | 
						|
    std::optional<Tile> NavMeshDb::findTile(std::string_view worldspace,
 | 
						|
        const TilePosition& tilePosition, const std::vector<std::byte>& input)
 | 
						|
    {
 | 
						|
        Tile result;
 | 
						|
        auto row = std::tie(result.mTileId, result.mVersion);
 | 
						|
        const std::vector<std::byte> compressedInput = Misc::compress(input);
 | 
						|
        if (&row == request(*mDb, mFindTile, &row, 1, worldspace, tilePosition, compressedInput))
 | 
						|
            return {};
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    std::optional<TileData> NavMeshDb::getTileData(std::string_view worldspace,
 | 
						|
        const TilePosition& tilePosition, const std::vector<std::byte>& input)
 | 
						|
    {
 | 
						|
        TileData result;
 | 
						|
        auto row = std::tie(result.mTileId, result.mVersion, result.mData);
 | 
						|
        const std::vector<std::byte> compressedInput = Misc::compress(input);
 | 
						|
        if (&row == request(*mDb, mGetTileData, &row, 1, worldspace, tilePosition, compressedInput))
 | 
						|
            return {};
 | 
						|
        result.mData = Misc::decompress(result.mData);
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
 | 
						|
    int NavMeshDb::insertTile(TileId tileId, std::string_view worldspace, const TilePosition& tilePosition,
 | 
						|
        TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data)
 | 
						|
    {
 | 
						|
        const std::vector<std::byte> compressedInput = Misc::compress(input);
 | 
						|
        const std::vector<std::byte> compressedData = Misc::compress(data);
 | 
						|
        return execute(*mDb, mInsertTile, tileId, worldspace, tilePosition, version, compressedInput, compressedData);
 | 
						|
    }
 | 
						|
 | 
						|
    int NavMeshDb::updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data)
 | 
						|
    {
 | 
						|
        const std::vector<std::byte> compressedData = Misc::compress(data);
 | 
						|
        return execute(*mDb, mUpdateTile, tileId, version, compressedData);
 | 
						|
    }
 | 
						|
 | 
						|
    int NavMeshDb::deleteTilesAt(std::string_view worldspace, const TilePosition& tilePosition)
 | 
						|
    {
 | 
						|
        return execute(*mDb, mDeleteTilesAt, worldspace, tilePosition);
 | 
						|
    }
 | 
						|
 | 
						|
    int NavMeshDb::deleteTilesAtExcept(std::string_view worldspace, const TilePosition& tilePosition, TileId excludeTileId)
 | 
						|
    {
 | 
						|
        return execute(*mDb, mDeleteTilesAtExcept, worldspace, tilePosition, excludeTileId);
 | 
						|
    }
 | 
						|
 | 
						|
    int NavMeshDb::deleteTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range)
 | 
						|
    {
 | 
						|
        return execute(*mDb, mDeleteTilesOutsideRange, worldspace, range);
 | 
						|
    }
 | 
						|
 | 
						|
    ShapeId NavMeshDb::getMaxShapeId()
 | 
						|
    {
 | 
						|
        ShapeId shapeId {0};
 | 
						|
        request(*mDb, mGetMaxShapeId, &shapeId, 1);
 | 
						|
        return shapeId;
 | 
						|
    }
 | 
						|
 | 
						|
    std::optional<ShapeId> NavMeshDb::findShapeId(std::string_view name, ShapeType type,
 | 
						|
        const Sqlite3::ConstBlob& hash)
 | 
						|
    {
 | 
						|
        ShapeId shapeId;
 | 
						|
        if (&shapeId == request(*mDb, mFindShapeId, &shapeId, 1, name, type, hash))
 | 
						|
            return {};
 | 
						|
        return shapeId;
 | 
						|
    }
 | 
						|
 | 
						|
    int NavMeshDb::insertShape(ShapeId shapeId, std::string_view name, ShapeType type,
 | 
						|
        const Sqlite3::ConstBlob& hash)
 | 
						|
    {
 | 
						|
        return execute(*mDb, mInsertShape, shapeId, name, type, hash);
 | 
						|
    }
 | 
						|
 | 
						|
    void NavMeshDb::vacuum()
 | 
						|
    {
 | 
						|
        execute(*mDb, mVacuum);
 | 
						|
    }
 | 
						|
 | 
						|
    namespace DbQueries
 | 
						|
    {
 | 
						|
        std::string_view GetMaxTileId::text() noexcept
 | 
						|
        {
 | 
						|
            return getMaxTileIdQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view FindTile::text() noexcept
 | 
						|
        {
 | 
						|
            return findTileQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void FindTile::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
 | 
						|
            const TilePosition& tilePosition, const std::vector<std::byte>& input)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":input", input);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view GetTileData::text() noexcept
 | 
						|
        {
 | 
						|
            return getTileDataQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void GetTileData::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
 | 
						|
            const TilePosition& tilePosition, const std::vector<std::byte>& input)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":input", input);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view InsertTile::text() noexcept
 | 
						|
        {
 | 
						|
            return insertTileQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void InsertTile::bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, std::string_view worldspace,
 | 
						|
            const TilePosition& tilePosition, TileVersion version, const std::vector<std::byte>& input,
 | 
						|
            const std::vector<std::byte>& data)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_id", tileId);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":version", version);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":input", input);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":data", data);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view UpdateTile::text() noexcept
 | 
						|
        {
 | 
						|
            return updateTileQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void UpdateTile::bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, TileVersion version,
 | 
						|
            const std::vector<std::byte>& data)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_id", tileId);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":version", version);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":data", data);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view DeleteTilesAt::text() noexcept
 | 
						|
        {
 | 
						|
            return deleteTilesAtQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void DeleteTilesAt::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
 | 
						|
            const TilePosition& tilePosition)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view DeleteTilesAtExcept::text() noexcept
 | 
						|
        {
 | 
						|
            return deleteTilesAtExceptQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void DeleteTilesAtExcept::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
 | 
						|
            const TilePosition& tilePosition, TileId excludeTileId)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":exclude_tile_id", excludeTileId);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view DeleteTilesOutsideRange::text() noexcept
 | 
						|
        {
 | 
						|
            return deleteTilesOutsideRangeQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void DeleteTilesOutsideRange::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
 | 
						|
            const TilesPositionsRange& range)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":begin_tile_position_x", range.mBegin.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":begin_tile_position_y", range.mBegin.y());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":end_tile_position_x", range.mEnd.x());
 | 
						|
            Sqlite3::bindParameter(db, statement, ":end_tile_position_y", range.mEnd.y());
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view GetMaxShapeId::text() noexcept
 | 
						|
        {
 | 
						|
            return getMaxShapeIdQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view FindShapeId::text() noexcept
 | 
						|
        {
 | 
						|
            return findShapeIdQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void FindShapeId::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view name,
 | 
						|
            ShapeType type, const Sqlite3::ConstBlob& hash)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":name", name);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":type", static_cast<int>(type));
 | 
						|
            Sqlite3::bindParameter(db, statement, ":hash", hash);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view InsertShape::text() noexcept
 | 
						|
        {
 | 
						|
            return insertShapeQuery;
 | 
						|
        }
 | 
						|
 | 
						|
        void InsertShape::bind(sqlite3& db, sqlite3_stmt& statement, ShapeId shapeId, std::string_view name,
 | 
						|
            ShapeType type, const Sqlite3::ConstBlob& hash)
 | 
						|
        {
 | 
						|
            Sqlite3::bindParameter(db, statement, ":shape_id", shapeId);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":name", name);
 | 
						|
            Sqlite3::bindParameter(db, statement, ":type", static_cast<int>(type));
 | 
						|
            Sqlite3::bindParameter(db, statement, ":hash", hash);
 | 
						|
        }
 | 
						|
 | 
						|
        std::string_view Vacuum::text() noexcept
 | 
						|
        {
 | 
						|
            return vacuumQuery;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |