github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/mvdata/channel_row_source.go (about) 1 // Copyright 2020-2021 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 mvdata 16 17 import ( 18 "io" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 ) 22 23 // ChannelRowSource is a sql.Node that wraps a channel as a sql.RowIter. 24 type ChannelRowSource struct { 25 schema sql.Schema 26 rowChannel chan sql.Row 27 } 28 29 var _ sql.ExecSourceRel = (*ChannelRowSource)(nil) 30 31 // NewChannelRowSource returns a ChannelRowSource object. 32 func NewChannelRowSource(schema sql.Schema, rowChannel chan sql.Row) *ChannelRowSource { 33 return &ChannelRowSource{schema: schema, rowChannel: rowChannel} 34 } 35 36 var _ sql.Node = (*ChannelRowSource)(nil) 37 38 // Resolved implements the sql.Node interface. 39 func (c *ChannelRowSource) Resolved() bool { 40 return true 41 } 42 43 func (c *ChannelRowSource) IsReadOnly() bool { 44 return true 45 } 46 47 // String implements the sql.Node interface. 48 func (c *ChannelRowSource) String() string { 49 return "ChannelRowSource()" 50 } 51 52 // Schema implements the sql.Node interface. 53 func (c *ChannelRowSource) Schema() sql.Schema { 54 return c.schema 55 } 56 57 // Children implements the sql.Node interface. 58 func (c *ChannelRowSource) Children() []sql.Node { 59 return nil 60 } 61 62 // RowIter implements the sql.Node interface. 63 func (c *ChannelRowSource) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, error) { 64 return &channelRowIter{ 65 rowChannel: c.rowChannel, 66 }, nil 67 } 68 69 // WithChildren implements the sql.Node interface. 70 func (c *ChannelRowSource) WithChildren(children ...sql.Node) (sql.Node, error) { 71 if len(children) != 0 { 72 return nil, sql.ErrInvalidChildrenNumber.New(c, len(children), 0) 73 } 74 75 return c, nil 76 } 77 78 // CheckPrivileges implements the sql.Node interface. 79 func (c *ChannelRowSource) CheckPrivileges(ctx *sql.Context, opChecker sql.PrivilegedOperationChecker) bool { 80 return true 81 } 82 83 // channelRowIter wraps the channel under the sql.RowIter interface 84 type channelRowIter struct { 85 rowChannel chan sql.Row 86 } 87 88 var _ sql.RowIter = (*channelRowIter)(nil) 89 90 // Next implements the sql.RowIter interface. 91 func (c *channelRowIter) Next(ctx *sql.Context) (sql.Row, error) { 92 for r := range c.rowChannel { 93 select { 94 case <-ctx.Done(): 95 return nil, io.EOF 96 default: 97 return r, nil 98 } 99 } 100 return nil, io.EOF 101 } 102 103 // Close implements the sql.RowIter interface. 104 func (c *channelRowIter) Close(context *sql.Context) error { 105 return nil 106 }