func Tables(ctx context.Context, typ string) ([]*models.Table, error) {
	db, l, schema, err := get(ctx)
	if err != nil {
		return nil, err
	}
	return l.Tables(ctx, db, schema, typ)
}
Tables returns the database tables.
package loader
import (
	"context"
	"database/sql"
	"fmt"
	"regexp"
	"sort"
	"strings"
	"github.com/kenshaw/snaker"
	"github.com/xo/xo/models"
	xo "github.com/xo/xo/types"
)
var loaders = make(map[string]Loader)
func Register(typ string, loader Loader) {
	loaders[typ] = loader
}
func Flags() []xo.FlagSet {
	var types []string
	for typ := range loaders {
		types = append(types, typ)
	}
	sort.Strings(types)
	var flags []xo.FlagSet
	for _, typ := range types {
		l := loaders[typ]
		if l.Flags == nil {
			continue
		}
		for _, flag := range l.Flags() {
			flags = append(flags, xo.FlagSet{
				Type: typ,
				Name: string(flag.ContextKey),
				Flag: flag,
			})
		}
	}
	return flags
}
type Loader struct {
	Type             string
	Mask             string
	Flags            func() []xo.Flag
	Schema           func(context.Context, models.DB) (string, error)
	Enums            func(context.Context, models.DB, string) ([]*models.Enum, error)
	EnumValues       func(context.Context, models.DB, string, string) ([]*models.EnumValue, error)
	Procs            func(context.Context, models.DB, string) ([]*models.Proc, error)
	ProcParams       func(context.Context, models.DB, string, string) ([]*models.ProcParam, error)
	Tables           func(context.Context, models.DB, string, string) ([]*models.Table, error)
	TableColumns     func(context.Context, models.DB, string, string) ([]*models.Column, error)
	TableSequences   func(context.Context, models.DB, string, string) ([]*models.Sequence, error)
	TableForeignKeys func(context.Context, models.DB, string, string) ([]*models.ForeignKey, error)
	TableIndexes     func(context.Context, models.DB, string, string) ([]*models.Index, error)
	IndexColumns     func(context.Context, models.DB, string, string, string) ([]*models.IndexColumn, error)
	ViewCreate       func(context.Context, models.DB, string, string, []string) (sql.Result, error)
	ViewSchema       func(context.Context, models.DB, string) (string, error)
	ViewTruncate     func(context.Context, models.DB, string, string) (sql.Result, error)
	ViewDrop         func(context.Context, models.DB, string, string) (sql.Result, error)
	ViewStrip        func([]string, []string) ([]string, []string, []string, error)
}
func get(ctx context.Context) (*sql.DB, *Loader, string, error) {
	typ, _ := ctx.Value(xo.DriverKey).(string)
	l, ok := loaders[typ]
	if !ok {
		return nil, nil, "", fmt.Errorf("no database loader available for %q", typ)
	}
	db, _ := ctx.Value(xo.DbKey).(*sql.DB)
	schema, _ := ctx.Value(xo.SchemaKey).(string)
	return db, &l, schema, nil
}
func NthParam(ctx context.Context) (func(int) string, error) {
	_, l, _, err := get(ctx)
	if err != nil {
		return nil, err
	}
	mask := "?"
	if l.Mask != "" {
		mask = l.Mask
	}
	if !strings.Contains(mask, "%d") {
		return func(int) string {
			return mask
		}, nil
	}
	return func(i int) string {
		return fmt.Sprintf(mask, i+1)
	}, nil
}
func Schema(ctx context.Context) (string, error) {
	db, l, _, err := get(ctx)
	if err != nil {
		return "", err
	}
	return l.Schema(ctx, db)
}
func Enums(ctx context.Context) ([]*models.Enum, error) {
	db, l, schema, err := get(ctx)
	if err != nil {
		return nil, err
	}
	if l.Enums != nil {
		return l.Enums(ctx, db, schema)
	}
	return nil, nil
}
func EnumValues(ctx context.Context, enum string) ([]*models.EnumValue, error) {
	db, l, schema, err := get(ctx)
	if err != nil {
		return nil, err
	}
	return l.EnumValues(ctx, db, schema, enum)
}
func Procs(ctx context.Context) ([]*models.Proc, error) {
	db, l, schema, err := get(ctx)
	if err != nil {
		return nil, err
	}
	if l.Procs != nil {
		return l.Procs(ctx, db, schema)
	}
	return nil, nil
}
func ProcParams(ctx context.Context, id string) ([]*models.ProcParam, error) {
	db, l, schema, err := get(ctx)
	if err != nil {
		return nil, err
	}
	if l.ProcParams != nil {
		return l.ProcParams(ctx, db, schema, id)
	}
	return nil, nil
}