// 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/configstore/types"
)

var (
	remoteSourceSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"remotesource.id", "remotesource.revision", "remotesource.creation_time", "remotesource.update_time", "remotesource.name", "remotesource.apiurl", "remotesource.skip_verify", "remotesource.type", "remotesource.auth_type", "remotesource.oauth2_client_id", "remotesource.oauth2_client_secret", "remotesource.ssh_host_key", "remotesource.skip_ssh_host_key_check", "remotesource.registration_enabled", "remotesource.login_enabled"}
		columns = append(columns, additionalCols...)

		return columns
	}

	remoteSourceSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(remoteSourceSelectColumns(additionalCols...)...).From("remotesource")
	}
)

func (d *DB) InsertOrUpdateRemoteSource(tx *sql.Tx, v *types.RemoteSource) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertRemoteSource(tx, v)
	} else {
		err = d.UpdateRemoteSource(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertRemoteSource(tx *sql.Tx, v *types.RemoteSource) 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.insertRawRemoteSourcePostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertRemoteSourceSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateRemoteSource(tx *sql.Tx, v *types.RemoteSource) 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.updateRemoteSourcePostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateRemoteSourceSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update remotesource")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	userSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"user_t.id", "user_t.revision", "user_t.creation_time", "user_t.update_time", "user_t.name", "user_t.secret", "user_t.admin"}
		columns = append(columns, additionalCols...)

		return columns
	}

	userSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(userSelectColumns(additionalCols...)...).From("user_t")
	}
)

func (d *DB) InsertOrUpdateUser(tx *sql.Tx, v *types.User) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertUser(tx, v)
	} else {
		err = d.UpdateUser(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertUser(tx *sql.Tx, v *types.User) 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.insertRawUserPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertUserSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateUser(tx *sql.Tx, v *types.User) 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.updateUserPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateUserSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update user_t")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	userTokenSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"usertoken.id", "usertoken.revision", "usertoken.creation_time", "usertoken.update_time", "usertoken.user_id", "usertoken.name", "usertoken.value"}
		columns = append(columns, additionalCols...)

		return columns
	}

	userTokenSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(userTokenSelectColumns(additionalCols...)...).From("usertoken")
	}
)

func (d *DB) InsertOrUpdateUserToken(tx *sql.Tx, v *types.UserToken) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertUserToken(tx, v)
	} else {
		err = d.UpdateUserToken(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertUserToken(tx *sql.Tx, v *types.UserToken) 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.insertRawUserTokenPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertUserTokenSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateUserToken(tx *sql.Tx, v *types.UserToken) 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.updateUserTokenPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateUserTokenSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update usertoken")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	linkedAccountSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"linkedaccount.id", "linkedaccount.revision", "linkedaccount.creation_time", "linkedaccount.update_time", "linkedaccount.user_id", "linkedaccount.remote_user_id", "linkedaccount.remote_user_name", "linkedaccount.remote_user_avatar_url", "linkedaccount.remote_source_id", "linkedaccount.user_access_token", "linkedaccount.oauth2_access_token", "linkedaccount.oauth2_refresh_token", "linkedaccount.oauth2_access_token_expires_at"}
		columns = append(columns, additionalCols...)

		return columns
	}

	linkedAccountSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(linkedAccountSelectColumns(additionalCols...)...).From("linkedaccount")
	}
)

func (d *DB) InsertOrUpdateLinkedAccount(tx *sql.Tx, v *types.LinkedAccount) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertLinkedAccount(tx, v)
	} else {
		err = d.UpdateLinkedAccount(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertLinkedAccount(tx *sql.Tx, v *types.LinkedAccount) 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.insertRawLinkedAccountPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertLinkedAccountSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateLinkedAccount(tx *sql.Tx, v *types.LinkedAccount) 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.updateLinkedAccountPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateLinkedAccountSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update linkedaccount")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	organizationSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"organization.id", "organization.revision", "organization.creation_time", "organization.update_time", "organization.name", "organization.visibility", "organization.creator_user_id"}
		columns = append(columns, additionalCols...)

		return columns
	}

	organizationSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(organizationSelectColumns(additionalCols...)...).From("organization")
	}
)

func (d *DB) InsertOrUpdateOrganization(tx *sql.Tx, v *types.Organization) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertOrganization(tx, v)
	} else {
		err = d.UpdateOrganization(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertOrganization(tx *sql.Tx, v *types.Organization) 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.insertRawOrganizationPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertOrganizationSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateOrganization(tx *sql.Tx, v *types.Organization) 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.updateOrganizationPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateOrganizationSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update organization")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	organizationMemberSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"orgmember.id", "orgmember.revision", "orgmember.creation_time", "orgmember.update_time", "orgmember.organization_id", "orgmember.user_id", "orgmember.member_role"}
		columns = append(columns, additionalCols...)

		return columns
	}

	organizationMemberSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(organizationMemberSelectColumns(additionalCols...)...).From("orgmember")
	}
)

func (d *DB) InsertOrUpdateOrganizationMember(tx *sql.Tx, v *types.OrganizationMember) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertOrganizationMember(tx, v)
	} else {
		err = d.UpdateOrganizationMember(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertOrganizationMember(tx *sql.Tx, v *types.OrganizationMember) 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.insertRawOrganizationMemberPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertOrganizationMemberSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateOrganizationMember(tx *sql.Tx, v *types.OrganizationMember) 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.updateOrganizationMemberPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateOrganizationMemberSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update orgmember")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	projectGroupSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"projectgroup.id", "projectgroup.revision", "projectgroup.creation_time", "projectgroup.update_time", "projectgroup.name", "projectgroup.parent_kind", "projectgroup.parent_id", "projectgroup.visibility"}
		columns = append(columns, additionalCols...)

		return columns
	}

	projectGroupSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(projectGroupSelectColumns(additionalCols...)...).From("projectgroup")
	}
)

func (d *DB) InsertOrUpdateProjectGroup(tx *sql.Tx, v *types.ProjectGroup) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertProjectGroup(tx, v)
	} else {
		err = d.UpdateProjectGroup(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertProjectGroup(tx *sql.Tx, v *types.ProjectGroup) 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.insertRawProjectGroupPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertProjectGroupSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateProjectGroup(tx *sql.Tx, v *types.ProjectGroup) 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.updateProjectGroupPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateProjectGroupSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update projectgroup")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	projectSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"project.id", "project.revision", "project.creation_time", "project.update_time", "project.name", "project.parent_kind", "project.parent_id", "project.secret", "project.visibility", "project.remote_repository_config_type", "project.remote_source_id", "project.linked_account_id", "project.repository_id", "project.repository_path", "project.ssh_private_key", "project.skip_ssh_host_key_check", "project.webhook_secret", "project.pass_vars_to_forked_pr", "project.default_branch"}
		columns = append(columns, additionalCols...)

		return columns
	}

	projectSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(projectSelectColumns(additionalCols...)...).From("project")
	}
)

func (d *DB) InsertOrUpdateProject(tx *sql.Tx, v *types.Project) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertProject(tx, v)
	} else {
		err = d.UpdateProject(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertProject(tx *sql.Tx, v *types.Project) 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.insertRawProjectPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertProjectSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateProject(tx *sql.Tx, v *types.Project) 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.updateProjectPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateProjectSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update project")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	secretSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"secret.id", "secret.revision", "secret.creation_time", "secret.update_time", "secret.name", "secret.parent_kind", "secret.parent_id", "secret.type", "secret.data", "secret.secret_provider_id", "secret.path"}
		columns = append(columns, additionalCols...)

		return columns
	}

	secretSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(secretSelectColumns(additionalCols...)...).From("secret")
	}
)

func (d *DB) InsertOrUpdateSecret(tx *sql.Tx, v *types.Secret) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertSecret(tx, v)
	} else {
		err = d.UpdateSecret(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertSecret(tx *sql.Tx, v *types.Secret) 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.insertRawSecretPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertSecretSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateSecret(tx *sql.Tx, v *types.Secret) 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.updateSecretPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateSecretSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update secret")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	variableSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"variable.id", "variable.revision", "variable.creation_time", "variable.update_time", "variable.name", "variable.parent_kind", "variable.parent_id", "variable.variable_values"}
		columns = append(columns, additionalCols...)

		return columns
	}

	variableSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(variableSelectColumns(additionalCols...)...).From("variable")
	}
)

func (d *DB) InsertOrUpdateVariable(tx *sql.Tx, v *types.Variable) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertVariable(tx, v)
	} else {
		err = d.UpdateVariable(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertVariable(tx *sql.Tx, v *types.Variable) 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.insertRawVariablePostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertVariableSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateVariable(tx *sql.Tx, v *types.Variable) 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.updateVariablePostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateVariableSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update variable")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	return nil
}

var (
	orgInvitationSelectColumns = func(additionalCols ...string) []string {
		columns := []string{"orginvitation.id", "orginvitation.revision", "orginvitation.creation_time", "orginvitation.update_time", "orginvitation.user_id", "orginvitation.organization_id", "orginvitation.role"}
		columns = append(columns, additionalCols...)

		return columns
	}

	orgInvitationSelect = func(additionalCols ...string) *sq.SelectBuilder {
		return sq.NewSelectBuilder().Select(orgInvitationSelectColumns(additionalCols...)...).From("orginvitation")
	}
)

func (d *DB) InsertOrUpdateOrgInvitation(tx *sql.Tx, v *types.OrgInvitation) error {
	var err error
	if v.Revision == 0 {
		err = d.InsertOrgInvitation(tx, v)
	} else {
		err = d.UpdateOrgInvitation(tx, v)
	}

	return errors.WithStack(err)
}

func (d *DB) InsertOrgInvitation(tx *sql.Tx, v *types.OrgInvitation) 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.insertRawOrgInvitationPostgres(tx, v);
	case sql.Sqlite3:
		err = d.insertOrgInvitationSqlite3(tx, v);
	}

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

	return nil
}

func (d *DB) UpdateOrgInvitation(tx *sql.Tx, v *types.OrgInvitation) 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.updateOrgInvitationPostgres(tx, curRevision, v);
	case sql.Sqlite3:
		res, err = d.updateOrgInvitationSqlite3(tx, curRevision, v);
	}
	if err != nil {
		v.Revision = curRevision
		return errors.Wrap(err, "failed to update orginvitation")
	}

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

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

	return nil
}

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

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

	return nil
}

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

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

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

	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 "RemoteSource":
		obj = &types.RemoteSource{}
	case "User":
		obj = &types.User{}
	case "UserToken":
		obj = &types.UserToken{}
	case "LinkedAccount":
		obj = &types.LinkedAccount{}
	case "Organization":
		obj = &types.Organization{}
	case "OrganizationMember":
		obj = &types.OrganizationMember{}
	case "ProjectGroup":
		obj = &types.ProjectGroup{}
	case "Project":
		obj = &types.Project{}
	case "Secret":
		obj = &types.Secret{}
	case "Variable":
		obj = &types.Variable{}
	case "OrgInvitation":
		obj = &types.OrgInvitation{}

	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.RemoteSource:
		return d.insertRawRemoteSource(tx, o)
	case *types.User:
		return d.insertRawUser(tx, o)
	case *types.UserToken:
		return d.insertRawUserToken(tx, o)
	case *types.LinkedAccount:
		return d.insertRawLinkedAccount(tx, o)
	case *types.Organization:
		return d.insertRawOrganization(tx, o)
	case *types.OrganizationMember:
		return d.insertRawOrganizationMember(tx, o)
	case *types.ProjectGroup:
		return d.insertRawProjectGroup(tx, o)
	case *types.Project:
		return d.insertRawProject(tx, o)
	case *types.Secret:
		return d.insertRawSecret(tx, o)
	case *types.Variable:
		return d.insertRawVariable(tx, o)
	case *types.OrgInvitation:
		return d.insertRawOrgInvitation(tx, o)

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

func (d *DB) SelectObject(kind string) *sq.SelectBuilder {
	switch kind {
	case "RemoteSource":
		return remoteSourceSelect()
	case "User":
		return userSelect()
	case "UserToken":
		return userTokenSelect()
	case "LinkedAccount":
		return linkedAccountSelect()
	case "Organization":
		return organizationSelect()
	case "OrganizationMember":
		return organizationMemberSelect()
	case "ProjectGroup":
		return projectGroupSelect()
	case "Project":
		return projectSelect()
	case "Secret":
		return secretSelect()
	case "Variable":
		return variableSelect()
	case "OrgInvitation":
		return orgInvitationSelect()

	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 "RemoteSource":
		fobjs, _, err := d.fetchRemoteSources(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 "User":
		fobjs, _, err := d.fetchUsers(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 "UserToken":
		fobjs, _, err := d.fetchUserTokens(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 "LinkedAccount":
		fobjs, _, err := d.fetchLinkedAccounts(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 "Organization":
		fobjs, _, err := d.fetchOrganizations(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 "OrganizationMember":
		fobjs, _, err := d.fetchOrganizationMembers(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 "ProjectGroup":
		fobjs, _, err := d.fetchProjectGroups(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 "Project":
		fobjs, _, err := d.fetchProjects(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 "Secret":
		fobjs, _, err := d.fetchSecrets(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 "Variable":
		fobjs, _, err := d.fetchVariables(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 "OrgInvitation":
		fobjs, _, err := d.fetchOrgInvitations(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.RemoteSource:
		type exportObject struct {
			ExportMeta sqlg.ExportMeta `json:"exportMeta"`

			*types.RemoteSource
		}

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

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

			*types.User
		}

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

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

			*types.UserToken
		}

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

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

			*types.LinkedAccount
		}

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

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

			*types.Organization
		}

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

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

			*types.OrganizationMember
		}

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

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

			*types.ProjectGroup
		}

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

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

			*types.Project
		}

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

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

			*types.Secret
		}

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

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

			*types.Variable
		}

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

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

			*types.OrgInvitation
		}

		if err := e.Encode(&exportObject{ExportMeta: sqlg.ExportMeta{ Kind: "OrgInvitation" }, OrgInvitation: 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 {

	return nil
}

func (d *DB) populateSequencesSqlite3(tx *sql.Tx) error {

	return nil
}
