go.temporal.io/server@v1.23.0/common/persistence/sql/sqlplugin/mysql/namespace.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package mysql 26 27 import ( 28 "context" 29 "database/sql" 30 "errors" 31 32 "go.temporal.io/api/serviceerror" 33 34 "go.temporal.io/server/common/persistence/sql/sqlplugin" 35 ) 36 37 const ( 38 createNamespaceQuery = `INSERT INTO 39 namespaces (partition_id, id, name, is_global, data, data_encoding, notification_version) 40 VALUES(?, ?, ?, ?, ?, ?, ?)` 41 42 updateNamespaceQuery = `UPDATE namespaces 43 SET name = ?, data = ?, data_encoding = ?, is_global = ?, notification_version = ? 44 WHERE partition_id=54321 AND id = ?` 45 46 getNamespacePart = `SELECT id, name, is_global, data, data_encoding, notification_version FROM namespaces` 47 48 getNamespaceByIDQuery = getNamespacePart + ` WHERE partition_id=? AND id = ?` 49 getNamespaceByNameQuery = getNamespacePart + ` WHERE partition_id=? AND name = ?` 50 51 listNamespacesQuery = getNamespacePart + ` WHERE partition_id=? ORDER BY id LIMIT ?` 52 listNamespacesRangeQuery = getNamespacePart + ` WHERE partition_id=? AND id > ? ORDER BY id LIMIT ?` 53 54 deleteNamespaceByIDQuery = `DELETE FROM namespaces WHERE partition_id=? AND id = ?` 55 deleteNamespaceByNameQuery = `DELETE FROM namespaces WHERE partition_id=? AND name = ?` 56 57 getNamespaceMetadataQuery = `SELECT notification_version FROM namespace_metadata WHERE partition_id = 54321` 58 lockNamespaceMetadataQuery = `SELECT notification_version FROM namespace_metadata WHERE partition_id = 54321 FOR UPDATE` 59 updateNamespaceMetadataQuery = `UPDATE namespace_metadata SET notification_version = ? WHERE notification_version = ? AND partition_id = 54321` 60 ) 61 62 const ( 63 partitionID = 54321 64 ) 65 66 var errMissingArgs = errors.New("missing one or more args for API") 67 68 // InsertIntoNamespace inserts a single row into namespaces table 69 func (mdb *db) InsertIntoNamespace( 70 ctx context.Context, 71 row *sqlplugin.NamespaceRow, 72 ) (sql.Result, error) { 73 return mdb.conn.ExecContext(ctx, 74 createNamespaceQuery, 75 partitionID, 76 row.ID, 77 row.Name, 78 row.IsGlobal, 79 row.Data, 80 row.DataEncoding, 81 row.NotificationVersion, 82 ) 83 } 84 85 // UpdateNamespace updates a single row in namespaces table 86 func (mdb *db) UpdateNamespace( 87 ctx context.Context, 88 row *sqlplugin.NamespaceRow, 89 ) (sql.Result, error) { 90 return mdb.conn.ExecContext(ctx, 91 updateNamespaceQuery, 92 row.Name, 93 row.Data, 94 row.DataEncoding, 95 row.IsGlobal, 96 row.NotificationVersion, 97 row.ID, 98 ) 99 } 100 101 // SelectFromNamespace reads one or more rows from namespaces table 102 func (mdb *db) SelectFromNamespace( 103 ctx context.Context, 104 filter sqlplugin.NamespaceFilter, 105 ) ([]sqlplugin.NamespaceRow, error) { 106 switch { 107 case filter.ID != nil || filter.Name != nil: 108 if filter.ID != nil && filter.Name != nil { 109 return nil, serviceerror.NewInternal("only ID or name filter can be specified for selection") 110 } 111 return mdb.selectFromNamespace(ctx, filter) 112 case filter.PageSize != nil && *filter.PageSize > 0: 113 return mdb.selectAllFromNamespace(ctx, filter) 114 default: 115 return nil, errMissingArgs 116 } 117 } 118 119 func (mdb *db) selectFromNamespace( 120 ctx context.Context, 121 filter sqlplugin.NamespaceFilter, 122 ) ([]sqlplugin.NamespaceRow, error) { 123 var err error 124 var row sqlplugin.NamespaceRow 125 switch { 126 case filter.ID != nil: 127 err = mdb.conn.GetContext(ctx, 128 &row, 129 getNamespaceByIDQuery, 130 partitionID, 131 *filter.ID, 132 ) 133 case filter.Name != nil: 134 err = mdb.conn.GetContext(ctx, 135 &row, 136 getNamespaceByNameQuery, 137 partitionID, 138 *filter.Name, 139 ) 140 } 141 if err != nil { 142 return nil, err 143 } 144 return []sqlplugin.NamespaceRow{row}, nil 145 } 146 147 func (mdb *db) selectAllFromNamespace( 148 ctx context.Context, 149 filter sqlplugin.NamespaceFilter, 150 ) ([]sqlplugin.NamespaceRow, error) { 151 var err error 152 var rows []sqlplugin.NamespaceRow 153 switch { 154 case filter.GreaterThanID != nil: 155 err = mdb.conn.SelectContext(ctx, 156 &rows, 157 listNamespacesRangeQuery, 158 partitionID, 159 *filter.GreaterThanID, 160 *filter.PageSize, 161 ) 162 default: 163 err = mdb.conn.SelectContext(ctx, 164 &rows, 165 listNamespacesQuery, 166 partitionID, 167 filter.PageSize, 168 ) 169 } 170 return rows, err 171 } 172 173 // DeleteFromNamespace deletes a single row in namespaces table 174 func (mdb *db) DeleteFromNamespace( 175 ctx context.Context, 176 filter sqlplugin.NamespaceFilter, 177 ) (sql.Result, error) { 178 var err error 179 var result sql.Result 180 switch { 181 case filter.ID != nil: 182 result, err = mdb.conn.ExecContext(ctx, 183 deleteNamespaceByIDQuery, 184 partitionID, 185 filter.ID, 186 ) 187 default: 188 result, err = mdb.conn.ExecContext(ctx, 189 deleteNamespaceByNameQuery, 190 partitionID, 191 filter.Name, 192 ) 193 } 194 return result, err 195 } 196 197 // LockNamespaceMetadata acquires a write lock on a single row in namespace_metadata table 198 func (mdb *db) LockNamespaceMetadata( 199 ctx context.Context, 200 ) (*sqlplugin.NamespaceMetadataRow, error) { 201 var row sqlplugin.NamespaceMetadataRow 202 err := mdb.conn.GetContext(ctx, 203 &row.NotificationVersion, 204 lockNamespaceMetadataQuery, 205 ) 206 if err != nil { 207 return nil, err 208 } 209 return &row, nil 210 } 211 212 // SelectFromNamespaceMetadata reads a single row in namespace_metadata table 213 func (mdb *db) SelectFromNamespaceMetadata( 214 ctx context.Context, 215 ) (*sqlplugin.NamespaceMetadataRow, error) { 216 var row sqlplugin.NamespaceMetadataRow 217 err := mdb.conn.GetContext(ctx, 218 &row.NotificationVersion, 219 getNamespaceMetadataQuery, 220 ) 221 return &row, err 222 } 223 224 // UpdateNamespaceMetadata updates a single row in namespace_metadata table 225 func (mdb *db) UpdateNamespaceMetadata( 226 ctx context.Context, 227 row *sqlplugin.NamespaceMetadataRow, 228 ) (sql.Result, error) { 229 return mdb.conn.ExecContext(ctx, 230 updateNamespaceMetadataQuery, 231 row.NotificationVersion+1, 232 row.NotificationVersion, 233 ) 234 }