1cab1f89eSJim Walker/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2cab1f89eSJim Walker/*
3cab1f89eSJim Walker *     Copyright 2017 Couchbase, Inc
4cab1f89eSJim Walker *
5cab1f89eSJim Walker *   Licensed under the Apache License, Version 2.0 (the "License");
6cab1f89eSJim Walker *   you may not use this file except in compliance with the License.
7cab1f89eSJim Walker *   You may obtain a copy of the License at
8cab1f89eSJim Walker *
9cab1f89eSJim Walker *       http://www.apache.org/licenses/LICENSE-2.0
10cab1f89eSJim Walker *
11cab1f89eSJim Walker *   Unless required by applicable law or agreed to in writing, software
12cab1f89eSJim Walker *   distributed under the License is distributed on an "AS IS" BASIS,
13cab1f89eSJim Walker *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14cab1f89eSJim Walker *   See the License for the specific language governing permissions and
15cab1f89eSJim Walker *   limitations under the License.
16cab1f89eSJim Walker */
17cab1f89eSJim Walker
18cab1f89eSJim Walker#pragma once
19cab1f89eSJim Walker
2099b0b58bSJim Walker#include <platform/sized_buffer.h>
2199b0b58bSJim Walker
22cab1f89eSJim Walkernamespace Collections {
23cab1f89eSJim Walker
24cab1f89eSJim Walker// The reserved name of the system owned, default collection.
2599b0b58bSJim Walkerconst char* const _DefaultCollectionIdentifier = "$default";
2699b0b58bSJim Walkerstatic cb::const_char_buffer DefaultCollectionIdentifier(
2799b0b58bSJim Walker        _DefaultCollectionIdentifier);
28cab1f89eSJim Walker
29cab1f89eSJim Walker// The default separator we will use for identifying collections in keys.
304730ffcfSJim Walkerconst char* const DefaultSeparator = ":";
312f12cd1aSJim Walker
32dea18910SJim Walker// SystemEvent keys or parts which will be made into keys
33dea18910SJim Walkerconst char* const SystemSeparator = ":"; // Note this never changes
34e57f09f4SJim Walkerconst char* const SystemEventPrefix = "$collections";
35dea18910SJim Walkerconst char* const SystemEventPrefixWithSeparator = "$collections:";
36dea18910SJim Walkerconst char* const SeparatorChangePrefix = "$collections_separator";
37dea18910SJim Walkerconst char* const SeparatorChangePrefixWithSeparator =
38dea18910SJim Walker        "$collections_separator:";
39dea18910SJim Walkerconst char* const DeleteKey = "$collections:delete:";
40cab1f89eSJim Walker
41d7615449SJim Walker// Couchstore private file name for manifest data
42d7615449SJim Walkerconst char CouchstoreManifest[] = "_local/collections_manifest";
43d7615449SJim Walker
44d7615449SJim Walker// Length of the string excluding the zero terminator (i.e. strlen)
45d7615449SJim Walkerconst size_t CouchstoreManifestLen = sizeof(CouchstoreManifest) - 1;
46d7615449SJim Walker
4730aab6b7SJim Walkerusing uid_t = uint64_t;
4830aab6b7SJim Walker
49cd98cc03SJim Walker/**
50cd98cc03SJim Walker * Return a uid from a C-string.
51cd98cc03SJim Walker * A valid uid is a C-string where each character satisfies std::isxdigit
52cd98cc03SJim Walker * and can be converted to a uid_t by std::strtoull.
53cd98cc03SJim Walker *
54cd98cc03SJim Walker * @param uid C-string uid
55cd98cc03SJim Walker * @throws std::invalid_argument if uid is invalid
56cd98cc03SJim Walker */
57cd98cc03SJim Walkeruid_t makeUid(const char* uid);
58cd98cc03SJim Walker
5930aab6b7SJim Walker/**
6030aab6b7SJim Walker * Interface definition for the a collection identifier - a pair of name and UID
6130aab6b7SJim Walker * Forces compile time dispatch for the 3 required methods.
6230aab6b7SJim Walker * getUid, getName and isDefaultCollection
6330aab6b7SJim Walker */
6430aab6b7SJim Walkertemplate <class T>
6530aab6b7SJim Walkerclass IdentifierInterface {
6630aab6b7SJim Walkerpublic:
6730aab6b7SJim Walker    /// @returns the UID for this identifier
6830aab6b7SJim Walker    uid_t getUid() const {
6930aab6b7SJim Walker        return static_cast<const T*>(this)->getUid();
7030aab6b7SJim Walker    }
7130aab6b7SJim Walker
7230aab6b7SJim Walker    /// @returns the name for this identifier
7330aab6b7SJim Walker    cb::const_char_buffer getName() const {
7430aab6b7SJim Walker        return static_cast<const T*>(this)->getName();
7530aab6b7SJim Walker    }
7630aab6b7SJim Walker
7730aab6b7SJim Walker    /// @returns true if the identifer's name matches the default name
7830aab6b7SJim Walker    bool isDefaultCollection() const {
7930aab6b7SJim Walker        return getName() == DefaultCollectionIdentifier;
8030aab6b7SJim Walker    }
8130aab6b7SJim Walker};
829160b844SJim Walker
839160b844SJim Walker/**
849160b844SJim Walker * A collection may exist concurrently, where one maybe open and the others
859160b844SJim Walker * are in the process of being erased. This class carries the information for
869160b844SJim Walker * locating the correct "generation" of a collection.
879160b844SJim Walker */
8830aab6b7SJim Walkerclass Identifier : public IdentifierInterface<Identifier> {
899160b844SJim Walkerpublic:
909160b844SJim Walker    Identifier(cb::const_char_buffer name, uid_t uid) : name(name), uid(uid) {
919160b844SJim Walker    }
929160b844SJim Walker
9330aab6b7SJim Walker    template <class T>
9430aab6b7SJim Walker    Identifier(const IdentifierInterface<T>& identifier)
9530aab6b7SJim Walker        : name(identifier.getName()), uid(identifier.getUid()) {
9630aab6b7SJim Walker    }
9730aab6b7SJim Walker
989160b844SJim Walker    cb::const_char_buffer getName() const {
999160b844SJim Walker        return name;
1009160b844SJim Walker    }
1019160b844SJim Walker
1029160b844SJim Walker    uid_t getUid() const {
1039160b844SJim Walker        return uid;
1049160b844SJim Walker    }
1059160b844SJim Walker
1069160b844SJim Walkerprivate:
1079160b844SJim Walker    cb::const_char_buffer name;
1089160b844SJim Walker    uid_t uid;
1099160b844SJim Walker};
1109160b844SJim Walker
111cd24b1b3SJim Walker/**
112cd24b1b3SJim Walker * All of the data a DCP system event message will carry.
113cd24b1b3SJim Walker * This covers create and delete collection.
114cd24b1b3SJim Walker * This struct is not the layout of such data.
115cd24b1b3SJim Walker */
116cd24b1b3SJim Walkerstruct SystemEventData {
117cd24b1b3SJim Walker    /// UID of manifest which triggered the event
118cd24b1b3SJim Walker    Collections::uid_t manifestUid;
119cd24b1b3SJim Walker    /// Identifier of the affected collection (name and UID).
120cd24b1b3SJim Walker    Identifier id;
121cd24b1b3SJim Walker};
122cd24b1b3SJim Walker
123cd24b1b3SJim Walker/**
124cd24b1b3SJim Walker * All of the data a DCP system event message will carry (for create/delete).
125cd24b1b3SJim Walker * This is the layout of such data and the collection name is the key of the
126cd24b1b3SJim Walker * event packet.
127cd24b1b3SJim Walker */
128cd24b1b3SJim Walkerstruct SystemEventDCPData {
129cd24b1b3SJim Walker    /// The manifest uid stored in network byte order ready for sending
130cd24b1b3SJim Walker    Collections::uid_t manifestUid;
131cd24b1b3SJim Walker    /// The collection uid stored in network byte order ready for sending
132cd24b1b3SJim Walker    Collections::uid_t collectionUid;
133cd24b1b3SJim Walker};
134cd24b1b3SJim Walker
135cd24b1b3SJim Walker/**
136cd24b1b3SJim Walker * All of the data a DCP separator changed system event message will carry.
137cd24b1b3SJim Walker * This struct is not the layout of such data.
138cd24b1b3SJim Walker */
139cd24b1b3SJim Walkerstruct SystemEventSeparatorData {
140cd24b1b3SJim Walker    /// UID of manifest which triggered the change of separator
141cd24b1b3SJim Walker    Collections::uid_t manifestUid;
142cd24b1b3SJim Walker    /// The new separator
143cd24b1b3SJim Walker    cb::const_char_buffer separator;
144cd24b1b3SJim Walker};
145cd24b1b3SJim Walker
14630aab6b7SJim Walkerstd::string to_string(const Identifier& identifier);
14730aab6b7SJim Walker
14830aab6b7SJim Walkerstd::ostream& operator<<(std::ostream& os, const Identifier& identifier);
1499160b844SJim Walker
150cab1f89eSJim Walker} // end namespace Collections