- Notifications
You must be signed in to change notification settings - Fork3
scan sql rows into any type powered by generics
License
NotificationsYou must be signed in to change notification settings
wroge/scan
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Take a look atgithub.com/wroge/esquel.
This package offers a convenient and flexible way to scan SQL rows into any type, leveraging the power of generics.
- Efficient and Reusable: Avoid repetitive code and define the column-mapping in one place.
- Auto Closing: No need to worry about resource leaks.
- No Reflection: Faster than reflection based mappers.
- Robust Error Handling: Best practices for managing errors.
import"github.com/wroge/scan"typeAuthorstruct {IDint64Namestring}typePoststruct {IDint64TitlestringAuthors []Author}// Define mapping of database columns to struct fields.varcolumns= scan.Columns[Post]{// Map the 'id' column to the 'ID' field in the 'Post' struct.// Uses the 'scan.Any' function for direct assignment without additional processing."id":scan.Any(func(p*Post,idint64) {p.ID=id }),// Map the 'title' column to the 'Title' field in the 'Post' struct.// The 'scan.Null' function allows handling of nullable database columns.// If the 'title' column is null, 'default title' is used as the value."title":scan.Null("default title",func(p*Post,titlestring) {p.Title=title }),// Map the 'authors' column, expected to be in JSON format, to the 'Authors' field in the 'Post' struct.// The 'scan.JSON' function automatically handles unmarshalling of the JSON data into the 'Author' struct slice."authors":scan.JSON(func(p*Post,authors []Author) {p.Authors=authors }),// Or you could create a custom scanner with this function.// "column": scan.Func[Post, V](func(p *Post, value V) error {// return nil// }),}rows,err:=db.Query("SELECT ...")// handle error
posts,err:=scan.All(rows,columns)// handle error
post,err:=scan.First(rows,columns)iferr!=nil {iferrors.Is(err,scan.ErrNoRows) {// handle no rows}// handle other error}
post,err:=scan.One(rows,columns)iferr!=nil {iferrors.Is(err,scan.ErrTooManyRows) {// handle too many rows// post is valid}iferrors.Is(err,scan.ErrNoRows) {// handle no rows}// handle other error}
posts,err:=scan.Limit(10,rows,columns)iferr!=nil {iferrors.Is(err,scan.ErrTooManyRows) {// ignore if result set has more than 10 rows// len(posts) == 10}// handle other error}
iter,err:=scan.Iter(rows,columns)// handle errordeferiter.Close()foriter.Next() {varpostPosterr=iter.Scan(&post)// handle error// Or use the Value method:post,err:=iter.Value()// handle error}