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  }