{{- $short := (shortname .Name "err" "res" "sqlstr" "db" "XOLog") -}} {{- $table := (schema .Schema .Table.TableName) -}} {{- if .Comment -}} // {{ .Comment }} {{- else -}} // {{ .Name }} represents a row from '{{ $table }}'. {{- end }} type {{ .Name }} struct { {{- range .Fields }} {{ .Name }} {{ retype .Type }} `db:"{{ .Col.ColumnName }}"` // {{ .Col.ColumnName }} {{- end }} {{- if .PrimaryKey }} // xo fields _exists, _deleted bool {{ end }} } {{ if .PrimaryKey }} // Exists determines if the {{ .Name }} exists in the database. func ({{ $short }} *{{ .Name }}) Exists() bool { return {{ $short }}._exists } // Deleted provides information if the {{ .Name }} has been deleted from the database. func ({{ $short }} *{{ .Name }}) Deleted() bool { return {{ $short }}._deleted } // Insert inserts the {{ .Name }} to the database. func ({{ $short }} *{{ .Name }}) Insert(db XODB) error { var err error // if already exist, bail if {{ $short }}._exists { return errors.New("insert failed: already exists") } {{ if .Table.ManualPk }} // sql insert query, primary key must be provided const sqlstr = `INSERT INTO {{ $table }} (` + `{{ colnames .Fields }}` + `) VALUES (` + `{{ colvals .Fields }}` + `)` // run query XOLog(sqlstr, {{ fieldnames .Fields $short }}) err = db.QueryRow(sqlstr, {{ fieldnames .Fields $short }}).Scan(&{{ $short }}.{{ .PrimaryKey.Name }}) if err != nil { return err } {{ else }} // sql insert query, primary key provided by sequence const sqlstr = `INSERT INTO {{ $table }} (` + `{{ colnames .Fields .PrimaryKey.Name }}` + `) VALUES (` + `{{ colvals .Fields .PrimaryKey.Name }}` + `) RETURNING {{ colname .PrimaryKey.Col }}` // run query XOLog(sqlstr, {{ fieldnames .Fields $short .PrimaryKey.Name }}) err = db.QueryRow(sqlstr, {{ fieldnames .Fields $short .PrimaryKey.Name }}).Scan(&{{ $short }}.{{ .PrimaryKey.Name }}) if err != nil { return err } {{ end }} // set existence {{ $short }}._exists = true return nil } {{ if ne (fieldnamesmulti .Fields $short .PrimaryKeyFields) "" }} // Update updates the {{ .Name }} in the database. func ({{ $short }} *{{ .Name }}) Update(db XODB) error { var err error // if doesn't exist, bail if !{{ $short }}._exists { return errors.New("update failed: does not exist") } // if deleted, bail if {{ $short }}._deleted { return errors.New("update failed: marked for deletion") } {{ if gt ( len .PrimaryKeyFields ) 1 }} // sql query with composite primary key const sqlstr = `UPDATE {{ $table }} SET (` + `{{ colnamesmulti .Fields .PrimaryKeyFields }}` + `) = ( ` + `{{ colvalsmulti .Fields .PrimaryKeyFields }}` + `) WHERE {{ colnamesquerymulti .PrimaryKeyFields " AND " (getstartcount .Fields .PrimaryKeyFields) nil }}` // run query XOLog(sqlstr, {{ fieldnamesmulti .Fields $short .PrimaryKeyFields }}, {{ fieldnames .PrimaryKeyFields $short}}) _, err = db.Exec(sqlstr, {{ fieldnamesmulti .Fields $short .PrimaryKeyFields }}, {{ fieldnames .PrimaryKeyFields $short}}) return err {{- else }} // sql query const sqlstr = `UPDATE {{ $table }} SET (` + `{{ colnames .Fields .PrimaryKey.Name }}` + `) = ( ` + `{{ colvals .Fields .PrimaryKey.Name }}` + `) WHERE {{ colname .PrimaryKey.Col }} = ${{ colcount .Fields .PrimaryKey.Name }}` // run query XOLog(sqlstr, {{ fieldnames .Fields $short .PrimaryKey.Name }}, {{ $short }}.{{ .PrimaryKey.Name }}) _, err = db.Exec(sqlstr, {{ fieldnames .Fields $short .PrimaryKey.Name }}, {{ $short }}.{{ .PrimaryKey.Name }}) return err {{- end }} } // Save saves the {{ .Name }} to the database. func ({{ $short }} *{{ .Name }}) Save(db XODB) error { if {{ $short }}.Exists() { return {{ $short }}.Update(db) } return {{ $short }}.Insert(db) } // Upsert performs an upsert for {{ .Name }}. // // NOTE: PostgreSQL 9.5+ only func ({{ $short }} *{{ .Name }}) Upsert(db XODB) error { var err error // if already exist, bail if {{ $short }}._exists { return errors.New("insert failed: already exists") } // sql query const sqlstr = `INSERT INTO {{ $table }} (` + `{{ colnames .Fields }}` + `) VALUES (` + `{{ colvals .Fields }}` + `) ON CONFLICT ({{ colnames .PrimaryKeyFields }}) DO UPDATE SET (` + `{{ colnames .Fields }}` + `) = (` + `{{ colprefixnames .Fields "EXCLUDED" }}` + `)` // run query XOLog(sqlstr, {{ fieldnames .Fields $short }}) _, err = db.Exec(sqlstr, {{ fieldnames .Fields $short }}) if err != nil { return err } // set existence {{ $short }}._exists = true return nil } {{ else }} // Update statements omitted due to lack of fields other than primary key {{ end }} // Delete deletes the {{ .Name }} from the database. func ({{ $short }} *{{ .Name }}) Delete(db XODB) error { var err error // if doesn't exist, bail if !{{ $short }}._exists { return nil } // if deleted, bail if {{ $short }}._deleted { return nil } {{ if gt ( len .PrimaryKeyFields ) 1 }} // sql query with composite primary key const sqlstr = `DELETE FROM {{ $table }} WHERE {{ colnamesquery .PrimaryKeyFields " AND " }}` // run query XOLog(sqlstr, {{ fieldnames .PrimaryKeyFields $short }}) _, err = db.Exec(sqlstr, {{ fieldnames .PrimaryKeyFields $short }}) if err != nil { return err } {{- else }} // sql query const sqlstr = `DELETE FROM {{ $table }} WHERE {{ colname .PrimaryKey.Col }} = $1` // run query XOLog(sqlstr, {{ $short }}.{{ .PrimaryKey.Name }}) _, err = db.Exec(sqlstr, {{ $short }}.{{ .PrimaryKey.Name }}) if err != nil { return err } {{- end }} // set deleted {{ $short }}._deleted = true return nil } {{- end }}