github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/sqle/dtables/commits_table.go (about) 1 // Copyright 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 dtables 16 17 import ( 18 "fmt" 19 "io" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 "github.com/dolthub/go-mysql-server/sql/types" 23 24 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 25 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 26 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/index" 27 "github.com/dolthub/dolt/go/store/datas" 28 "github.com/dolthub/dolt/go/store/hash" 29 ) 30 31 const commitsDefaultRowCount = 10 32 33 // CommitsTable is a sql.Table that implements a system table which 34 // shows the combined commit log for all branches in the repo. 35 type CommitsTable struct { 36 dbName string 37 ddb *doltdb.DoltDB 38 } 39 40 var _ sql.Table = (*CommitsTable)(nil) 41 var _ sql.IndexAddressable = (*CommitsTable)(nil) 42 var _ sql.StatisticsTable = (*CommitsTable)(nil) 43 44 // NewCommitsTable creates a CommitsTable 45 func NewCommitsTable(_ *sql.Context, dbName string, ddb *doltdb.DoltDB) sql.Table { 46 return &CommitsTable{dbName: dbName, ddb: ddb} 47 } 48 49 func (dt *CommitsTable) DataLength(ctx *sql.Context) (uint64, error) { 50 numBytesPerRow := schema.SchemaAvgLength(dt.Schema()) 51 numRows, _, err := dt.RowCount(ctx) 52 if err != nil { 53 return 0, err 54 } 55 return numBytesPerRow * numRows, nil 56 } 57 58 func (dt *CommitsTable) RowCount(_ *sql.Context) (uint64, bool, error) { 59 return commitsDefaultRowCount, false, nil 60 } 61 62 // Name is a sql.Table interface function which returns the name of the table. 63 func (dt *CommitsTable) Name() string { 64 return doltdb.CommitsTableName 65 } 66 67 // String is a sql.Table interface function which returns the name of the table. 68 func (dt *CommitsTable) String() string { 69 return doltdb.CommitsTableName 70 } 71 72 // Schema is a sql.Table interface function that gets the sql.Schema of the commits system table. 73 func (dt *CommitsTable) Schema() sql.Schema { 74 return []*sql.Column{ 75 {Name: "commit_hash", Type: types.Text, Source: doltdb.CommitsTableName, PrimaryKey: true, DatabaseSource: dt.dbName}, 76 {Name: "committer", Type: types.Text, Source: doltdb.CommitsTableName, PrimaryKey: false, DatabaseSource: dt.dbName}, 77 {Name: "email", Type: types.Text, Source: doltdb.CommitsTableName, PrimaryKey: false, DatabaseSource: dt.dbName}, 78 {Name: "date", Type: types.Datetime, Source: doltdb.CommitsTableName, PrimaryKey: false, DatabaseSource: dt.dbName}, 79 {Name: "message", Type: types.Text, Source: doltdb.CommitsTableName, PrimaryKey: false, DatabaseSource: dt.dbName}, 80 } 81 } 82 83 // Collation implements the sql.Table interface. 84 func (dt *CommitsTable) Collation() sql.CollationID { 85 return sql.Collation_Default 86 } 87 88 // Partitions is a sql.Table interface function that returns a partition 89 // of the data. Currently the data is unpartitioned. 90 func (dt *CommitsTable) Partitions(*sql.Context) (sql.PartitionIter, error) { 91 return index.SinglePartitionIterFromNomsMap(nil), nil 92 } 93 94 // PartitionRows is a sql.Table interface function that gets a row iterator for a partition. 95 func (dt *CommitsTable) PartitionRows(ctx *sql.Context, p sql.Partition) (sql.RowIter, error) { 96 switch p := p.(type) { 97 case *doltdb.CommitPart: 98 return sql.RowsToRowIter(formatCommitTableRow(p.Hash(), p.Meta())), nil 99 default: 100 return NewCommitsRowItr(ctx, dt.ddb) 101 } 102 } 103 104 // GetIndexes implements sql.IndexAddressable 105 func (dt *CommitsTable) GetIndexes(ctx *sql.Context) ([]sql.Index, error) { 106 return index.DoltCommitIndexes(dt.dbName, dt.Name(), dt.ddb, true) 107 } 108 109 // IndexedAccess implements sql.IndexAddressable 110 func (dt *CommitsTable) IndexedAccess(lookup sql.IndexLookup) sql.IndexedTable { 111 nt := *dt 112 return &nt 113 } 114 115 func (dt *CommitsTable) PreciseMatch() bool { 116 return true 117 } 118 119 func (dt *CommitsTable) LookupPartitions(ctx *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) { 120 if lookup.Index.ID() == index.CommitHashIndexId { 121 hashStrs, ok := index.LookupToPointSelectStr(lookup) 122 if !ok { 123 return nil, fmt.Errorf("failed to parse commit lookup ranges: %s", sql.DebugString(lookup.Ranges)) 124 } 125 hashes, commits, metas := index.HashesToCommits(ctx, dt.ddb, hashStrs, nil, false) 126 if len(hashes) == 0 { 127 return sql.PartitionsToPartitionIter(), nil 128 } 129 130 return doltdb.NewCommitSlicePartitionIter(hashes, commits, metas), nil 131 } 132 133 return dt.Partitions(ctx) 134 } 135 136 // CommitsRowItr is a sql.RowItr which iterates over each commit as if it's a row in the table. 137 type CommitsRowItr struct { 138 itr doltdb.CommitItr 139 } 140 141 // NewCommitsRowItr creates a CommitsRowItr from the current environment. 142 func NewCommitsRowItr(ctx *sql.Context, ddb *doltdb.DoltDB) (CommitsRowItr, error) { 143 itr, err := doltdb.CommitItrForAllBranches(ctx, ddb) 144 if err != nil { 145 return CommitsRowItr{}, err 146 } 147 148 return CommitsRowItr{itr: itr}, nil 149 } 150 151 // Next retrieves the next row. It will return io.EOF if it's the last row. 152 // After retrieving the last row, Close will be automatically closed. 153 func (itr CommitsRowItr) Next(ctx *sql.Context) (sql.Row, error) { 154 h, optCmt, err := itr.itr.Next(ctx) 155 if err != nil { 156 return nil, err 157 } 158 cm, ok := optCmt.ToCommit() 159 if !ok { 160 return nil, io.EOF 161 } 162 163 meta, err := cm.GetCommitMeta(ctx) 164 if err != nil { 165 return nil, err 166 } 167 168 return formatCommitTableRow(h, meta), nil 169 } 170 171 // Close closes the iterator. 172 func (itr CommitsRowItr) Close(*sql.Context) error { 173 return nil 174 } 175 176 func formatCommitTableRow(h hash.Hash, meta *datas.CommitMeta) sql.Row { 177 return sql.NewRow(h.String(), meta.Name, meta.Email, meta.Time(), meta.Description) 178 }