github.com/dolthub/go-mysql-server@v0.18.0/sql/fulltext/multi_editor.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 fulltext 16 17 import ( 18 "fmt" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 ) 22 23 // MultiTableEditor wraps multiple table editors, allowing for a single function to handle writes across multiple tables. 24 type MultiTableEditor struct { 25 primary sql.TableEditor 26 secondaries []sql.TableEditor 27 } 28 29 var _ sql.TableEditor = MultiTableEditor{} 30 var _ sql.ForeignKeyEditor = MultiTableEditor{} 31 var _ sql.AutoIncrementSetter = MultiTableEditor{} 32 33 // CreateMultiTableEditor creates a TableEditor that writes to both the primary and secondary editors. The primary 34 // editor must implement ForeignKeyEditor and AutoIncrementSetter in addition to TableEditor. 35 func CreateMultiTableEditor(ctx *sql.Context, primary sql.TableEditor, secondaries ...sql.TableEditor) (sql.TableEditor, error) { 36 if _, ok := primary.(sql.ForeignKeyEditor); !ok { 37 return nil, fmt.Errorf("cannot create a MultiTableEditor with a primary editor that does not implement ForeignKeyEditor") 38 } 39 if _, ok := primary.(sql.AutoIncrementSetter); !ok { 40 return nil, fmt.Errorf("cannot create a MultiTableEditor with a primary editor that does not implement AutoIncrementSetter") 41 } 42 return MultiTableEditor{ 43 primary: primary, 44 secondaries: secondaries, 45 }, nil 46 } 47 48 // PrimaryEditor returns the primary editor. 49 func (editor MultiTableEditor) PrimaryEditor() sql.TableEditor { 50 return editor.primary 51 } 52 53 // SecondaryEditors returns the secondary editors. 54 func (editor MultiTableEditor) SecondaryEditors() []sql.TableEditor { 55 return editor.secondaries 56 } 57 58 // StatementBegin implements the interface sql.TableEditor. 59 func (editor MultiTableEditor) StatementBegin(ctx *sql.Context) { 60 for _, secondary := range editor.secondaries { 61 secondary.StatementBegin(ctx) 62 } 63 editor.primary.StatementBegin(ctx) 64 } 65 66 // DiscardChanges implements the interface sql.TableEditor. 67 func (editor MultiTableEditor) DiscardChanges(ctx *sql.Context, errorEncountered error) error { 68 var err error 69 for _, secondary := range editor.secondaries { 70 if nErr := secondary.DiscardChanges(ctx, errorEncountered); err == nil { 71 err = nErr 72 } 73 } 74 if nErr := editor.primary.DiscardChanges(ctx, errorEncountered); err == nil { 75 err = nErr 76 } 77 return err 78 } 79 80 // StatementComplete implements the interface sql.TableEditor. 81 func (editor MultiTableEditor) StatementComplete(ctx *sql.Context) error { 82 var err error 83 for _, secondary := range editor.secondaries { 84 if nErr := secondary.StatementComplete(ctx); err == nil { 85 err = nErr 86 } 87 } 88 if nErr := editor.primary.StatementComplete(ctx); err == nil { 89 err = nErr 90 } 91 return err 92 } 93 94 // Insert implements the interface sql.TableEditor. 95 func (editor MultiTableEditor) Insert(ctx *sql.Context, row sql.Row) error { 96 for _, secondary := range editor.secondaries { 97 if err := secondary.Insert(ctx, row); err != nil { 98 return err 99 } 100 } 101 return editor.primary.Insert(ctx, row) 102 } 103 104 // Update implements the interface sql.TableEditor. 105 func (editor MultiTableEditor) Update(ctx *sql.Context, old sql.Row, new sql.Row) error { 106 for _, secondary := range editor.secondaries { 107 if err := secondary.Update(ctx, old, new); err != nil { 108 return err 109 } 110 } 111 return editor.primary.Update(ctx, old, new) 112 } 113 114 // Delete implements the interface sql.TableEditor. 115 func (editor MultiTableEditor) Delete(ctx *sql.Context, row sql.Row) error { 116 for _, secondary := range editor.secondaries { 117 if err := secondary.Delete(ctx, row); err != nil { 118 return err 119 } 120 } 121 return editor.primary.Delete(ctx, row) 122 } 123 124 // IndexedAccess implements the interface ForeignKeyEditor. 125 func (editor MultiTableEditor) IndexedAccess(lookup sql.IndexLookup) sql.IndexedTable { 126 return editor.primary.(sql.ForeignKeyEditor).IndexedAccess(lookup) 127 } 128 129 func (editor MultiTableEditor) PreciseMatch() bool { 130 return true 131 } 132 133 // GetIndexes implements the interface ForeignKeyEditor. 134 func (editor MultiTableEditor) GetIndexes(ctx *sql.Context) ([]sql.Index, error) { 135 return editor.primary.(sql.ForeignKeyEditor).GetIndexes(ctx) 136 } 137 138 // SetAutoIncrementValue implements the interface AutoIncrementSetter. 139 func (editor MultiTableEditor) SetAutoIncrementValue(ctx *sql.Context, u uint64) error { 140 return editor.primary.(sql.AutoIncrementSetter).SetAutoIncrementValue(ctx, u) 141 } 142 143 // Close implements the interface sql.TableEditor. 144 func (editor MultiTableEditor) Close(ctx *sql.Context) error { 145 var err error 146 for _, secondary := range editor.secondaries { 147 if nErr := secondary.Close(ctx); err == nil { 148 err = nErr 149 } 150 } 151 if nErr := editor.primary.Close(ctx); err == nil { 152 err = nErr 153 } 154 return err 155 }