You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: decoder.go
    path of file: ./repos/portmaster/netquery/orm
    
    the code of the file until where you have to start completion: package orm

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"reflect"
	"strings"
	"time"

	"zombiezen.com/go/sqlite"
)

// Commonly used error messages when working with orm.
var (
	errStructExpected        = errors.New("encode: can only encode structs to maps")
	errStructPointerExpected = errors.New("decode: result must be pointer to a struct type or map[string]interface{}")
	errUnexpectedColumnType  = errors.New("decode: unexpected column type")
)

// constants used when transforming data to and from sqlite.
var (
	// sqliteTimeFromat defines the string representation that is
	// expected by SQLite DATETIME functions.
	// Note that SQLite itself does not include support for a DATETIME
	// column type. Instead, dates and times are stored either as INTEGER,
	// TEXT or REAL.
	// This package provides support for time.Time being stored as TEXT (using a
	// preconfigured timezone; UTC by default) or as INTEGER (the user can choose between
	// unixepoch and unixnano-epoch where the nano variant is not officially supported by
	// SQLITE).
	SqliteTimeFormat = "2006-01-02 15:04:05"
)


    
func DatetimeDecoder(loc *time.Location) DecodeFunc {
	return func(colIdx int, colDef *ColumnDef, stmt Stmt, fieldDef reflect.StructField, outval reflect.Value) (interface{}, bool, error) {
		// if we have the column definition available we
		// use the target go type from there.
		outType := outval.Type()

		if colDef != nil {
			outType = colDef.GoType
		}

		// we only care about "time.Time" here
		if outType.String() != "time.Time" || (colDef != nil && !colDef.IsTime) {
			// log.Printf("not decoding %s %v", outType, colDef)
			return nil, false, nil
		}

		switch stmt.ColumnType(colIdx) { //nolint:exhaustive // Only selecting specific types.
		case sqlite.TypeInteger:
			// stored as unix-epoch, if unixnano is set in the struct field tag
			// we parse it with nano-second resolution
			// TODO(ppacher): actually split the tag value at "," and search
			// the slice for "unixnano"
			if strings.Contains(fieldDef.Tag.Get("sqlite"), ",unixnano") {
				return time.Unix(0, int64(stmt.ColumnInt(colIdx))), true, nil
			}

			return time.Unix(int64(stmt.ColumnInt(colIdx)), 0), true, nil

		case sqlite.TypeText:
			// stored ISO8601 but does not have any timezone information
			// assigned so we always treat it as loc here.
			t, err := time.ParseInLocation(SqliteTimeFormat, stmt.ColumnText(colIdx), loc)
			if err != nil {
				return nil, false, fmt.Errorf("failed to parse %q in %s: %w", stmt.ColumnText(colIdx), fieldDef.Name, err)
			}

			return t, true, nil

		case sqlite.TypeFloat:
			// stored as Julian day numbers
			return nil, false, fmt.Errorf("REAL storage type not support for time.Time")

		case sqlite.TypeNull:
			return nil, true, nil

		default:
			return nil, false, fmt.Errorf("unsupported storage type for time.Time: %s", stmt.ColumnType(colIdx))
		}
	}
}