// Code generated by go generate; DO NOT EDIT.
package db

import (
	"encoding/json"
	"fmt"
	stdsql "database/sql"
	"time"

	"github.com/sorintlab/errors"
	sq "github.com/huandu/go-sqlbuilder"

	"agola.io/agola/internal/sqlg"
	"agola.io/agola/internal/sqlg/sql"

	types "agola.io/agola/services/notification/types"
)

var (
	runWebhookSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"runwebhook.id", "runwebhook.revision", "runwebhook.creation_time", "runwebhook.update_time", "runwebhook.payload", "runwebhook.project_id"}
		columns = append(columns, additionalCols...)

		return columns
	}

	runWebhookSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(runWebhookSelectColumns(additionalCols...)...).From("runwebhook")
	}
)

func (d *DB) InsertOrUpdateRunWebhook(tx *sql.Tx, v *types.RunWebhook) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertRunWebhook(tx, v)
	} else {
		err = d.UpdateRunWebhook(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertRunWebhook(tx *sql.Tx, v *types.RunWebhook) error {
	if v.Revision != 0 {
		return errors.Errorf("expected revision 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not created by this transaction")
	}

	v.Revision = 1

	now := time.Now()
	v.CreationTime = now
	v.UpdateTime = now

	var err error

	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawRunWebhookPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRunWebhookSqlite3(tx, v);
	}

	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert runwebhook")
	}

	return nil
}

func (d *DB) UpdateRunWebhook(tx *sql.Tx, v *types.RunWebhook) error {
	if v.Revision < 1 {
		return errors.Errorf("expected revision > 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not fetched by this transaction")
	}

	curRevision := v.Revision
	v.Revision++

	v.UpdateTime = time.Now()

	var res stdsql.Result
	var err error
	switch d.DBType() {
	case sql.Postgres:
		res, err = d.updateRunWebhookPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateRunWebhookSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update runwebhook")
	}

	rows, err := res.RowsAffected()
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update runwebhook")
	}

	if rows != 1 {
		v.Revision = curRevision
		return sqlg.ErrConcurrent
	}

	return nil
}

func (d *DB) deleteRunWebhook(tx *sql.Tx, runWebhookID string) error {
	q := sq.NewDeleteBuilder()
	q.DeleteFrom("runwebhook").Where(q.E("id", runWebhookID))

	if _, err := d.exec(tx, q); err != nil {
		return errors.Wrap(err, "failed to delete runWebhook")
	}

	return nil
}

func (d *DB) DeleteRunWebhook(tx *sql.Tx, id string) error {
	return d.deleteRunWebhook(tx, id)
}

// insertRawRunWebhook should be used only for import.
// * It won't update object times.
// * It will insert values for sequences.
func (d *DB) insertRawRunWebhook(tx *sql.Tx, v *types.RunWebhook) error {
	v.Revision = 1

	var err error
	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawRunWebhookPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRawRunWebhookSqlite3(tx, v);
	}
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert runwebhook")
	}

	return nil
}

var (
	runWebhookDeliverySelectColumns = func(additionalCols ...string) []string {
		columns := []string{"runwebhookdelivery.id", "runwebhookdelivery.revision", "runwebhookdelivery.creation_time", "runwebhookdelivery.update_time", "runwebhookdelivery.sequence", "runwebhookdelivery.run_webhook_id", "runwebhookdelivery.delivery_status", "runwebhookdelivery.delivered_at", "runwebhookdelivery.status_code"}
		columns = append(columns, additionalCols...)

		return columns
	}

	runWebhookDeliverySelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(runWebhookDeliverySelectColumns(additionalCols...)...).From("runwebhookdelivery")
	}
)

func (d *DB) InsertOrUpdateRunWebhookDelivery(tx *sql.Tx, v *types.RunWebhookDelivery) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertRunWebhookDelivery(tx, v)
	} else {
		err = d.UpdateRunWebhookDelivery(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertRunWebhookDelivery(tx *sql.Tx, v *types.RunWebhookDelivery) error {
	if v.Revision != 0 {
		return errors.Errorf("expected revision 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not created by this transaction")
	}

	v.Revision = 1

	now := time.Now()
	v.CreationTime = now
	v.UpdateTime = now

	var err error
	var nextSeq uint64

	nextSeq, err = d.nextSequence(tx, "runwebhookdelivery_sequence_seq")
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to create next sequence for runwebhookdelivery_sequence_seq")
	}
	v.Sequence = nextSeq

	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawRunWebhookDeliveryPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRunWebhookDeliverySqlite3(tx, v);
	}

	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert runwebhookdelivery")
	}

	return nil
}

func (d *DB) UpdateRunWebhookDelivery(tx *sql.Tx, v *types.RunWebhookDelivery) error {
	if v.Revision < 1 {
		return errors.Errorf("expected revision > 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not fetched by this transaction")
	}

	curRevision := v.Revision
	v.Revision++

	v.UpdateTime = time.Now()

	var res stdsql.Result
	var err error
	switch d.DBType() {
	case sql.Postgres:
		res, err = d.updateRunWebhookDeliveryPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateRunWebhookDeliverySqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update runwebhookdelivery")
	}

	rows, err := res.RowsAffected()
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update runwebhookdelivery")
	}

	if rows != 1 {
		v.Revision = curRevision
		return sqlg.ErrConcurrent
	}

	return nil
}

func (d *DB) deleteRunWebhookDelivery(tx *sql.Tx, runWebhookDeliveryID string) error {
	q := sq.NewDeleteBuilder()
	q.DeleteFrom("runwebhookdelivery").Where(q.E("id", runWebhookDeliveryID))

	if _, err := d.exec(tx, q); err != nil {
		return errors.Wrap(err, "failed to delete runWebhookDelivery")
	}

	return nil
}

func (d *DB) DeleteRunWebhookDelivery(tx *sql.Tx, id string) error {
	return d.deleteRunWebhookDelivery(tx, id)
}

// insertRawRunWebhookDelivery should be used only for import.
// * It won't update object times.
// * It will insert values for sequences.
func (d *DB) insertRawRunWebhookDelivery(tx *sql.Tx, v *types.RunWebhookDelivery) error {
	v.Revision = 1

	var err error
	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawRunWebhookDeliveryPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRawRunWebhookDeliverySqlite3(tx, v);
	}
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert runwebhookdelivery")
	}

	return nil
}

var (
	lastRunEventSequenceSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"lastruneventsequence.id", "lastruneventsequence.revision", "lastruneventsequence.creation_time", "lastruneventsequence.update_time", "lastruneventsequence.value"}
		columns = append(columns, additionalCols...)

		return columns
	}

	lastRunEventSequenceSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(lastRunEventSequenceSelectColumns(additionalCols...)...).From("lastruneventsequence")
	}
)

func (d *DB) InsertOrUpdateLastRunEventSequence(tx *sql.Tx, v *types.LastRunEventSequence) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertLastRunEventSequence(tx, v)
	} else {
		err = d.UpdateLastRunEventSequence(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertLastRunEventSequence(tx *sql.Tx, v *types.LastRunEventSequence) error {
	if v.Revision != 0 {
		return errors.Errorf("expected revision 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not created by this transaction")
	}

	v.Revision = 1

	now := time.Now()
	v.CreationTime = now
	v.UpdateTime = now

	var err error

	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawLastRunEventSequencePostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertLastRunEventSequenceSqlite3(tx, v);
	}

	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert lastruneventsequence")
	}

	return nil
}

func (d *DB) UpdateLastRunEventSequence(tx *sql.Tx, v *types.LastRunEventSequence) error {
	if v.Revision < 1 {
		return errors.Errorf("expected revision > 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not fetched by this transaction")
	}

	curRevision := v.Revision
	v.Revision++

	v.UpdateTime = time.Now()

	var res stdsql.Result
	var err error
	switch d.DBType() {
	case sql.Postgres:
		res, err = d.updateLastRunEventSequencePostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateLastRunEventSequenceSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update lastruneventsequence")
	}

	rows, err := res.RowsAffected()
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update lastruneventsequence")
	}

	if rows != 1 {
		v.Revision = curRevision
		return sqlg.ErrConcurrent
	}

	return nil
}

func (d *DB) deleteLastRunEventSequence(tx *sql.Tx, lastRunEventSequenceID string) error {
	q := sq.NewDeleteBuilder()
	q.DeleteFrom("lastruneventsequence").Where(q.E("id", lastRunEventSequenceID))

	if _, err := d.exec(tx, q); err != nil {
		return errors.Wrap(err, "failed to delete lastRunEventSequence")
	}

	return nil
}

func (d *DB) DeleteLastRunEventSequence(tx *sql.Tx, id string) error {
	return d.deleteLastRunEventSequence(tx, id)
}

// insertRawLastRunEventSequence should be used only for import.
// * It won't update object times.
// * It will insert values for sequences.
func (d *DB) insertRawLastRunEventSequence(tx *sql.Tx, v *types.LastRunEventSequence) error {
	v.Revision = 1

	var err error
	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawLastRunEventSequencePostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRawLastRunEventSequenceSqlite3(tx, v);
	}
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert lastruneventsequence")
	}

	return nil
}

var (
	commitStatusSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"commitstatus.id", "commitstatus.revision", "commitstatus.creation_time", "commitstatus.update_time", "commitstatus.project_id", "commitstatus.state", "commitstatus.commit_sha", "commitstatus.run_counter", "commitstatus.description", "commitstatus.context"}
		columns = append(columns, additionalCols...)

		return columns
	}

	commitStatusSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(commitStatusSelectColumns(additionalCols...)...).From("commitstatus")
	}
)

func (d *DB) InsertOrUpdateCommitStatus(tx *sql.Tx, v *types.CommitStatus) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertCommitStatus(tx, v)
	} else {
		err = d.UpdateCommitStatus(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertCommitStatus(tx *sql.Tx, v *types.CommitStatus) error {
	if v.Revision != 0 {
		return errors.Errorf("expected revision 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not created by this transaction")
	}

	v.Revision = 1

	now := time.Now()
	v.CreationTime = now
	v.UpdateTime = now

	var err error

	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawCommitStatusPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertCommitStatusSqlite3(tx, v);
	}

	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert commitstatus")
	}

	return nil
}

func (d *DB) UpdateCommitStatus(tx *sql.Tx, v *types.CommitStatus) error {
	if v.Revision < 1 {
		return errors.Errorf("expected revision > 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not fetched by this transaction")
	}

	curRevision := v.Revision
	v.Revision++

	v.UpdateTime = time.Now()

	var res stdsql.Result
	var err error
	switch d.DBType() {
	case sql.Postgres:
		res, err = d.updateCommitStatusPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateCommitStatusSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update commitstatus")
	}

	rows, err := res.RowsAffected()
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update commitstatus")
	}

	if rows != 1 {
		v.Revision = curRevision
		return sqlg.ErrConcurrent
	}

	return nil
}

func (d *DB) deleteCommitStatus(tx *sql.Tx, commitStatusID string) error {
	q := sq.NewDeleteBuilder()
	q.DeleteFrom("commitstatus").Where(q.E("id", commitStatusID))

	if _, err := d.exec(tx, q); err != nil {
		return errors.Wrap(err, "failed to delete commitStatus")
	}

	return nil
}

func (d *DB) DeleteCommitStatus(tx *sql.Tx, id string) error {
	return d.deleteCommitStatus(tx, id)
}

// insertRawCommitStatus should be used only for import.
// * It won't update object times.
// * It will insert values for sequences.
func (d *DB) insertRawCommitStatus(tx *sql.Tx, v *types.CommitStatus) error {
	v.Revision = 1

	var err error
	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawCommitStatusPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRawCommitStatusSqlite3(tx, v);
	}
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert commitstatus")
	}

	return nil
}

var (
	commitStatusDeliverySelectColumns = func(additionalCols ...string) []string {
		columns := []string{"commitstatusdelivery.id", "commitstatusdelivery.revision", "commitstatusdelivery.creation_time", "commitstatusdelivery.update_time", "commitstatusdelivery.sequence", "commitstatusdelivery.commit_status_id", "commitstatusdelivery.delivery_status", "commitstatusdelivery.delivered_at"}
		columns = append(columns, additionalCols...)

		return columns
	}

	commitStatusDeliverySelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(commitStatusDeliverySelectColumns(additionalCols...)...).From("commitstatusdelivery")
	}
)

func (d *DB) InsertOrUpdateCommitStatusDelivery(tx *sql.Tx, v *types.CommitStatusDelivery) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertCommitStatusDelivery(tx, v)
	} else {
		err = d.UpdateCommitStatusDelivery(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertCommitStatusDelivery(tx *sql.Tx, v *types.CommitStatusDelivery) error {
	if v.Revision != 0 {
		return errors.Errorf("expected revision 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not created by this transaction")
	}

	v.Revision = 1

	now := time.Now()
	v.CreationTime = now
	v.UpdateTime = now

	var err error
	var nextSeq uint64

	nextSeq, err = d.nextSequence(tx, "commitstatusdelivery_sequence_seq")
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to create next sequence for commitstatusdelivery_sequence_seq")
	}
	v.Sequence = nextSeq

	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawCommitStatusDeliveryPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertCommitStatusDeliverySqlite3(tx, v);
	}

	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert commitstatusdelivery")
	}

	return nil
}

func (d *DB) UpdateCommitStatusDelivery(tx *sql.Tx, v *types.CommitStatusDelivery) error {
	if v.Revision < 1 {
		return errors.Errorf("expected revision > 0 got %d", v.Revision)
	}

	if v.TxID != tx.ID() {
		return errors.Errorf("object was not fetched by this transaction")
	}

	curRevision := v.Revision
	v.Revision++

	v.UpdateTime = time.Now()

	var res stdsql.Result
	var err error
	switch d.DBType() {
	case sql.Postgres:
		res, err = d.updateCommitStatusDeliveryPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateCommitStatusDeliverySqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update commitstatusdelivery")
	}

	rows, err := res.RowsAffected()
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update commitstatusdelivery")
	}

	if rows != 1 {
		v.Revision = curRevision
		return sqlg.ErrConcurrent
	}

	return nil
}

func (d *DB) deleteCommitStatusDelivery(tx *sql.Tx, commitStatusDeliveryID string) error {
	q := sq.NewDeleteBuilder()
	q.DeleteFrom("commitstatusdelivery").Where(q.E("id", commitStatusDeliveryID))

	if _, err := d.exec(tx, q); err != nil {
		return errors.Wrap(err, "failed to delete commitStatusDelivery")
	}

	return nil
}

func (d *DB) DeleteCommitStatusDelivery(tx *sql.Tx, id string) error {
	return d.deleteCommitStatusDelivery(tx, id)
}

// insertRawCommitStatusDelivery should be used only for import.
// * It won't update object times.
// * It will insert values for sequences.
func (d *DB) insertRawCommitStatusDelivery(tx *sql.Tx, v *types.CommitStatusDelivery) error {
	v.Revision = 1

	var err error
	switch d.DBType() {
	case sql.Postgres:
		err = d.insertRawCommitStatusDeliveryPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRawCommitStatusDeliverySqlite3(tx, v);
	}
	if err != nil {
		v.Revision = 0
		return errors.Wrap(err, "failed to insert commitstatusdelivery")
	}

	return nil
}

func (d *DB) UnmarshalExportObject(data []byte) (sqlg.Object, error) {
	type exportObjectExportMeta struct {
		ExportMeta sqlg.ExportMeta `json:"exportMeta"`
	}

	var om exportObjectExportMeta
	if err := json.Unmarshal(data, &om); err != nil {
		return nil, errors.WithStack(err)
	}

	var obj sqlg.Object

	switch om.ExportMeta.Kind {
	case "RunWebhook":
		obj = &types.RunWebhook{}
	case "RunWebhookDelivery":
		obj = &types.RunWebhookDelivery{}
	case "LastRunEventSequence":
		obj = &types.LastRunEventSequence{}
	case "CommitStatus":
		obj = &types.CommitStatus{}
	case "CommitStatusDelivery":
		obj = &types.CommitStatusDelivery{}

	default:
		panic(errors.Errorf("unknown object kind %q, data: %s", om.ExportMeta.Kind, data))
	}

	if err := json.Unmarshal(data, &obj); err != nil {
		return nil, errors.WithStack(err)
	}

	return obj, nil
}

func (d *DB) InsertRawObject(tx *sql.Tx, obj sqlg.Object) error {
	switch o := obj.(type) {
	case *types.RunWebhook:
		return d.insertRawRunWebhook(tx, o)
	case *types.RunWebhookDelivery:
		return d.insertRawRunWebhookDelivery(tx, o)
	case *types.LastRunEventSequence:
		return d.insertRawLastRunEventSequence(tx, o)
	case *types.CommitStatus:
		return d.insertRawCommitStatus(tx, o)
	case *types.CommitStatusDelivery:
		return d.insertRawCommitStatusDelivery(tx, o)

	default:
		panic(errors.Errorf("unknown object type %T", obj))
	}
}

func (d *DB) SelectObject(kind string) *sq.SelectBuilder {
	switch kind {
	case "RunWebhook":
		return runWebhookSelect()
	case "RunWebhookDelivery":
		return runWebhookDeliverySelect()
	case "LastRunEventSequence":
		return lastRunEventSequenceSelect()
	case "CommitStatus":
		return commitStatusSelect()
	case "CommitStatusDelivery":
		return commitStatusDeliverySelect()

	default:
		panic(errors.Errorf("unknown object kind %q", kind))
	}
}

func (d *DB) FetchObjects(tx *sql.Tx, kind string, q sq.Builder) ([]sqlg.Object, error) {
	switch kind {
	case "RunWebhook":
		fobjs, _, err := d.fetchRunWebhooks(tx, q)
		if err != nil {
			return nil, errors.WithStack(err)
		}

		objs := make([]sqlg.Object, len(fobjs))
		for i, fobj := range fobjs {
		        objs[i] = fobj
		}

		return objs, nil
	case "RunWebhookDelivery":
		fobjs, _, err := d.fetchRunWebhookDeliverys(tx, q)
		if err != nil {
			return nil, errors.WithStack(err)
		}

		objs := make([]sqlg.Object, len(fobjs))
		for i, fobj := range fobjs {
		        objs[i] = fobj
		}

		return objs, nil
	case "LastRunEventSequence":
		fobjs, _, err := d.fetchLastRunEventSequences(tx, q)
		if err != nil {
			return nil, errors.WithStack(err)
		}

		objs := make([]sqlg.Object, len(fobjs))
		for i, fobj := range fobjs {
		        objs[i] = fobj
		}

		return objs, nil
	case "CommitStatus":
		fobjs, _, err := d.fetchCommitStatuss(tx, q)
		if err != nil {
			return nil, errors.WithStack(err)
		}

		objs := make([]sqlg.Object, len(fobjs))
		for i, fobj := range fobjs {
		        objs[i] = fobj
		}

		return objs, nil
	case "CommitStatusDelivery":
		fobjs, _, err := d.fetchCommitStatusDeliverys(tx, q)
		if err != nil {
			return nil, errors.WithStack(err)
		}

		objs := make([]sqlg.Object, len(fobjs))
		for i, fobj := range fobjs {
		        objs[i] = fobj
		}

		return objs, nil

	default:
		panic(errors.Errorf("unknown object kind %q", kind))
	}
}

func (d *DB) ObjectToExportJSON(obj sqlg.Object, e *json.Encoder) error {
	switch o := obj.(type) {
	case *types.RunWebhook:
		type exportObject struct {
			ExportMeta sqlg.ExportMeta `json:"exportMeta"`

			*types.RunWebhook
		}

		if err := e.Encode(&exportObject{ExportMeta: sqlg.ExportMeta{ Kind: "RunWebhook" }, RunWebhook: o}); err != nil {
			return errors.WithStack(err)
		}

		return nil
	case *types.RunWebhookDelivery:
		type exportObject struct {
			ExportMeta sqlg.ExportMeta `json:"exportMeta"`

			*types.RunWebhookDelivery
		}

		if err := e.Encode(&exportObject{ExportMeta: sqlg.ExportMeta{ Kind: "RunWebhookDelivery" }, RunWebhookDelivery: o}); err != nil {
			return errors.WithStack(err)
		}

		return nil
	case *types.LastRunEventSequence:
		type exportObject struct {
			ExportMeta sqlg.ExportMeta `json:"exportMeta"`

			*types.LastRunEventSequence
		}

		if err := e.Encode(&exportObject{ExportMeta: sqlg.ExportMeta{ Kind: "LastRunEventSequence" }, LastRunEventSequence: o}); err != nil {
			return errors.WithStack(err)
		}

		return nil
	case *types.CommitStatus:
		type exportObject struct {
			ExportMeta sqlg.ExportMeta `json:"exportMeta"`

			*types.CommitStatus
		}

		if err := e.Encode(&exportObject{ExportMeta: sqlg.ExportMeta{ Kind: "CommitStatus" }, CommitStatus: o}); err != nil {
			return errors.WithStack(err)
		}

		return nil
	case *types.CommitStatusDelivery:
		type exportObject struct {
			ExportMeta sqlg.ExportMeta `json:"exportMeta"`

			*types.CommitStatusDelivery
		}

		if err := e.Encode(&exportObject{ExportMeta: sqlg.ExportMeta{ Kind: "CommitStatusDelivery" }, CommitStatusDelivery: o}); err != nil {
			return errors.WithStack(err)
		}

		return nil

	default:
		panic(errors.Errorf("unknown object kind %T", obj))
	}
}

func (d *DB) GetSequence(tx *sql.Tx, sequenceName string) (uint64, error) {
	var q *sq.SelectBuilder

	switch d.DBType() {
	case sql.Postgres:
		q = sq.NewSelectBuilder().Select("last_value").From(sequenceName)

	case sql.Sqlite3:
		q = sq.NewSelectBuilder().Select("value").From("sequence_t")
		q.Where(q.E("name", sequenceName))
	}

	rows, err := d.query(tx, q)
	if err != nil {
		return 0, errors.WithStack(err)
	}
	defer rows.Close()

	var value uint64
	if !rows.Next() {
		return value, nil
	}

	if err := rows.Scan(&value); err != nil {
		return 0, errors.Wrap(err, "failed to scan rows")
	}
	if err := rows.Err(); err != nil {
		return 0, errors.WithStack(err)
	}

	return value, nil
}

func (d *DB) nextSequence(tx *sql.Tx, sequenceName string) (uint64, error) {
	var value uint64

	switch d.DBType() {
	case sql.Postgres:
		q := fmt.Sprintf("SELECT nextval('%s');", sequenceName)

		rows, err := tx.Query(q)
		if err != nil {
			return 0, errors.Wrapf(err, "failed to get sequence %s nextval", sequenceName)
		}

		defer rows.Close()

		if !rows.Next() {
			return value, nil
		}

		if err := rows.Scan(&value); err != nil {
			return 0, errors.Wrap(err, "failed to scan rows")
		}
		if err := rows.Err(); err != nil {
			return 0, errors.WithStack(err)
		}

	case sql.Sqlite3:
		var err error
		value, err = d.GetSequence(tx, sequenceName)
		if err != nil {
			return 0, errors.WithStack(err)
		}

		if value == 0 {
			value++
			q := sq.NewInsertBuilder()
			q.InsertInto("sequence_t").Cols("name", "value").Values(sequenceName, value)
			if _, err := d.exec(tx, q); err != nil {
				return 0, errors.WithStack(err)
			}
		} else {
			value++
			q := sq.NewUpdateBuilder()
			q.Update("sequence_t").Set(q.Assign("value", value)).Where(q.E("name", sequenceName))
			if _, err := d.exec(tx, q); err != nil {
				return 0, errors.WithStack(err)
			}
		}
	}

	return value, nil
}

func (d *DB) PopulateSequences(tx *sql.Tx) error {
	switch d.DBType() {
	case sql.Postgres:
		return d.populateSequencesPostgres(tx);
	case sql.Sqlite3:
		return d.populateSequencesSqlite3(tx);
	}

	return nil
}

func (d *DB) populateSequencesPostgres(tx *sql.Tx) error {
	var q string
	q = "SELECT setval('runwebhookdelivery_sequence_seq', (SELECT COALESCE(MAX(sequence), 1) FROM runwebhookdelivery));"
	if _, err := tx.Exec(q); err != nil {
		return errors.Wrap(err, "failed to update sequence runwebhookdelivery_sequence_seq")
	}
	q = "SELECT setval('commitstatusdelivery_sequence_seq', (SELECT COALESCE(MAX(sequence), 1) FROM commitstatusdelivery));"
	if _, err := tx.Exec(q); err != nil {
		return errors.Wrap(err, "failed to update sequence commitstatusdelivery_sequence_seq")
	}

	return nil
}

func (d *DB) populateSequencesSqlite3(tx *sql.Tx) error {
	var q string
	q = "INSERT INTO sequence_t (name, value) VALUES ('runwebhookdelivery_sequence_seq', (SELECT COALESCE(MAX(sequence), 1) FROM runwebhookdelivery));"
	if _, err := tx.Exec(q); err != nil {
		return errors.Wrap(err, "failed to update sequence for runwebhookdelivery_sequence_seq")
	}
	q = "INSERT INTO sequence_t (name, value) VALUES ('commitstatusdelivery_sequence_seq', (SELECT COALESCE(MAX(sequence), 1) FROM commitstatusdelivery));"
	if _, err := tx.Exec(q); err != nil {
		return errors.Wrap(err, "failed to update sequence for commitstatusdelivery_sequence_seq")
	}

	return nil
}
