gobatis

package module
v1.3.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 24, 2025 License: BSD-4-Clause-UC Imports: 19 Imported by: 0

README

gobatis

The fantastic library for golang, aims to be the most powerful and stable ORM.

Overview

  • 支持 go1.18+
  • 使用 xml 定义 SQL
  • 丰富的 Postgres 类型支持
  • 支持原生 SQL 执行
  • 支持事务
  • 支持日志 Logger 接口
  • 支持所有SQL特性, 避免常规ORM对于复杂SQL的编写复杂度
  • 支持 Postgres 类型的 INSERT/UPDATE/DELETE xxx RETURNING xxx 语法
  • 支持 window 窗口函数
  • 使用 sql/database 接口
    • Postgres
    • MySQL
    • SQLite

Getting Started

++
 |- statements
    |-- user.xml
    |-- order.xml
 |- main.go
<mapper type="mysql">
    <!--  SQL segements  -->
    <sql id="userColumns">
        ${alias}.name, ${alias}.department
    </sql>

    <!--复杂的例子-->
    <select id="findMOrderComplexMore">
        select count(*) as cnt from
        <foreach collection="conditions" item="item" separator="," index="index">
            (select count(*) as cnt from app_events where
            <foreach collection="item.detail" item="detail" separator="and" index="index1">
                <trim prefixOverrides="and">
                  <if test="detail.id != null">
                  and (id = #{detail.id} and id > #{index})
                </if>
                <if test="detail.price != null">
                  and (price = #{detail.price})
                </if>
                <if test="detail.order_id != null or index1 > 0">
                  and (order_id = #{detail.order_id})
                </if>
              </trim>
            </foreach>
            ) as ${item.alias+string(index)}
        </foreach>
        <where>
            (a0.cnt > 0 or b1.cnt > 0)
        </where>
        ${page}
    </select>
    
   <!-- 查询用户信息 -->
    <select id="findUser" type="mysql">
        select * from employees
        <where>
            <trim prefix="" prefixOverrides="AND | OR">
                <if test="employee_id != null">
                    AND employee_id in (#{employee_id})
                </if>
                <if test="department != null">
                    AND department = #{department}
                </if>
            </trim>
        </where>
        order by id asc limit 5
    </select>
    
    <!-- 添加用户 -->
    <insert id="addUser">
        insert into employees 
        (<include refid="userColumns" alias="alias" value="employees" />)
        values
        <foreach item="item" collection="list" separator=",">
        (#{item.name}, #{item.department})
        </foreach>
    </insert>
    
    <!-- 删除用户 -->
    <delete id="deleteUser">
        delete from employees where id = #{id}
    </delete>
    
    <!-- 修改用户 -->
    <update id="updateUser">
        update employees set name = #{name}, department = #{department} where id = #{id}
    </update>
</mapper>
针对于不同的数据库,需要引入不同的数据库驱动:
import (
    // used for mysql
	_ "github.com/go-sql-driver/mysql"

    // used for postgres
	_ "github.com/jackc/pgx/v5/stdlib"
	
	// used for posgres
	_ "github.com/lib/pq"
)
    type Employees struct {
        EmployeeId       int    `json:"employee_id"`
        Name             string `json:"name"`
        Department       int    `json:"department"`
        PerformanceScore string `json:"performance_score"`
        Salary           string `json:"salary"`
    }

   //go:embed statements/*.xml
    var embedFs embed.Fs

    db, err := OpenWithEmbedFs(driverName, dsn, embedFs, `statements`)
    if err != nil {
    	panic(err)
    }
    var ctx = context.TODO()

    var out []Employees
    if err = db.WithContext(ctx).Mapper(`findUser`).Args(&gobatis.Args{
        `employee_id`: []int{38, 39, 40},
        `department`:  2,
    }).Find(&out).Error; err != nil {
        panic(err)
    } else {
        fmt.Printf("%#v\n", out)
    }
查询数据用 Find 方法
  • select * from xxx 直接查询
  • insert into xxx returning xxx 插入后返回插入数据
  • update xxx set xxx where xxx returning xxx 更新后返回更新数据
  • delete from xxx where xxx returning xxx 删除后返回删除数据
var out []any
if err := db.WithContext(ctx).
	Mapper(`findEmployeesByIds`).
	Args(&Gobatis{`ids`:[]int{1,3,5}}).Find(&out).Error; err != nil {
	panic(err)
}
fmt.Printf("%#v\n", out)
增删改数据但是不返回查询 用 Execute 方法
  • insert into xxx values (xxx)
  • update xxx set xxx where xxx
  • delete from xxx where xxx
if err := db.WithContext(ctx).
	Mapper(`updateEmployeesById`).
	Args(&Gobatis{`id`:1, `name`:`test`}).Execute().Error; err != nil {
	panic(err)
}
原生SQL的增删改查
// 查询操作
var three MOrder
err := tx.RawQuery(`select * from m_order where id = ?`, 3).Find(&three).Error
if err != nil {
	return err
}

// 增删改操作
err := tx.RawExec(`delete from m_order where id = ?`, 3).Execute().Error
if err != nil {
	return err
}	
事务用法
err := db.WithContext(ctx).Transaction(func(tx *gobatis.DB) error {
	// insert
	ndb := tx.Mapper(`insertMOrderByValue`).Args(&gobatis.Args{
		`name`:       `test-value`,
		`price`:      1000,
		`created_at`: time.Now().Add(time.Hour * 24 * -1),
		`updated_at`: time.Now().Add(time.Hour * 6),
	}).Execute()
	if ndb.Error != nil {
		return ndb.Error
	}

	id := ndb.LastInserId

	// find
	var two MOrder
	if err = tx.Mapper(`findMOrderById`).Args(&gobatis.Args{`id`: id}).Find(&two).Error; err != nil {
		return err
	}
	
	return nil
})
if err != nil {
	panic(err)
}

结构体映射

create table example (
    id int primary key auto_increment,
    name varchar(255),
    age int
    address varchar(255)
);
type Example struct {
	Id     int    `json:"id"`
	Name   string `json:"name"`
	Age    int    `json:"age"`
	Address string `json:"address"`
}

正如上面看到的那样, 我们可以使用 json tag 来让结构体与数据库字段进行映射, 对应的我们也支持更多 tag:

按照顺序解析 json, sql, db, expr, leopard, gorm tag,遇到了就作为名称映射,否则使用结构体字段名. 建议大家使用 json tag 即可, 不用增加复杂度。

[注意]:

gobatis 支持内嵌结构体映射。

type BoxCommon struct {
	Id int `sql:"id"`
}

type BoxData struct {
	BoxCommon
}

type MOrder struct {
	BoxData
	Name      string     `json:"name"`
	Price     float64    `json:"price"`
	CreatedAt time.Time  `json:"created_at"`
	UpdatedAt time.Time  `json:"updated_at"`
	DeletedAt *time.Time `json:"deleted_at"`
}

MOrder 的内嵌 BoxData 结构体 和 BoxCommon结构体。

Postgres 复杂类型支持

目前 gobatis 支持 Postgres 的多种复杂类型包括:

Postgres类型 gobatis类型 解析与回写
int[], integer[], int2[], int4[], int8[] gobatis.PgArrayInt
text[], varchar[], char[] gobatis.PgArrayString
bool[] gobatis.PgArrayBool
float[], float4[], float8[] gobatis.PgArrayFloat
record[] gobatis.PgArrayRecord
line[] gobatis.PgArrayLine
point[] gobatis.PgArrayPoint
polygon[] gobatis.PgArrayPolygon
circle[] gobatis.PgArrayCircle
box[] gobatis.PgArrayBox
path[] gobatis.PgArrayPath
lseg[] gobatis.PgArrayLSeg
int4range[], int8range[], numrange[], tsrange[], tstzrange[], daterange[] gobatis.PgArrayRange
create type as (xxx) 自定义类型 gobatis.PgRecord
create type as (xxx) 自定义类型数组 gobatis.PgArrayRecord
int4range, int8range, numrange, tsrange, tstzrange, daterange gobatis.PgRange
point gobatis.PgPoint
line gobatis.PgLine
polygon gobatis.PgPolygon
lseg gobatis.PgLSeg
box gobatis.PgBox
path gobatis.PgPath
circle gobatis.PgCircle
PostGIS - ×

[ PostGIS ] 对于 PostGIS 中的以下类型的支持后续视情况迭代跟进

  • POINT 二维 或者 三维 点类型
  • LINESTRING 线类型
  • POLYGON 多边形类型
  • MULTIPOINT 多点类型
  • MULTILINESTRING 多线类型
  • MULTIPOLYGON 多多边形类型
  • GEOMETRYCOLLECTION 几何集合类型
  • CIRCULARSTRING 圆弧字符串类型
  • COMPOUNDCURVE 复合曲线类型
  • CURVEPOLYGON 曲线多边形类型

示例如下:

create table example (
    id serial,
    name text,
    cards int[]
);

// Example
type Example struct {
  Id int `json:"id"`
  Name string `json:"name"`
  Cards gobatis.PgArrayInt `json:"cards"`
}

// Query
var out []*Example
err := db.WithContext(ctx).Mapper(`xxx`).Args(&gobatis.Args{`id`: 1}).Find(&out).Error

// Insert & Update & Delete
err := db.WithContext(ctx).Mapper(`xxx`).Args(&gobatis.Args{`id`: 1, `name`: `hello`, `cards`: &gobatis.PgArrayInt{1, 2, 3}}).Execute().Error

如果是自定义类型,则需要使用 gobatis.PgRecord 或者 gobatis.PgArrayRecord 作为结构体的值变量,实现 sql.Scanner & driver.Valuer 接口即可:

  • gobatis.PgArrayRecord: 自定义的类型的数组
  • gobatis.PgRecord: 自定义类型

create type card as (
    card_num text,
    card_name text,
    card_isn varchar(32)
);

create table exmaple (
    id serial,
    name text,
    cards card[]
);

type Card struct {
    CardNum string `json:"card_num"`
    CardName string `json:"card_name"`
    CardIsn string `json:"card_isn"`
}

type Cards struct {
    value gobatis.PgArrayRecord
    Details []*Card
}

func (c *Cards) Scan(value interface{}) error {
    err := c.value.Scan(value)
    if err != nil {
        return err
    }
    for _, cardItem := range c.value {
        if len(cardItem) != 3 {
            return errors.New("card detail is invalid")
        }
        c.Details = append(c.Details, &Card{
            CardNum: cardItem[0],
            CardName: cardItem[1],
            CardIsn: cardItem[2],
        })
    }
    return nil
}

func (c *Cards) Value() (driver.Value, error) {
	c.value = nil
	for _, card := range c.Details {
		c.value = append(c.value, []string{card.CardNum, card.CardName, card.CardIsn})
	}
	return c.value.Value()
}

type Example struct {
  Id int `json:"id"`
  Name string `json:"name"`
  Cards Cards  `json:"cards"`
}

// Query
var out []Example
if err = db.WithContext(ctx).Mapper(`findCardById`).Args(&gobatis.Args{`id`: 2}).Find(&out).Error; err != nil {
    panic(err)
}
t.Log(out)

// Insert & Update & delete
err = db.WithContext(ctx).Mapper(`insertCard`).
		Args(&gobatis.Args{
			`name`: `card example 2`,
			`cards`: &Cards{
				Details: []*Card{
					{
						CardNum:  `CardNum1`,
						CardName: `CardName1`,
						CardIsn:  `CardIsn1`,
					},
					{
						CardNum:  `CardNum2`,
						CardName: `CardName2`,
						CardIsn:  `CardIsn2`,
					},
				},
			},
		}).Execute().Error

动态SQL

gobatis 采用 xml 模板实现动态编程得到 SQL

[ 注意 ]: 由于 xml 规范的原因,以下字符需要转义:

& 需要转义为 &amp;

< 需要转义为 &lt;

> 需要转义为 &gt;

' 需要转义为 &apos;

" 需要转义为 &quot;

或者你可以使用 CDATA 标签包裹:

<![CDATA[ 内容 ]]>

[ 说明 ]: 标签内容里面替换规则:

${xxx} 会被替换为对应的值

#{xxx} 会被替换为预处理变量。

  • mapper 标签
<mapper type="postgres|mysql"></mapper> 

一个 mapper 标签代表一张表,里面包含整个表的增删改查语句,mapper 标签包含 type 属性 该属性的值为数据库类型,目前支持 mysqlpostgressqlite 数据库类型。 设置了 mapper 标签的 type 属性后,子元素会自动继承该属性,如果子元素单独设置 type 那么以子元素设置的为准.

mapper 可以包含以下标签: sql, include, select, insert, update, delete. 标签可以多级嵌套, 但是其他之外的标签会被忽略.

  • sql 标签
<sql id="xxx">name,user,address</sql>

sql 标签用于定义公用部分内容,如数据表的字段信息、公用窗口函数语句等。标签必须定义 id 属性,此属性供 include标签的 refid 属性引用。 include引用之前必须先在 mapper 子级定义 sql 节点。

不能将 sql 节点定义为其他标签的内嵌标签(特例:执行单元 insert, select, delete, update 标签内部只需要在 include 标签前定义即可, 既是是内嵌标签也没有问题).

正确的示例:

<mapper>
    <sql id="modelColumnsNest">*</sql>  <!-- 正确的位置1 -->
    <insert id="insertMOrderMultiAndReturning">
        <sql id="modelColumnsNest">*</sql>  <!-- 正确的位置2 -->
        insert into m_order (order_id, price, strategy, created_at, updated_at) values
        <foreach item="item" collection="list" separator=",">
          <sql id="modelColumnsNest">*</sql>  <!-- 正确的位置3 -->
            (#{item.OrderId}, #{item.Price}, #{item.Strategy}, #{item.CreatedAt}, #{item.UpdatedAt})
        </foreach>
        returning <include refid="modelColumnsNest"/>  <!-- 此处引用 -->
    </insert>
    <sql id="modelColumnsNest">*</sql>  <!-- 正确的位置4 -->
</mapper>

错误的示例:

<mapper>
    <insert id="insertMOrderMultiAndReturning">
        <sql id="modelColumnsNest">*</sql>  <!-- 错误的位置1 -->
        insert into m_order (order_id, price, strategy, created_at, updated_at) values
        <foreach item="item" collection="list" separator=",">
          <sql id="modelColumnsNest">*</sql>  <!-- 错误的位置2 -->
            (#{item.OrderId}, #{item.Price}, #{item.Strategy}, #{item.CreatedAt}, #{item.UpdatedAt})
        </foreach>
        <sql id="modelColumnsNest">*</sql>  <!-- 错误的位置3 -->
    </insert>

    <select id="findMOrderById">
        <!-- 此处引用 -->
        select <include refid="modelColumnsNest"/> from m_order where id in (#{map(ids, .Id)})
    </select>
</mapper>

[ 注意 ]:

mapper 标签下级的 sql 节点, 所有其他地方都可以 include 引用, 但是各执行单元(update, insert, select, delete) 内的 sql 节点, 只能各单元内使用, 只需要遵守 先定义后使用 的原则即可.

  • include 标签
<include refid="xxx" alias="xxx" value=""/>

include 节点用于引用之前定义的 sql 节点。

include 节点必须定义 refid 属性 此属性引用之前定义的 sql 节点。 支持 alias 属性与 value 属性,alias 属性用于指定字段别名,value 属性用于指定字段值。

如下示例:

<sql id="userColumns">${t}.name, ${t}.department</sql>

<include refid="userColumns" alias="t" value="employees"/>

此时 include 标签会被替换为

employees.name, employees.department

也就是 ${t} 被替换为 employees

  • if 标签
<if test="id != null">
    id = #{id}
</if>

if 节点用于判断条件,如果test条件满足,那么 if标签的文本内容会参与组装,否则忽略。

  • elif 标签
<elif test="id != null and id > 10">
    id = #{id}
</elif>

注意定义 elif 节点前,必须有 if 节点。 不能单独定义 elif 标签

elif 标签与最近的一个 if 节点搭配

elif 节点用于判断条件,如果test条件满足,那么 elif标签的文本内容会参与组装,否则忽略。

  • else 标签
<else>
    department = #{department}
</else>

else标签定义之前必须定义一个 if 节点或者 elif 节点。

else 标签与最近的一个 if 或者 elif 搭配

else 节点存在的作用就是当前 if 或者前置的 elif 条件都不满足时,执行 else 节点的文本内容,

  • choose, when, otherwise 标签
<choose>
    <when test="id != null">
        id = #{id}
    </when>
    <when test="department != null">
        department = #{department}
    </when>
    <otherwise>
        id = 100
    </otherwise>
</choose>

[说明]: 当没有 choose 节点时候, when 节点的运行与 if 作用一致.

choose 节点下的 多个 when & otherwise 类似与程序的 switch 语句。

otherwise 与最近的一个 when 搭配。

  • where 标签
<where>
    id = #{id}
    <if test="department != null">and department = #{department}</if>
</where>

where 标签用于组装 where 语句。当子句有 and | or 开头的时候 where 会自动去掉 and | or, 并且加上 where 前缀

  • foreach 标签
<foreach collection="list" item="item" separator="union" index="index">
    select * from employees where id = #{item.id}
</foreach>

collection: 定义的时候传入变量的变量名称

item: 表示循环 collection 值的时候单个值的变量名

separator: 表示 foreach 子句的内容之间用什么分隔.

index: 表示数组的元素的索引,从 0 开始, 可选属性

  • trim 标签
<trim prefix="" prefixOverrides="AND | OR">
    other statements
</trim>

trim标签用来去掉子句中多余的定义在 prefixOverrides 属性的内容

多个内容用 | 分隔

最后在内容前拼接 prefix 属性定义的内容。

expression

  • 支持运算符:

+, -, *, /, % (取模), ^ 或者 ** (次方)

  • 比较运算符:

==, !=, <, >, <=, >=

  • 逻辑运算符:

not or !, and, or or ||

  • 条件运算符:

?: (三元运算符), ?? (nil合并), if else

  • 成员运算符:

[], ., ?., in

  • 字符串运算符:

+ (连接字符串), contains, startsWith, endsWith

  • 范围运算符:

.. (范围运算符)

  • 切片运算符:

[:] (切片运算符)

  • 管道运算符:

|

expr 函数篇
  • 字符串函数

    • trim(str[, chars])
    • trimPrefix(str, prefix)
    • trimSuffix(str, suffix)
    • upper(str)
    • lower(str)
    • split(str, delimiter[, n])
    • splitAfter(str, delimiter[, n])
    • replace(str, old, new)
    • repeat(str, n)
    • indexOf(str, substring)
    • lastIndexOf(str, substring)
    • hasPrefix(str, prefix)
    • hasSuffix(str, suffix)
  • 日期函数

    • now()
    • duration(str) 有效时间单位 "ns", "us" (or "µs"), "ms", "s", "m", "h".
    • date(str[, format[, timezone]])
    • timezone(str)
  • 数字函数

    • max(n1, n2)
    • min(n1, n2)
    • abs(n)
    • ceil(n)
    • floor(n)
    • round(n)
  • 数组函数

    • all(array, predicate)
    • any(array, predicate)
    • one(array, predicate)
    • none(array, predicate)
    • map(array, predicate)
    • filter(array, predicate)
    • find(array, predicate)
    • findIndex(array, predicate)
    • findLast(array, predicate)
    • findLastIndex(array, predicate)
    • groupBy(array, predicate)
    • count(array[, predicate])
    • concat(array1, array2[, ...])
    • flatten(array)
    • uniq(array)
    • join(array[, delimiter])
    • reduce(array, predicate[, initialValue])
    • sum(array[, predicate])
    • mean(array)
    • median(array)
    • first(array)
    • last(array)
    • take(array, n)
    • reverse(array)
    • sort(array[, order])
    • sortBy(array[, predicate, order])
  • 字典Map函数

    • keys(map)
    • values(map)
  • 类型检查转换函数

    • type(v) nil bool int uint float string array map.
    • int(v)
    • float(v)
    • string(v)
    • toJSON(v)
    • fromJSON(v)
    • toBase64(v)
    • fromBase64(v)
    • toPairs(map)
    • fromPairs(array)
  • 其他函数

    • len(v) 获取数组、map、字符串的长度
    • get(v, index)
  • 位运算函数

    • bitand(int, int)
    • bitor(int, int)
    • bitxor(int, int)
    • bitnand(int, int)
    • bitnot(int)
    • bitshl(int, int)
    • bitshr(int, int)
    • bitushr(int, int)
  • 具体的明细内容参考 expr-lang/expr Language Definition

Documentation

Index

Constants

View Source
const (
	LogLevelDebug = iota
	LogLevelInfo
	LogLevelError
)
View Source
const (
	TestKey            = `test`
	PrefixOverridesKey = `prefixOverrides`
	PrefixKey          = `prefix`
	CollectionKey      = `collection`
	ItemKey            = `item`
	SeparatorKey       = `separator`
	IdKey              = `id`
	TypeKey            = `type`
	IndexKey           = `index`
)
View Source
const (
	// TsTzDateTimeFormat postgres timestamp with time zone format
	TsTzDateTimeFormat = `2006-01-02 15:04:05-07`

	// TsDateTimeFormat postgres timestamp format
	TsDateTimeFormat = `2006-01-02 15:04:05`
)

Variables

View Source
var (
	ErrorNotFound                  = errors.New(`gobatis: record not found`)
	ErrorInvalidScanRowType        = errors.New(`scanRow: non-pointer of dest`)
	ErrorInvalidScanSliceType      = errors.New(`scanSlice: non-pointer of dest`)
	ErrorNowRowsFound              = errors.New(`no rows found`)
	ErrorMapperCallFirst           = errors.New(`gobatis: Mapper() must be invoked, before Bind`)
	ErrorExecuteFailedWithType     = errors.New(`gobatis: Execute: invalid type`)
	ErrorDestCantBeNil             = errors.New("gobatis: dest can't be nil")
	ErrorBindArgsNeedBeMapOrStruct = errors.New(`gobatis: Args need be map or struct`)
	ErrorPreparedStatementsEmpty   = errors.New(`gobatis: prepared statements empty`)
)
View Source
var (
	ErrorElementNotSupported             = errors.New(`element not supported`)
	ErrorXmlNotValid                     = errors.New(`xml not valid`)
	ErrorElifMustFollowIfStmt            = errors.New(`elif must follow if statement`)
	ErrorElseMustFollowIfStmt            = errors.New(`else must follow if statement`)
	ErrorOtherwiseMustFollowChooseStmt   = errors.New(`otherwise must follow when statement`)
	ErrorForeachNeedCollection           = errors.New(`foreach statment need collection attr`)
	ErrorForeachNeedItem                 = errors.New(`foreach statment need item attr`)
	ErrorInputMustBeMap                  = errors.New(`input must be map`)
	ErrorForeachStatementIsNotArrayOrMap = errors.New(`foreach statement is not array or map`)
	ErrorIncludeTagNeedRefIdAttr         = errors.New(`include tag need refid attr`)
)
View Source
var (
	ArrayStringReplacer        = strings.NewReplacer(`\"`, `"`, `\\`, `\`)
	ArrayStringReverseReplacer = strings.NewReplacer(`"`, `\"`)
)
View Source
var (
	// SplitPgArrayType split string used by bufio.Scanner Split func
	SplitPgArrayType = SplitByString("{,}")

	// SplitPgArrayStringType split string used by bufio.Scanner Split func
	SplitPgArrayStringType = SplitByString("{,\"}")

	// SplitPgRangeType split string used by bufio.Scanner Split func
	SplitPgRangeType = SplitByString("[,]()")

	// SplitPgRecordType split string used by bufio.Scanner Split func
	SplitPgRecordType = SplitByString(`(,")`)

	// SplitPgArrayRecordType split string used by bufio.Scanner Split func
	SplitPgArrayRecordType = SplitByString("{}(,\")")

	// SplitPgPointType split string used by bufio.Scanner Split func
	SplitPgPointType = SplitByString(`(,)`)

	// SplitPgArrayLineType split string used by bufio.Scanner Split func
	SplitPgArrayLineType = SplitByString(`{",}`)

	// SplitPgArrayLsegType split string used by bufio.Scanner Split func
	SplitPgArrayLsegType = SplitByString(`{[(,)]}`)

	// SplitPgArrayBoxType split string used by bufio.Scanner Split func
	SplitPgArrayBoxType = SplitByString(`{(),;}`)

	// SplitPgArrayPathType split string used by bufio.Scanner Split func
	SplitPgArrayPathType = SplitByString(`{"(),}`)

	// SplitPgCircleType split string used by bufio.Scanner Split func
	SplitPgCircleType = SplitByString(`<(,)>`)

	// SplitPgArrayCircleType split string used by bufio.Scanner Split func
	SplitPgArrayCircleType = SplitByString(`{"<(,)>}`)

	// SplitPgArrayRangeType split string used by bufio.Scanner Split func
	SplitPgArrayRangeType = SplitByString(`{"[(,)]}`)

	// SplitMoreCharsPrefix every prefix in the SplitMoreCharsPrefix will be split togother.
	SplitMoreCharsPrefix = []string{`\"`}
)
View Source
var (
	PgNewRecordReplacer           = strings.NewReplacer(`\\`, `\`)
	PgNewArrayRecordReplacer      = strings.NewReplacer(`\\\\`, `\`, `\\\\\\\\`, `\`)
	PgNewRecordInnerReplacer      = strings.NewReplacer(`""`, `"`, `\\\\`, `\`, `\\`, ``)
	PgNewArrayRecordInnerReplacer = strings.NewReplacer(`\\\\\"\"`, `"`, `\\\\`, `\`, `\\`, ``)
	DoubleQuoteReplacer           = strings.NewReplacer(`""`, `"`)
	SlashDoubleQuoteReplacer      = strings.NewReplacer(`\"\"`, `"`, `\\`, `\`)

	RecordReverseReplacer      = strings.NewReplacer(`"`, `""`, `\`, `\\`)
	ArrayRecordReverseReplacer = strings.NewReplacer(`"`, `\\\\\"\"`, `\`, `\\\\`)
)

ROW(2, '"\test', array['"\12345678901', '12345678902\\"']) (2,"""\\test","{""\\""\\\\12345678901"",""12345678902\\\\\\\\\\""""}", "[aaaa,bbb)")

Functions

func AsBool

func AsBool(v string) (bool, error)

AsBool convert string to bool

func AsByte

func AsByte(v string) (byte, error)

AsByte convert string to byte

func AsFloat

func AsFloat(v string) (float64, error)

AsFloat convert string to float64

func AsInt

func AsInt(v string) (int64, error)

AsInt type convert tools function contains: int64, byte, rune, float64, bool, string time.Time simple example:

Parse string into int64 v, _ := AsInt("10")

func AsLocation

func AsLocation(v string) (*time.Location, error)

AsLocation convert string to *time.Location

func AsMilliseconds

func AsMilliseconds(duration int64) float64

AsMilliseconds convert duration to milliseconds

func AsRune

func AsRune(v string) (rune, error)

AsRune convert string to rune

func AsSeconds

func AsSeconds(duration int64) float64

AsSeconds convert duration to seconds

func AsString

func AsString(v interface{}) (string, error)

deprecated AsString convert interface{} to string Not recommend to use AsString.

func NewUuid

func NewUuid() string

NewUuid generate uuid for variables

func Ptr

func Ptr[T any](v T) *T

Ptr return pointer of v

func PtrToAny

func PtrToAny[T any](v *T) any

PtrToAny return the value of pointer

func PtrToValue

func PtrToValue[T any](v *T) T

PtrToValue return the value of pointer

func SplitByString

func SplitByString(chars string) func(data []byte, atEOF bool) (advance int, token []byte, err error)

SplitByString split string used by bufio.Scanner Split func any char in chars will be split and return

func SplitByStringWithPrefix

func SplitByStringWithPrefix(chars string, prefixs []string) func(data []byte, atEOF bool) (advance int, token []byte, err error)

SplitByStringWithPrefix split string used by bufio.Scanner Split func any char in chars will be split and return

func SplitForXmlAttr

func SplitForXmlAttr(data []byte, atEOF bool) (advance int, token []byte, err error)

func WithLogger

func WithLogger(logger Logger) func(*DB)

WithLogger set logger

func WithMapper

func WithMapper(mapper *Mapper) func(*DB)

WithMapper set mapper from outspace

Types

type Args

type Args = map[string]interface{}

Args bind variables

func AsMap

func AsMap(v any) Args

AsMap convert struct to map, remain field name, if not define the following tag: `json`, `sql`, `db`, `expr`, `leopard`, `gorm` only support input param was struct & map, others panic

type BatisInput

type BatisInput = map[string]interface{}

BatisInput Args bind variables

type BindHandler

type BindHandler interface {
	Bind(ctx context.Context, input *HandlerPayload) *BindVar
}

type BindVar

type BindVar struct {
	// contains filtered or unexported fields
}

func (*BindVar) Vars

func (bv *BindVar) Vars() (string, []interface{}, error)

type Choose

type Choose struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewChoose

func NewChoose() *Choose

func (*Choose) UnmarshalXML

func (m *Choose) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type DB

type DB struct {

	// error information.
	LastInserId  int64
	RowsAffected int64
	Error        error
	// contains filtered or unexported fields
}

func Open

func Open(driverName, dataSourceName string, opts ...func(*DB)) (*DB, error)

Open database

func OpenWithEmbedFs

func OpenWithEmbedFs(
	driverName, dataSourceName string,
	fs embed.FS,
	directory string,
	opts ...func(*DB),
) (*DB, error)

OpenWithEmbedFs open database with embed.FS

func (*DB) Args

func (b *DB) Args(variables interface{}) *DB

Args alias to Bind operation

func (*DB) Bind

func (b *DB) Bind(variables interface{}) *DB

Bind variables to mapper generate stmt prepared handler next call will use the stmt. caller should have known if the variables input was map, he must make sure the input variables [ thread-safe ].

func (*DB) Clone

func (b *DB) Clone() *DB

func (*DB) DeleteMapper

func (b *DB) DeleteMapper(mapperId string) *DB

DeleteMapper Find mapper from delete mapper list, if not found, return error

func (*DB) Execute

func (b *DB) Execute() *DB

Execute database's insert, update and delete if database running statements with returning, use method Find instead.

func (*DB) Find

func (b *DB) Find(dest any) *DB

Find result from previous Query call

func (*DB) InsertMapper

func (b *DB) InsertMapper(mapperId string) *DB

InsertMapper Find mapper from insert mapper list, if not found, return error

func (*DB) Mapper

func (b *DB) Mapper(mapperId string) *DB

Mapper fetch mapper from all xml with the id identifier

forexample:

fetch data: db.Mapper('id').Args(variables).Find(dest).Error

otherwise: db.Mapper('id').Args(variables).Execute().Error

normal state, you can call Mapper(`xxx`) to fetch the mapper

but in some conditions, this is slower, because the find order follow the order of `select`, `insert`, `update`, `delete`

the update & delete mapper list is the last one to fetch, so if your mapper type you known, you can call

SelectMapper(`xxx`), InsertMapper(`xxx`), UpdateMapper(`xxx`), DeleteMapper(`xxx`) directly

to speed up or accelerate the operation.

func (*DB) RawExec

func (b *DB) RawExec(query string, args ...any) *DB

RawExec do an insert, update or delete operation

func (*DB) RawQuery

func (b *DB) RawQuery(query string, args ...any) *DB

RawQuery database then call Find to get result

func (*DB) SelectMapper

func (b *DB) SelectMapper(mapperId string) *DB

SelectMapper Find mapper from select mapper list, if not found, return error

func (*DB) Transaction

func (b *DB) Transaction(fn func(tx *DB) error) (err error)

Transaction start transaction to database when transaction completed successfully, the tx will be committed and can't use again

func (*DB) UpdateMapper

func (b *DB) UpdateMapper(mapperId string) *DB

UpdateMapper Find mapper from update mapper list, if not found, return error

func (*DB) WithContext

func (b *DB) WithContext(ctx context.Context) *DB

WithContext set context to db

type DateTime

type DateTime time.Time

DateTime type convert tools function contains: int64, byte, rune, float64, bool, string time.Time simple example:

Parse string into Time

  1. tq, _ := AsDateTime("2021-01-01", TimeFormat(`Y-m-d`).AsTimeFormat().String()) println(tq.Format(TimeFormatYmdInCN))

or you can use AsTime() function

dt, _ := TimeFormat(`Y-m-d`).AsTimeFormat().AsTime("2021-01-01")
println(dt.Format(TimeFormatYmdInCN)

also, you can simplely use like this:

dt, _ := TimeFormatYmd.AsTime("2021-01-01")
println(dt.Format(TimeFormatYmdInCN)

func AsDateTime

func AsDateTime(v string, format string) (DateTime, error)

AsDateTime type convert tools function contains: int64, byte, rune, float64, bool, string time.Time simple example:

Parse string into Time

  1. tq, _ := AsDateTime("2021-01-01", TimeFormat(`Y-m-d`).AsTimeFormat().String()) println(tq.Format(TimeFormatYmdInCN))

or you can use AsTime() function

dt, _ := TimeFormat(`Y-m-d`).AsTimeFormat().AsTime("2021-01-01")
println(dt.Format(TimeFormatYmdInCN)

also, you can simplely use like this:

dt, _ := TimeFormatYmd.AsTime("2021-01-01")
println(dt.Format(TimeFormatYmdInCN)

AsDateTime convert string to DateTime

func NewDateTimeFromNow

func NewDateTimeFromNow() DateTime

NewDateTimeFromNow create DateTime from now

func NewDateTimeFromTime

func NewDateTimeFromTime(t time.Time) DateTime

NewDateTimeFromTime create DateTime from time.Time

func (DateTime) AddDay

func (dt DateTime) AddDay(d int) DateTime

AddDay add day

func (DateTime) AddDuration

func (dt DateTime) AddDuration(duration time.Duration) DateTime

AddDuration add duration

func (DateTime) AddDurationInText

func (dt DateTime) AddDurationInText(duration string) (DateTime, error)

AddDurationInText add duration in text

func (DateTime) AddHour

func (dt DateTime) AddHour(h int) DateTime

AddHour add hour

func (DateTime) AddMinute

func (dt DateTime) AddMinute(m int) DateTime

AddMinute add minute

func (DateTime) AddMonth

func (dt DateTime) AddMonth(m int) DateTime

AddMonth add month

func (DateTime) AddSecond

func (dt DateTime) AddSecond(s int) DateTime

AddSecond add second

func (DateTime) AddWeek

func (dt DateTime) AddWeek(week int) DateTime

AddWeek add week

func (DateTime) AddYear

func (dt DateTime) AddYear(y int) DateTime

AddYear add year

func (DateTime) After

func (dt DateTime) After(t DateTime) bool

After return true if the DateTime is after another DateTime

func (DateTime) AfterInTime

func (dt DateTime) AfterInTime(t time.Time) bool

AfterInTime return true if the DateTime is after another time.Time

func (DateTime) Before

func (dt DateTime) Before(t DateTime) bool

Before return true if the DateTime is before another DateTime

func (DateTime) BeforeInTime

func (dt DateTime) BeforeInTime(t time.Time) bool

BeforeInTime return true if the DateTime is before another time.Time

func (DateTime) BeforeOrEqual

func (dt DateTime) BeforeOrEqual(t DateTime) bool

BeforeOrEqual compare DateTime with another DateTime

func (DateTime) Day

func (dt DateTime) Day() int

Day return day

func (DateTime) EndOfDay

func (dt DateTime) EndOfDay() DateTime

EndOfDay return end of day some database engine like mysql, the precison of datetime is microseconds, so we omit the nsec part. if you want to set the nsec, you can use DateTime.AddDurationInText() or DateTime.AddDuration() to set the nsec.

func (DateTime) EndOfMonth

func (dt DateTime) EndOfMonth() DateTime

EndOfMonth return end of month

func (DateTime) EndOfWeek

func (dt DateTime) EndOfWeek() DateTime

EndOfWeek return end of week (Sunday)

func (DateTime) Equal

func (dt DateTime) Equal(t DateTime) bool

Equal compare two DateTime

func (DateTime) EqualInTime

func (dt DateTime) EqualInTime(t time.Time) bool

EqualInTime compare DateTime with time.Time is Equal

func (DateTime) Format

func (dt DateTime) Format(format TimeFormat) string

Format time with the given format string and return the formatted string

func (DateTime) Hour

func (dt DateTime) Hour() int

Hour return hour

func (DateTime) IsZero

func (dt DateTime) IsZero() bool

IsZero return true if the DateTime is zero

func (DateTime) Minute

func (dt DateTime) Minute() int

Minute return minute

func (DateTime) Month

func (dt DateTime) Month() time.Month

Month return month

func (DateTime) Nanosecond

func (dt DateTime) Nanosecond() int

Nanosecond return nanosecond

func (DateTime) Second

func (dt DateTime) Second() int

Second return second

func (DateTime) StartOfDay

func (dt DateTime) StartOfDay() DateTime

StartOfDay return start of day

func (DateTime) StartOfMonth

func (dt DateTime) StartOfMonth() DateTime

StartOfMonth return start of month

func (DateTime) StartOfWeek

func (dt DateTime) StartOfWeek() DateTime

StartOfWeek return start of week (Monday)

func (DateTime) ToTime

func (dt DateTime) ToTime() time.Time

ToTime convert DateTime to time.Time

func (DateTime) Unix

func (dt DateTime) Unix() int64

Unix return unix timestamp

func (DateTime) UnixNano

func (dt DateTime) UnixNano() int64

UnixNano return unix timestamp with nanosecond

func (DateTime) Year

func (dt DateTime) Year() int

Year return year

type Delete

type Delete struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql

	Text string `xml:",chardata"`
}

Delete children can be one of: CharData, If, Elif, Else, Choose, Where, Foreach, Trim, Otherwise, Include, Sql,

func NewDelete

func NewDelete() *Delete

func (*Delete) Bind

func (m *Delete) Bind(ctx context.Context, input *HandlerPayload) *BindVar

func (*Delete) Evaluate

func (m *Delete) Evaluate(ctx context.Context, input *HandlerPayload) (string, error)

func (*Delete) UnmarshalXML

func (m *Delete) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Elif

type Elif struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewElif

func NewElif() *Elif

func (*Elif) UnmarshalXML

func (m *Elif) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Else

type Else struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewElse

func NewElse() *Else

func (*Else) UnmarshalXML

func (m *Else) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Foreach

type Foreach struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewForeach

func NewForeach() *Foreach

func (*Foreach) UnmarshalXML

func (m *Foreach) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Gobatis

type Gobatis = map[string]interface{}

Gobatis Args bind variables

type Handler

type Handler interface {
	Evaluate(ctx context.Context, input *HandlerPayload) (string, error)
}

type HandlerPayload

type HandlerPayload struct {
	Input     any
	SqlMapper map[string]string
	// contains filtered or unexported fields
}

type If

type If struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewIf

func NewIf() *If

func (*If) Evaluate

func (m *If) Evaluate(ctx context.Context, input *HandlerPayload) (string, error)

func (*If) UnmarshalXML

func (m *If) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Include

type Include struct {
	RefId string `xml:"refid,attr"`
	Alias string `xml:"alias,attr"`
	Value string `xml:"value,attr"`
}

func NewInclude

func NewInclude() *Include

type Insert

type Insert struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql

	Text string `xml:",chardata"`
}

Insert children can be one of: CharData, If, Elif, Else, Choose, Where, Foreach, Trim, Otherwise, Include, Sql,

func NewInsert

func NewInsert() *Insert

func (*Insert) Bind

func (m *Insert) Bind(ctx context.Context, input *HandlerPayload) *BindVar

func (*Insert) Evaluate

func (m *Insert) Evaluate(ctx context.Context, input *HandlerPayload) (string, error)

func (*Insert) UnmarshalXML

func (m *Insert) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Logger

type Logger interface {
	// Log
	// param level: 0:debug, 1:info, 2:error
	// param duration: go time.Duration
	// param sql: prepared sql
	// param args: prepared sql args.
	// when level is LogLevelError, args[0] is error.
	Log(ctx context.Context, level int, duration int64, sql string, args ...any)
}

type Mapper

type Mapper struct {
	Select []*Select
	Update []*Update
	Insert []*Insert
	Delete []*Delete
	Sql    []*Sql

	Attrs   []xml.Attr
	AttrMap map[string]string
}

Mapper all data mapper into Mapper struct

func ParseMapperFromBuffer

func ParseMapperFromBuffer(xmlContent []byte) (*Mapper, error)

ParseMapperFromBuffer parse xml mapper from buffer

func (*Mapper) UnmarshalXML

func (m *Mapper) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Otherwise

type Otherwise struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewOtherwise

func NewOtherwise() *Otherwise

func (*Otherwise) UnmarshalXML

func (m *Otherwise) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type PgArrayBool

type PgArrayBool []bool

PgArrayBool postgresql array bool Exists []bool which Exists was PgArrayBool type

func (*PgArrayBool) Scan

func (pg *PgArrayBool) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayBool) Value

func (pg *PgArrayBool) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayBox

type PgArrayBox []*PgBox

PgArrayBox postgres array box type

func (*PgArrayBox) Scan

func (pg *PgArrayBox) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayBox) Value

func (pg *PgArrayBox) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayCircle

type PgArrayCircle []*PgCircle

PgArrayCircle postgres circle[] type

func (*PgArrayCircle) Scan

func (pg *PgArrayCircle) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayCircle) Value

func (pg *PgArrayCircle) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayFloat

type PgArrayFloat []float64

PgArrayFloat postgresql array float Prices []float64 which Prices was PgArrayFloat type

func (*PgArrayFloat) Scan

func (pg *PgArrayFloat) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayFloat) Value

func (pg *PgArrayFloat) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayInt

type PgArrayInt []int64

PgArrayInt postgresql array int Ids []int which Ids was PgArrayInt type

func (*PgArrayInt) Scan

func (pg *PgArrayInt) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayInt) Value

func (pg *PgArrayInt) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayLSeg

type PgArrayLSeg []*PgLSeg

PgArrayLSeg postgres array lseg type

func (*PgArrayLSeg) Scan

func (pg *PgArrayLSeg) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayLSeg) Value

func (pg *PgArrayLSeg) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayLine

type PgArrayLine []*PgLine

PgArrayLine postgres array line type

func (*PgArrayLine) Scan

func (pg *PgArrayLine) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayLine) Value

func (pg *PgArrayLine) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayPath

type PgArrayPath []*PgPath

PgArrayPath postgres path[] type

func (*PgArrayPath) Scan

func (pg *PgArrayPath) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayPath) Value

func (pg *PgArrayPath) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayPoint

type PgArrayPoint []*PgPoint

PgArrayPoint postgres point[] type

func (*PgArrayPoint) Scan

func (pg *PgArrayPoint) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayPoint) Value

func (pg *PgArrayPoint) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayPolygon

type PgArrayPolygon []*PgPolygon

PgArrayPolygon postgres polygon[] type

func (*PgArrayPolygon) Scan

func (pg *PgArrayPolygon) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayPolygon) Value

func (pg *PgArrayPolygon) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayRange

type PgArrayRange []*PgRange

PgArrayRange postgres range[], contains `int4range`, `int8range`, `numrange`, `tsrange`, `tstzrange`, `daterange` type

func (*PgArrayRange) Scan

func (pg *PgArrayRange) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayRange) Value

func (pg *PgArrayRange) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayRecord

type PgArrayRecord []PgRecord

func (*PgArrayRecord) Scan

func (pg *PgArrayRecord) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayRecord) Value

func (pg *PgArrayRecord) Value() (driver.Value, error)

Value sql/database Value interface

type PgArrayString

type PgArrayString []string

PgArrayString postgresql array string Names []text which Names was PgArrayString type

func (*PgArrayString) Scan

func (pg *PgArrayString) Scan(value any) error

Scan sql/database Scan interface

func (*PgArrayString) Value

func (pg *PgArrayString) Value() (driver.Value, error)

Value sql/database Value interface

type PgBox

type PgBox struct {
	RightTop   *PgPoint
	LeftBottom *PgPoint
}

PgBox postgres box type

func (*PgBox) Scan

func (pg *PgBox) Scan(value any) error

Scan sql/database Scan interface

func (*PgBox) Value

func (pg *PgBox) Value() (driver.Value, error)

Value sql/database Value interface

type PgCircle

type PgCircle struct {
	Center *PgPoint
	Radius float64
}

PgCircle postgres circle type

func (*PgCircle) Scan

func (pg *PgCircle) Scan(value any) error

Scan sql/database Scan interface

func (*PgCircle) Value

func (pg *PgCircle) Value() (driver.Value, error)

Value sql/database Value interface

type PgLSeg

type PgLSeg struct {
	P1, P2 *PgPoint
}

PgLSeg postgres lseg type

func (*PgLSeg) Scan

func (pg *PgLSeg) Scan(value any) error

Scan sql/database Scan interface

func (*PgLSeg) Value

func (pg *PgLSeg) Value() (driver.Value, error)

Value sql/database Value interface

type PgLine

type PgLine struct {
	A, B, C float64
}

PgLine postgres line type

func (*PgLine) Scan

func (pg *PgLine) Scan(value any) error

Scan sql/database Scan interface

func (*PgLine) Value

func (pg *PgLine) Value() (driver.Value, error)

Value sql/database Value interface

type PgPath

type PgPath struct {
	Points []*PgPoint
	Open   bool
}

PgPath postgres path type

func (*PgPath) Scan

func (pg *PgPath) Scan(value any) error

Scan sql/database Scan interface

func (*PgPath) Value

func (pg *PgPath) Value() (driver.Value, error)

Value sql/database Value interface

type PgPoint

type PgPoint struct {
	X float64
	Y float64
}

PgPoint postgres point type

func (*PgPoint) Scan

func (pg *PgPoint) Scan(value any) error

Scan sql/database Scan interface

func (*PgPoint) Value

func (pg *PgPoint) Value() (driver.Value, error)

Value sql/database Value interface

type PgPolygon

type PgPolygon []*PgPoint

PgPolygon postgres polygon type

func (*PgPolygon) Scan

func (pg *PgPolygon) Scan(value any) error

Scan sql/database Scan interface

func (*PgPolygon) Value

func (pg *PgPolygon) Value() (driver.Value, error)

Value sql/database Value interface

type PgRange

type PgRange struct {
	ContainFrom bool
	From        string

	ContainTo bool
	To        string
}

PgRange postgres range type support int4range, int8range, numrange, tsrange, tstzrange, daterange

func (*PgRange) Scan

func (pg *PgRange) Scan(value any) error

Scan sql/database Scan interface

func (*PgRange) Value

func (pg *PgRange) Value() (driver.Value, error)

Value sql/database Value interface

type PgRecord

type PgRecord []string

PgRecord postgres record type caller should use this method as inner value to parse value into field. each field should be string, array, record, range type. user should convert to the real type.

caller should use this method as inner value to parse value into field. like this:

type SomeRecord struct {
	value gobatis.Record
	FieldOne string `pg:"field_one"`
	FieldTwo string `pg:"field_two"`
}

func (sr *SomeRecord) Scan(value any) error {
	err := sr.value.scan(value)
	if err != nil {
	  return err
	}
	sr.FieldOne = sr.value[0]
	sr.FieldTwo = sr.value[1]
	return nil
}

func (sr *SomeRecord) Value() (driver.Value, error) {
	sr.value = nil
	sr.value = append(sr.value, sr.FieldOne, sr.FieldTwo)
    return sr.value.Value()
}

func (*PgRecord) Scan

func (pg *PgRecord) Scan(value any) error

Scan sql/database Scan interface

func (*PgRecord) Value

func (pg *PgRecord) Value() (driver.Value, error)

Value sql/database Value interface

type PgVectorFloat added in v1.3.9

type PgVectorFloat []float64

PgVectorFloat postgresql array float Prices []float64 which Prices was PgArrayFloat type

func (*PgVectorFloat) Scan added in v1.3.9

func (pg *PgVectorFloat) Scan(value any) error

Scan sql/database Scan interface

func (*PgVectorFloat) Value added in v1.3.9

func (pg *PgVectorFloat) Value() (driver.Value, error)

Value sql/database Value interface

type Select

type Select struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

Select children can be one of: CharData, If, Elif, Else, Choose, Where, Foreach, Trim, Otherwise, Include, Sql,

func NewSelect

func NewSelect() *Select

func (*Select) Bind

func (m *Select) Bind(ctx context.Context, input *HandlerPayload) *BindVar

func (*Select) Evaluate

func (m *Select) Evaluate(ctx context.Context, input *HandlerPayload) (string, error)

func (*Select) UnmarshalXML

func (m *Select) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Sql

type Sql struct {
	Id   string `xml:"id,attr"`
	Text string `xml:",chardata"`
}

func NewSql

func NewSql() *Sql

type TimeFormat

type TimeFormat string

TimeFormat type convert tools function simple example:

Parse string into Time

  1. tq, _ := AsDateTime("2021-01-01", TimeFormat(`Y-m-d`).AsTimeFormat().String()) println(tq.Format(TimeFormatYmdInCN))

or you can use AsTime() function

dt, _ := TimeFormat(`Y-m-d`).AsTimeFormat().AsTime("2021-01-01")
println(dt.Format(TimeFormatYmdInCN)

also, you can simplely use like this:

dt, _ := TimeFormatYmd.AsTime("2021-01-01")
println(dt.Format(TimeFormatYmdInCN)
const (
	TimeFormatY           TimeFormat = "2006"
	TimeFormatYInCN       TimeFormat = "2006年"
	TimeFormatYm          TimeFormat = "2006-1"
	TimeFormatMy          TimeFormat = "1-2006"
	TimeFormatYmInCN      TimeFormat = "2006年1月"
	TimeFormatMyInCN      TimeFormat = "1月2006年"
	TimeFormatYmWithSlash TimeFormat = "2006/1"
	TimeFormatMyWithSlash TimeFormat = "1/2006"

	TimeFormatYmd                  TimeFormat = "2006-1-2"
	TimeFormatYmdWithSlash         TimeFormat = "2006/1/2"
	TimeFormatYmdInCN              TimeFormat = "2006年1月2日"
	TimeFormatYmdHms               TimeFormat = "2006-1-2 15:04:05"
	TimeFormatYmdHmsWithSlash      TimeFormat = "2006/1/2 15:04:05"
	TimeFormatYmdHmsInCN           TimeFormat = "2006年1月2日 15点04分05"
	TimeFormatYmdHmsWithSecondInCN TimeFormat = "2006年1月2日 15点04分05秒"
	TimeFormatHms                  TimeFormat = "15:04:05"
	TimeFormatHmsInCN              TimeFormat = "15点04分05"
	TimeFormatHmsWithSecondInCN    TimeFormat = "15点04分05秒"

	TimeFormatDmyHms TimeFormat = "2/1/2006 15:04:05"
	TimeFormatDmyHis TimeFormat = TimeFormatDmyHms

	TimeFormatMdy TimeFormat = "1-2-2006"

	TimeFormatYmdHis               TimeFormat = TimeFormatYmdHms
	TimeFormatYmdHisWithSlash      TimeFormat = TimeFormatYmdHmsWithSlash
	TimeFormatYmdHisInCN           TimeFormat = TimeFormatYmdHmsInCN
	TimeFormatHis                  TimeFormat = TimeFormatHms
	TimeFormatHisInCN              TimeFormat = TimeFormatHmsInCN
	TimeFormatYmdHisWithSecondInCN TimeFormat = TimeFormatYmdHmsWithSecondInCN
	TimeFormatHisWithSecondInCN    TimeFormat = TimeFormatHmsWithSecondInCN

	TimeFormatRFC3339        TimeFormat = time.RFC3339
	TimeFormatRFC3339Nano    TimeFormat = time.RFC3339Nano
	TimeFormatRFC822         TimeFormat = time.RFC822
	TimeFormatRFC850         TimeFormat = time.RFC850
	TimeFormatRFC822Z        TimeFormat = time.RFC822Z
	TimeFormatRFC1123        TimeFormat = time.RFC1123
	TimeFormatRFC1123Z       TimeFormat = time.RFC1123Z
	TimeFormatUnixDate       TimeFormat = time.UnixDate
	TimeFormatANSIC          TimeFormat = time.ANSIC
	TimeFormatRubyDate       TimeFormat = time.RubyDate
	TimeFormatDateTimeLayout TimeFormat = time.Layout
	TimeFormatKitchen        TimeFormat = time.Kitchen
	TimeFormatStamp          TimeFormat = time.Stamp
	TimeFormatStampMilli     TimeFormat = time.StampMilli
	TimeFormatStampMicro     TimeFormat = time.StampMicro
	TimeFormatStampNano      TimeFormat = time.StampNano
)

func (TimeFormat) AsTime

func (tf TimeFormat) AsTime(v string) (DateTime, error)

AsTime convert string to time.Time

func (TimeFormat) AsTimeFormat

func (tf TimeFormat) AsTimeFormat() TimeFormat

AsTimeFormat convert TimeFormat to time.Time format

func (TimeFormat) AsTimeInLocation

func (tf TimeFormat) AsTimeInLocation(v string, loc *time.Location) (DateTime, error)

AsTimeInLocation convert string to time.Time

func (TimeFormat) AsTimeInLocationName

func (tf TimeFormat) AsTimeInLocationName(v string, locationName string) (DateTime, error)

AsTimeInLocationName convert string to time.Time

func (TimeFormat) String

func (tf TimeFormat) String() string

String return TimeFormat

type Trim

type Trim struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewTrim

func NewTrim() *Trim

func (*Trim) UnmarshalXML

func (m *Trim) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Update

type Update struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql

	Text string `xml:",chardata"`
}

Update children can be one of: CharData, If, Elif, Else, Choose, Where, Foreach, Trim, Otherwise, Include, Sql,

func NewUpdate

func NewUpdate() *Update

func (*Update) Bind

func (m *Update) Bind(ctx context.Context, input *HandlerPayload) *BindVar

func (*Update) Evaluate

func (m *Update) Evaluate(ctx context.Context, input *HandlerPayload) (string, error)

func (*Update) UnmarshalXML

func (m *Update) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type When

type When struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewWhen

func NewWhen() *When

func (*When) UnmarshalXML

func (m *When) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type Where

type Where struct {
	Children []interface{}
	Attrs    []xml.Attr
	AttrsMap map[string]string
	Sql      []*Sql
}

func NewWhere

func NewWhere() *Where

func (*Where) UnmarshalXML

func (m *Where) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

type XmlName

type XmlName xml.Name

func (XmlName) Name

func (xn XmlName) Name() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL