aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Access/Common/AccessFlags.h
blob: c9672da7d926ed0752d9feaeae9450ca642ec7fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#pragma once

#include <Access/Common/AccessType.h>
#include <bitset>
#include <cstring>
#include <vector>
#include <unordered_map>


namespace DB
{
using Strings = std::vector<String>;

/// Represents a combination of access types which can be granted globally, on databases, tables, columns, etc.
/// For example "SELECT, CREATE USER" is an access type.
class AccessFlags
{
public:
    AccessFlags(AccessType type); /// NOLINT

    /// The same as AccessFlags(AccessType::NONE).
    AccessFlags() = default;

    /// Constructs from a string like "SELECT".
    AccessFlags(std::string_view keyword); /// NOLINT

    /// Constructs from a list of strings like "SELECT, UPDATE, INSERT".
    AccessFlags(const std::vector<std::string_view> & keywords); /// NOLINT
    AccessFlags(const Strings & keywords); /// NOLINT

    AccessFlags(const AccessFlags & src) = default;
    AccessFlags(AccessFlags && src) = default;
    AccessFlags & operator =(const AccessFlags & src) = default;
    AccessFlags & operator =(AccessFlags && src) = default;

    /// Returns the access type which contains two specified access types.
    AccessFlags & operator |=(const AccessFlags & other) { flags |= other.flags; return *this; }
    friend AccessFlags operator |(const AccessFlags & left, const AccessFlags & right) { return AccessFlags(left) |= right; }

    /// Returns the access type which contains the common part of two access types.
    AccessFlags & operator &=(const AccessFlags & other) { flags &= other.flags; return *this; }
    friend AccessFlags operator &(const AccessFlags & left, const AccessFlags & right) { return AccessFlags(left) &= right; }

    /// Returns the access type which contains only the part of the first access type which is not the part of the second access type.
    /// (lhs - rhs) is the same as (lhs & ~rhs).
    AccessFlags & operator -=(const AccessFlags & other) { flags &= ~other.flags; return *this; }
    friend AccessFlags operator -(const AccessFlags & left, const AccessFlags & right) { return AccessFlags(left) -= right; }

    AccessFlags operator ~() const { AccessFlags res; res.flags = ~flags; return res; }

    bool isEmpty() const { return flags.none(); }
    bool isAll() const { return flags.all(); }
    explicit operator bool() const { return !isEmpty(); }
    bool contains(const AccessFlags & other) const { return (flags & other.flags) == other.flags; }
    bool isGlobalWithParameter() const;
    enum ParameterType
    {
        NONE,
        NAMED_COLLECTION,
    };
    ParameterType getParameterType() const;
    std::unordered_map<ParameterType, AccessFlags> splitIntoParameterTypes() const;

    friend bool operator ==(const AccessFlags & left, const AccessFlags & right) { return left.flags == right.flags; }
    friend bool operator !=(const AccessFlags & left, const AccessFlags & right) { return !(left == right); }
    friend bool operator <(const AccessFlags & left, const AccessFlags & right) { return memcmp(&left.flags, &right.flags, sizeof(Flags)) < 0; }
    friend bool operator >(const AccessFlags & left, const AccessFlags & right) { return right < left; }
    friend bool operator <=(const AccessFlags & left, const AccessFlags & right) { return !(right < left); }
    friend bool operator >=(const AccessFlags & left, const AccessFlags & right) { return !(left < right); }

    void clear() { flags.reset(); }

    /// Returns a comma-separated list of keywords, like "SELECT, CREATE USER, UPDATE".
    String toString() const;

    /// Returns a list of access types.
    std::vector<AccessType> toAccessTypes() const;

    /// Returns a list of keywords.
    std::vector<std::string_view> toKeywords() const;

    /// Returns all the flags.
    /// These are the same as (allGlobalFlags() | allDatabaseFlags() | allTableFlags() | allColumnsFlags() | allDictionaryFlags()).
    static AccessFlags allFlags();

    /// Returns all the global flags.
    static AccessFlags allGlobalFlags();

    static AccessFlags allGlobalWithParameterFlags();

    /// Returns all the flags related to a database.
    static AccessFlags allDatabaseFlags();

    /// Returns all the flags related to a table.
    static AccessFlags allTableFlags();

    /// Returns all the flags related to a column.
    static AccessFlags allColumnFlags();

    /// Returns all the flags related to a dictionary.
    static AccessFlags allDictionaryFlags();

    /// Returns all the flags related to a named collection.
    static AccessFlags allNamedCollectionFlags();

    /// Returns all the flags which could be granted on the global level.
    /// The same as allFlags().
    static AccessFlags allFlagsGrantableOnGlobalLevel();

    /// Returns all the flags which could be granted on the global with parameter level.
    static AccessFlags allFlagsGrantableOnGlobalWithParameterLevel();

    /// Returns all the flags which could be granted on the database level.
    /// Returns allDatabaseFlags() | allTableFlags() | allDictionaryFlags() | allColumnFlags().
    static AccessFlags allFlagsGrantableOnDatabaseLevel();

    /// Returns all the flags which could be granted on the table level.
    /// Returns allTableFlags() | allDictionaryFlags() | allColumnFlags().
    static AccessFlags allFlagsGrantableOnTableLevel();

    /// Returns all the flags which could be granted on the global level.
    /// The same as allColumnFlags().
    static AccessFlags allFlagsGrantableOnColumnLevel();

    static constexpr size_t SIZE = 256;
private:
    using Flags = std::bitset<SIZE>;
    Flags flags;

    AccessFlags(const Flags & flags_) : flags(flags_) {} /// NOLINT
};

AccessFlags operator |(AccessType left, AccessType right);
AccessFlags operator &(AccessType left, AccessType right);
AccessFlags operator -(AccessType left, AccessType right);
AccessFlags operator ~(AccessType x);

}