github.com/dolthub/go-mysql-server@v0.18.0/sql/in_mem_table/multimaptable.go (about) 1 // Copyright 2023 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package in_mem_table 16 17 import ( 18 "sync" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 ) 22 23 func ToRows[V any](ctx *sql.Context, ops *ValueOps[V], is IndexedSet[V]) ([]sql.Row, error) { 24 var res []sql.Row 25 var err error 26 is.VisitEntries(func(v V) { 27 if err != nil { 28 return 29 } 30 var r sql.Row 31 r, err = ops.ToRow(ctx, v) 32 if err == nil { 33 res = append(res, r) 34 } 35 }) 36 if err != nil { 37 return nil, err 38 } 39 return res, nil 40 } 41 42 func MultiToRows[V any](ctx *sql.Context, ops *MultiValueOps[V], is IndexedSet[V]) ([]sql.Row, error) { 43 var res []sql.Row 44 var err error 45 is.VisitEntries(func(v V) { 46 if err != nil { 47 return 48 } 49 var rs []sql.Row 50 rs, err = ops.ToRows(ctx, v) 51 if err == nil { 52 res = append(res, rs...) 53 } 54 }) 55 if err != nil { 56 return nil, err 57 } 58 return res, nil 59 } 60 61 var _ sql.Table = (*IndexedSetTable[string])(nil) 62 var _ sql.InsertableTable = (*IndexedSetTable[string])(nil) 63 var _ sql.UpdatableTable = (*IndexedSetTable[string])(nil) 64 var _ sql.DeletableTable = (*IndexedSetTable[string])(nil) 65 var _ sql.ReplaceableTable = (*IndexedSetTable[string])(nil) 66 var _ sql.TruncateableTable = (*IndexedSetTable[string])(nil) 67 68 type IndexedSetTable[V any] struct { 69 name string 70 schema sql.Schema 71 coll sql.CollationID 72 73 set IndexedSet[V] 74 ops ValueOps[V] 75 76 lock sync.Locker 77 rlock sync.Locker 78 } 79 80 func NewIndexedSetTable[V any](name string, schema sql.Schema, coll sql.CollationID, set IndexedSet[V], ops ValueOps[V], lock, rlock sync.Locker) *IndexedSetTable[V] { 81 return &IndexedSetTable[V]{ 82 name, 83 schema, 84 coll, 85 set, 86 ops, 87 lock, 88 rlock, 89 } 90 } 91 92 func (t *IndexedSetTable[V]) TableId() sql.TableId { 93 return 0 94 } 95 96 func (t *IndexedSetTable[V]) Set() IndexedSet[V] { 97 return t.set 98 } 99 100 func (t *IndexedSetTable[V]) Name() string { 101 return t.name 102 } 103 104 func (t *IndexedSetTable[V]) String() string { 105 return t.Name() 106 } 107 108 func (t *IndexedSetTable[V]) Schema() sql.Schema { 109 return t.schema 110 } 111 112 func (t *IndexedSetTable[V]) Collation() sql.CollationID { 113 return t.coll 114 } 115 116 func (t *IndexedSetTable[V]) Partitions(ctx *sql.Context) (sql.PartitionIter, error) { 117 return sql.PartitionsToPartitionIter(partition{}), nil 118 } 119 120 func (t *IndexedSetTable[V]) PartitionRows(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) { 121 t.rlock.Lock() 122 defer t.rlock.Unlock() 123 rows, err := ToRows[V](ctx, &t.ops, t.set) 124 if err != nil { 125 return nil, err 126 } 127 return sql.RowsToRowIter(rows...), nil 128 } 129 130 func (t *IndexedSetTable[V]) Inserter(ctx *sql.Context) sql.RowInserter { 131 return t.Editor() 132 } 133 134 func (t *IndexedSetTable[V]) Updater(ctx *sql.Context) sql.RowUpdater { 135 return t.Editor() 136 } 137 138 func (t *IndexedSetTable[V]) Deleter(ctx *sql.Context) sql.RowDeleter { 139 return t.Editor() 140 } 141 142 func (t *IndexedSetTable[V]) Replacer(ctx *sql.Context) sql.RowReplacer { 143 return t.Editor() 144 } 145 146 func (t *IndexedSetTable[V]) Truncate(ctx *sql.Context) (int, error) { 147 t.lock.Lock() 148 defer t.lock.Unlock() 149 c := t.set.Count() 150 t.set.Clear() 151 return c, nil 152 } 153 154 type editor interface { 155 sql.RowInserter 156 sql.RowUpdater 157 sql.RowDeleter 158 sql.RowReplacer 159 } 160 161 func (t *IndexedSetTable[V]) Editor() editor { 162 return OperationLockingTableEditor{ 163 t.lock, 164 &IndexedSetTableEditor[V]{ 165 t.set, 166 t.ops, 167 }, 168 } 169 } 170 171 var _ sql.Table = (*MultiIndexedSetTable[string])(nil) 172 var _ sql.InsertableTable = (*MultiIndexedSetTable[string])(nil) 173 var _ sql.UpdatableTable = (*MultiIndexedSetTable[string])(nil) 174 var _ sql.DeletableTable = (*MultiIndexedSetTable[string])(nil) 175 var _ sql.ReplaceableTable = (*MultiIndexedSetTable[string])(nil) 176 177 type MultiIndexedSetTable[V any] struct { 178 name string 179 schema sql.Schema 180 coll sql.CollationID 181 182 set IndexedSet[V] 183 ops MultiValueOps[V] 184 185 lock sync.Locker 186 rlock sync.Locker 187 } 188 189 func NewMultiIndexedSetTable[V any](name string, schema sql.Schema, coll sql.CollationID, set IndexedSet[V], ops MultiValueOps[V], lock, rlock sync.Locker) *MultiIndexedSetTable[V] { 190 return &MultiIndexedSetTable[V]{ 191 name, 192 schema, 193 coll, 194 set, 195 ops, 196 lock, 197 rlock, 198 } 199 } 200 201 func (t *MultiIndexedSetTable[V]) Set() IndexedSet[V] { 202 return t.set 203 } 204 205 func (t *MultiIndexedSetTable[V]) Name() string { 206 return t.name 207 } 208 209 func (t *MultiIndexedSetTable[V]) String() string { 210 return t.Name() 211 } 212 213 func (t *MultiIndexedSetTable[V]) Schema() sql.Schema { 214 return t.schema 215 } 216 217 func (t *MultiIndexedSetTable[V]) Collation() sql.CollationID { 218 return t.coll 219 } 220 221 func (t *MultiIndexedSetTable[V]) Partitions(ctx *sql.Context) (sql.PartitionIter, error) { 222 return sql.PartitionsToPartitionIter(partition{}), nil 223 } 224 225 func (t *MultiIndexedSetTable[V]) PartitionRows(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) { 226 t.rlock.Lock() 227 defer t.rlock.Unlock() 228 rows, err := MultiToRows[V](ctx, &t.ops, t.set) 229 if err != nil { 230 return nil, err 231 } 232 return sql.RowsToRowIter(rows...), nil 233 } 234 235 func (t *MultiIndexedSetTable[V]) Inserter(ctx *sql.Context) sql.RowInserter { 236 return t.Editor() 237 } 238 239 func (t *MultiIndexedSetTable[V]) Updater(ctx *sql.Context) sql.RowUpdater { 240 return t.Editor() 241 } 242 243 func (t *MultiIndexedSetTable[V]) Deleter(ctx *sql.Context) sql.RowDeleter { 244 return t.Editor() 245 } 246 247 func (t *MultiIndexedSetTable[V]) Replacer(ctx *sql.Context) sql.RowReplacer { 248 return t.Editor() 249 } 250 251 func (t *MultiIndexedSetTable[V]) Editor() editor { 252 return OperationLockingTableEditor{ 253 t.lock, 254 &MultiIndexedSetTableEditor[V]{ 255 t.set, 256 t.ops, 257 }, 258 } 259 } 260 261 type partition struct{} 262 263 var _ sql.Partition = partition{} 264 265 func (partition) Key() []byte { 266 return nil 267 }