MCPcopy Create free account
hub / github.com/Shopify/ghostferry / Fetch

Method Fetch

cursor.go:161–281  ·  view source on GitHub ↗
(db SqlPreparer)

Source from the content-addressed store, hash-verified

159}
160
161func (c *Cursor) Fetch(db SqlPreparer) (batch *RowBatch, paginationKeypos PaginationKey, err error) {
162 var selectBuilder squirrel.SelectBuilder
163 batchSize := c.CursorConfig.GetBatchSize(c.Table.Schema, c.Table.Name)
164
165 if c.BuildSelect != nil {
166 selectBuilder, err = c.BuildSelect(c.ColumnsToSelect, c.Table, c.lastSuccessfulPaginationKey, batchSize)
167 if err != nil {
168 c.logger.WithError(err).Error("failed to apply filter for select")
169 return
170 }
171 } else {
172 selectBuilder = DefaultBuildSelect(c.ColumnsToSelect, c.Table, c.lastSuccessfulPaginationKey, batchSize)
173 }
174
175 if c.RowLock {
176 mySqlVersion, err := c.DB.QueryMySQLVersion()
177 if err != nil {
178 return nil, NewUint64Key(0), err
179 }
180 if strings.HasPrefix(mySqlVersion, "8.") {
181 selectBuilder = selectBuilder.Suffix("FOR SHARE NOWAIT")
182 } else {
183 selectBuilder = selectBuilder.Suffix("LOCK IN SHARE MODE")
184 }
185 }
186
187 query, args, err := selectBuilder.ToSql()
188 if err != nil {
189 c.logger.WithError(err).Error("failed to build chunking sql")
190 return
191 }
192
193 // With the inline verifier, the columns to be selected may be very large as
194 // the query generated will be very large. The code here simply hides the
195 // columns from the logger to not spam the logs.
196
197 splitQuery := strings.Split(query, "FROM")
198 loggedQuery := fmt.Sprintf("SELECT [omitted] FROM %s", splitQuery[1])
199
200 logger := c.logger.WithFields(Fields{
201 "sql": loggedQuery,
202 "args": args,
203 })
204
205 // This query must be a prepared query. If it is not, querying will use
206 // MySQL's plain text interface, which will scan all values into []uint8
207 // if we give it []interface{}.
208 stmt, err := db.Prepare(query)
209 if err != nil {
210 logger.WithError(err).Error("failed to prepare query")
211 return
212 }
213
214 defer stmt.Close()
215
216 rows, err := stmt.Query(args...)
217 if err != nil {
218 logger.WithError(err).Error("failed to query database")

Callers 1

EachMethod · 0.95

Calls 15

DefaultBuildSelectFunction · 0.85
NewUint64KeyFunction · 0.85
ScanGenericRowFunction · 0.85
NewPaginationKeyFromRowFunction · 0.85
GetBatchSizeMethod · 0.80
QueryMySQLVersionMethod · 0.80
SizeMethod · 0.80
BuildSelectMethod · 0.65
ErrorMethod · 0.65
WithErrorMethod · 0.65
WithFieldsMethod · 0.65
PrepareMethod · 0.65

Tested by

no test coverage detected