Save information about the organization and user from ArcGIS

This commit is contained in:
Eli Ribble 2025-11-07 02:07:33 +00:00
parent 07d3b3ea76
commit a08cd87813
No known key found for this signature in database
20 changed files with 786 additions and 93 deletions

View file

@ -39,3 +39,14 @@ PSQL_DSN="postgresql://?host=/var/run/postgresql&sslmode=disable&dbname=nidus-sy
``` ```
This will generate a bunch of files. They're already committed, you only need this if you change the database schema in some way. This will generate a bunch of files. They're already committed, you only need this if you change the database schema in some way.
### goose
This uses [goose](https://github.com/pressly/goose). You can use the goose command line to check status and make changes
```sh
> cd migrations
> GOOSE_DRIVER=postgres GOOSE_DBSTRING="dbname=nidus-sync sslmode=disable" goose status
> GOOSE_DRIVER=postgres GOOSE_DBSTRING="dbname=nidus-sync sslmode=disable" goose down
> GOOSE_DRIVER=postgres GOOSE_DBSTRING="dbname=nidus-sync sslmode=disable" goose up
```

@ -1 +1 @@
Subproject commit 5bc087a120a5dab09789b9abe913fd01b735dcff Subproject commit a99b4a72b2bb3dcff642209f029eb4e7d746fa8d

View file

@ -6,6 +6,7 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"log/slog" "log/slog"
@ -19,6 +20,8 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/models" "github.com/Gleipnir-Technology/nidus-sync/models"
"github.com/Gleipnir-Technology/nidus-sync/sql" "github.com/Gleipnir-Technology/nidus-sync/sql"
"github.com/aarondl/opt/omit" "github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/jackc/pgx/v5"
) )
var CodeVerifier string = "random_secure_string_min_43_chars_long_should_be_stored_in_session" var CodeVerifier string = "random_secure_string_min_43_chars_long_should_be_stored_in_session"
@ -63,7 +66,7 @@ func generateCodeVerifier() string {
} }
// Find out what we can about this user // Find out what we can about this user
func getArcgisUserData(access_token string, expires time.Time, refresh_token string) { func updateArcgisUserData(ctx context.Context, user *models.User, access_token string, expires time.Time, refresh_token string) {
client := arcgis.NewArcGIS( client := arcgis.NewArcGIS(
arcgis.AuthenticatorOAuth{ arcgis.AuthenticatorOAuth{
AccessToken: access_token, AccessToken: access_token,
@ -71,15 +74,60 @@ func getArcgisUserData(access_token string, expires time.Time, refresh_token str
RefreshToken: refresh_token, RefreshToken: refresh_token,
}, },
) )
/*portal, err := client.PortalsSelf() portal, err := client.PortalsSelf()
if err != nil { if err != nil {
slog.Error("Failed to get ArcGIS user data", slog.String("err", err.Error())) slog.Error("Failed to get ArcGIS user data", slog.String("err", err.Error()))
return return
} }
slog.Info("Got portals data", slog.Info("Got portals data",
slog.String("Username", portal.User.Username), slog.String("Username", portal.User.Username),
slog.String("ID", portal.ID)) slog.String("user_id", portal.User.ID),
*/ slog.String("org_id", portal.User.OrgID),
slog.String("org_name", portal.Name),
slog.String("license_type_id", portal.User.UserLicenseTypeID))
_, err = sql.UpdateOauthTokenOrg(portal.User.ID, portal.User.UserLicenseTypeID, refresh_token).Exec(ctx, PGInstance.BobDB)
if err != nil {
slog.Error("Failed to update oauth token portal data", slog.String("err", err.Error()))
return
}
var org *models.Organization
orgs, err := models.Organizations.Query(models.SelectWhere.Organizations.ArcgisName.EQ(portal.Name)).All(ctx, PGInstance.BobDB)
switch len(orgs) {
case 0:
setter := models.OrganizationSetter{
Name: omitnull.From(portal.Name),
ArcgisID: omitnull.From(portal.User.OrgID),
ArcgisName: omitnull.From(portal.Name),
}
org, err = models.Organizations.Insert(&setter).One(ctx, PGInstance.BobDB)
if err != nil {
slog.Error("Failed to create new organization", slog.String("err", err.Error()))
return
}
slog.Info("Created new organization", slog.Int("org_id", int(org.ID)))
case 1:
org = orgs[0]
slog.Info("Organization already exists")
default:
slog.Error("Got too many organizations, bailing")
return
}
if err != nil {
LogErrorTypeInfo(err)
if errors.Is(err, pgx.ErrNoRows) {
} else {
slog.Error("Failed to query for existing org", slog.String("err", err.Error()))
return
}
}
err = org.AttachUser(ctx, PGInstance.BobDB, user)
if err != nil {
slog.Error("Failed to attach user to organization", slog.String("err", err.Error()), slog.Int("user_id", int(user.ID)), slog.Int("org_id", int(org.ID)))
return
}
search, err := client.Search("Fieldseeker") search, err := client.Search("Fieldseeker")
if err != nil { if err != nil {
slog.Error("Failed to get search FieldseekerGIS data", slog.String("err", err.Error())) slog.Error("Failed to get search FieldseekerGIS data", slog.String("err", err.Error()))
@ -152,7 +200,7 @@ func handleOauthAccessCode(ctx context.Context, user *models.User, code string)
if err != nil { if err != nil {
return fmt.Errorf("Failed to save token to database: %v", err) return fmt.Errorf("Failed to save token to database: %v", err)
} }
go getArcgisUserData(tokenResponse.AccessToken, expires, tokenResponse.RefreshToken) go updateArcgisUserData(context.Background(), user, tokenResponse.AccessToken, expires, tokenResponse.RefreshToken)
return nil return nil
} }
@ -166,3 +214,7 @@ func hasFieldseekerConnection(ctx context.Context, user *models.User) (bool, err
func redirectURL() string { func redirectURL() string {
return BaseURL + "/arcgis/oauth/callback" return BaseURL + "/arcgis/oauth/callback"
} }
// This is a goroutine that is in charge of getting Fieldseeker data and keeping it fresh.
func refreshFieldseekerData(newOauthCh <-chan int, done <-chan struct{}) {
}

View file

@ -69,6 +69,24 @@ var OauthTokens = Table[
Generated: false, Generated: false,
AutoIncr: false, AutoIncr: false,
}, },
ArcgisID: column{
Name: "arcgis_id",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ArcgisLicenseTypeID: column{
Name: "arcgis_license_type_id",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
}, },
Indexes: oauthTokenIndexes{ Indexes: oauthTokenIndexes{
OauthTokenPkey: index{ OauthTokenPkey: index{
@ -110,17 +128,19 @@ var OauthTokens = Table[
} }
type oauthTokenColumns struct { type oauthTokenColumns struct {
ID column ID column
AccessToken column AccessToken column
Expires column Expires column
RefreshToken column RefreshToken column
Username column Username column
UserID column UserID column
ArcgisID column
ArcgisLicenseTypeID column
} }
func (c oauthTokenColumns) AsSlice() []column { func (c oauthTokenColumns) AsSlice() []column {
return []column{ return []column{
c.ID, c.AccessToken, c.Expires, c.RefreshToken, c.Username, c.UserID, c.ID, c.AccessToken, c.Expires, c.RefreshToken, c.Username, c.UserID, c.ArcgisID, c.ArcgisLicenseTypeID,
} }
} }

View file

@ -33,6 +33,24 @@ var Organizations = Table[
Generated: false, Generated: false,
AutoIncr: false, AutoIncr: false,
}, },
ArcgisID: column{
Name: "arcgis_id",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
ArcgisName: column{
Name: "arcgis_name",
DBType: "text",
Default: "NULL",
Comment: "",
Nullable: true,
Generated: false,
AutoIncr: false,
},
}, },
Indexes: organizationIndexes{ Indexes: organizationIndexes{
OrganizationPkey: index{ OrganizationPkey: index{
@ -63,13 +81,15 @@ var Organizations = Table[
} }
type organizationColumns struct { type organizationColumns struct {
ID column ID column
Name column Name column
ArcgisID column
ArcgisName column
} }
func (c organizationColumns) AsSlice() []column { func (c organizationColumns) AsSlice() []column {
return []column{ return []column{
c.ID, c.Name, c.ID, c.Name, c.ArcgisID, c.ArcgisName,
} }
} }

28
errors.go Normal file
View file

@ -0,0 +1,28 @@
package main
import (
"errors"
"log/slog"
"reflect"
)
func LogErrorTypeInfo(err error) {
if err == nil {
slog.Info("Error is nil")
return
}
// Log current error type
errType := reflect.TypeOf(err)
slog.Info("Error type info",
"type", errType.String(),
"pkgPath", errType.PkgPath(),
"error", err.Error())
// Recursively log wrapped errors
wrappedErr := errors.Unwrap(err)
if wrappedErr != nil {
slog.Info("Contains wrapped error")
LogErrorTypeInfo(wrappedErr)
}
}

View file

@ -76,6 +76,8 @@ func (f *Factory) FromExistingOauthToken(m *models.OauthToken) *OauthTokenTempla
o.RefreshToken = func() string { return m.RefreshToken } o.RefreshToken = func() string { return m.RefreshToken }
o.Username = func() string { return m.Username } o.Username = func() string { return m.Username }
o.UserID = func() int32 { return m.UserID } o.UserID = func() int32 { return m.UserID }
o.ArcgisID = func() null.Val[string] { return m.ArcgisID }
o.ArcgisLicenseTypeID = func() null.Val[string] { return m.ArcgisLicenseTypeID }
ctx := context.Background() ctx := context.Background()
if m.R.UserUser != nil { if m.R.UserUser != nil {
@ -106,6 +108,8 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization
o.ID = func() int32 { return m.ID } o.ID = func() int32 { return m.ID }
o.Name = func() null.Val[string] { return m.Name } o.Name = func() null.Val[string] { return m.Name }
o.ArcgisID = func() null.Val[string] { return m.ArcgisID }
o.ArcgisName = func() null.Val[string] { return m.ArcgisName }
ctx := context.Background() ctx := context.Background()
if len(m.R.User) > 0 { if len(m.R.User) > 0 {

View file

@ -9,7 +9,9 @@ import (
"time" "time"
models "github.com/Gleipnir-Technology/nidus-sync/models" models "github.com/Gleipnir-Technology/nidus-sync/models"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit" "github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/jaswdr/faker/v2" "github.com/jaswdr/faker/v2"
"github.com/stephenafamo/bob" "github.com/stephenafamo/bob"
) )
@ -35,12 +37,14 @@ func (mods OauthTokenModSlice) Apply(ctx context.Context, n *OauthTokenTemplate)
// OauthTokenTemplate is an object representing the database table. // OauthTokenTemplate is an object representing the database table.
// all columns are optional and should be set by mods // all columns are optional and should be set by mods
type OauthTokenTemplate struct { type OauthTokenTemplate struct {
ID func() int32 ID func() int32
AccessToken func() string AccessToken func() string
Expires func() time.Time Expires func() time.Time
RefreshToken func() string RefreshToken func() string
Username func() string Username func() string
UserID func() int32 UserID func() int32
ArcgisID func() null.Val[string]
ArcgisLicenseTypeID func() null.Val[string]
r oauthTokenR r oauthTokenR
f *Factory f *Factory
@ -103,6 +107,14 @@ func (o OauthTokenTemplate) BuildSetter() *models.OauthTokenSetter {
val := o.UserID() val := o.UserID()
m.UserID = omit.From(val) m.UserID = omit.From(val)
} }
if o.ArcgisID != nil {
val := o.ArcgisID()
m.ArcgisID = omitnull.FromNull(val)
}
if o.ArcgisLicenseTypeID != nil {
val := o.ArcgisLicenseTypeID()
m.ArcgisLicenseTypeID = omitnull.FromNull(val)
}
return m return m
} }
@ -143,6 +155,12 @@ func (o OauthTokenTemplate) Build() *models.OauthToken {
if o.UserID != nil { if o.UserID != nil {
m.UserID = o.UserID() m.UserID = o.UserID()
} }
if o.ArcgisID != nil {
m.ArcgisID = o.ArcgisID()
}
if o.ArcgisLicenseTypeID != nil {
m.ArcgisLicenseTypeID = o.ArcgisLicenseTypeID()
}
o.setModelRels(m) o.setModelRels(m)
@ -308,6 +326,8 @@ func (m oauthTokenMods) RandomizeAllColumns(f *faker.Faker) OauthTokenMod {
OauthTokenMods.RandomRefreshToken(f), OauthTokenMods.RandomRefreshToken(f),
OauthTokenMods.RandomUsername(f), OauthTokenMods.RandomUsername(f),
OauthTokenMods.RandomUserID(f), OauthTokenMods.RandomUserID(f),
OauthTokenMods.RandomArcgisID(f),
OauthTokenMods.RandomArcgisLicenseTypeID(f),
} }
} }
@ -497,6 +517,112 @@ func (m oauthTokenMods) RandomUserID(f *faker.Faker) OauthTokenMod {
}) })
} }
// Set the model columns to this value
func (m oauthTokenMods) ArcgisID(val null.Val[string]) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisID = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m oauthTokenMods) ArcgisIDFunc(f func() null.Val[string]) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisID = f
})
}
// Clear any values for the column
func (m oauthTokenMods) UnsetArcgisID() OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m oauthTokenMods) RandomArcgisID(f *faker.Faker) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisID = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m oauthTokenMods) RandomArcgisIDNotNull(f *faker.Faker) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisID = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m oauthTokenMods) ArcgisLicenseTypeID(val null.Val[string]) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisLicenseTypeID = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m oauthTokenMods) ArcgisLicenseTypeIDFunc(f func() null.Val[string]) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisLicenseTypeID = f
})
}
// Clear any values for the column
func (m oauthTokenMods) UnsetArcgisLicenseTypeID() OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisLicenseTypeID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m oauthTokenMods) RandomArcgisLicenseTypeID(f *faker.Faker) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisLicenseTypeID = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m oauthTokenMods) RandomArcgisLicenseTypeIDNotNull(f *faker.Faker) OauthTokenMod {
return OauthTokenModFunc(func(_ context.Context, o *OauthTokenTemplate) {
o.ArcgisLicenseTypeID = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
func (m oauthTokenMods) WithParentsCascading() OauthTokenMod { func (m oauthTokenMods) WithParentsCascading() OauthTokenMod {
return OauthTokenModFunc(func(ctx context.Context, o *OauthTokenTemplate) { return OauthTokenModFunc(func(ctx context.Context, o *OauthTokenTemplate) {
if isDone, _ := oauthTokenWithParentsCascadingCtx.Value(ctx); isDone { if isDone, _ := oauthTokenWithParentsCascadingCtx.Value(ctx); isDone {

View file

@ -36,8 +36,10 @@ func (mods OrganizationModSlice) Apply(ctx context.Context, n *OrganizationTempl
// OrganizationTemplate is an object representing the database table. // OrganizationTemplate is an object representing the database table.
// all columns are optional and should be set by mods // all columns are optional and should be set by mods
type OrganizationTemplate struct { type OrganizationTemplate struct {
ID func() int32 ID func() int32
Name func() null.Val[string] Name func() null.Val[string]
ArcgisID func() null.Val[string]
ArcgisName func() null.Val[string]
r organizationR r organizationR
f *Factory f *Factory
@ -91,6 +93,14 @@ func (o OrganizationTemplate) BuildSetter() *models.OrganizationSetter {
val := o.Name() val := o.Name()
m.Name = omitnull.FromNull(val) m.Name = omitnull.FromNull(val)
} }
if o.ArcgisID != nil {
val := o.ArcgisID()
m.ArcgisID = omitnull.FromNull(val)
}
if o.ArcgisName != nil {
val := o.ArcgisName()
m.ArcgisName = omitnull.FromNull(val)
}
return m return m
} }
@ -119,6 +129,12 @@ func (o OrganizationTemplate) Build() *models.Organization {
if o.Name != nil { if o.Name != nil {
m.Name = o.Name() m.Name = o.Name()
} }
if o.ArcgisID != nil {
m.ArcgisID = o.ArcgisID()
}
if o.ArcgisName != nil {
m.ArcgisName = o.ArcgisName()
}
o.setModelRels(m) o.setModelRels(m)
@ -261,6 +277,8 @@ func (m organizationMods) RandomizeAllColumns(f *faker.Faker) OrganizationMod {
return OrganizationModSlice{ return OrganizationModSlice{
OrganizationMods.RandomID(f), OrganizationMods.RandomID(f),
OrganizationMods.RandomName(f), OrganizationMods.RandomName(f),
OrganizationMods.RandomArcgisID(f),
OrganizationMods.RandomArcgisName(f),
} }
} }
@ -348,6 +366,112 @@ func (m organizationMods) RandomNameNotNull(f *faker.Faker) OrganizationMod {
}) })
} }
// Set the model columns to this value
func (m organizationMods) ArcgisID(val null.Val[string]) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisID = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m organizationMods) ArcgisIDFunc(f func() null.Val[string]) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisID = f
})
}
// Clear any values for the column
func (m organizationMods) UnsetArcgisID() OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisID = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m organizationMods) RandomArcgisID(f *faker.Faker) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisID = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m organizationMods) RandomArcgisIDNotNull(f *faker.Faker) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisID = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Set the model columns to this value
func (m organizationMods) ArcgisName(val null.Val[string]) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisName = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m organizationMods) ArcgisNameFunc(f func() null.Val[string]) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisName = f
})
}
// Clear any values for the column
func (m organizationMods) UnsetArcgisName() OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisName = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m organizationMods) RandomArcgisName(f *faker.Faker) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisName = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m organizationMods) RandomArcgisNameNotNull(f *faker.Faker) OrganizationMod {
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
o.ArcgisName = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
func (m organizationMods) WithParentsCascading() OrganizationMod { func (m organizationMods) WithParentsCascading() OrganizationMod {
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) { return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
if isDone, _ := organizationWithParentsCascadingCtx.Value(ctx); isDone { if isDone, _ := organizationWithParentsCascadingCtx.Value(ctx); isDone {

View file

@ -76,6 +76,9 @@ func main() {
localFS := http.Dir("./static") localFS := http.Dir("./static")
FileServer(r, "/static", localFS, embeddedStaticFS, "static") FileServer(r, "/static", localFS, embeddedStaticFS, "static")
newTokenChannel := make(chan int)
endChannel := make(chan struct{})
go refreshFieldseekerData(newTokenChannel, endChannel)
log.Printf("Serving on %s", bind) log.Printf("Serving on %s", bind)
log.Fatal(http.ListenAndServe(bind, r)) log.Fatal(http.ListenAndServe(bind, r))
} }

View file

@ -0,0 +1,10 @@
-- +goose Up
ALTER TABLE organization ADD COLUMN arcgis_id TEXT;
ALTER TABLE organization ADD COLUMN arcgis_name TEXT;
ALTER TABLE oauth_token ADD COLUMN arcgis_id TEXT;
ALTER TABLE oauth_token ADD COLUMN arcgis_license_type_id TEXT;
-- +goose Down
ALTER TABLE organization DROP COLUMN arcgis_id;
ALTER TABLE organization DROP COLUMN arcgis_name;
ALTER TABLE oauth_token DROP COLUMN arcgis_id;
ALTER TABLE oauth_token DROP COLUMN arcgis_license_type_id;

View file

@ -9,7 +9,9 @@ import (
"io" "io"
"time" "time"
"github.com/aarondl/opt/null"
"github.com/aarondl/opt/omit" "github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/stephenafamo/bob" "github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql" "github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect" "github.com/stephenafamo/bob/dialect/psql/dialect"
@ -24,12 +26,14 @@ import (
// OauthToken is an object representing the database table. // OauthToken is an object representing the database table.
type OauthToken struct { type OauthToken struct {
ID int32 `db:"id,pk" ` ID int32 `db:"id,pk" `
AccessToken string `db:"access_token" ` AccessToken string `db:"access_token" `
Expires time.Time `db:"expires" ` Expires time.Time `db:"expires" `
RefreshToken string `db:"refresh_token" ` RefreshToken string `db:"refresh_token" `
Username string `db:"username" ` Username string `db:"username" `
UserID int32 `db:"user_id" ` UserID int32 `db:"user_id" `
ArcgisID null.Val[string] `db:"arcgis_id" `
ArcgisLicenseTypeID null.Val[string] `db:"arcgis_license_type_id" `
R oauthTokenR `db:"-" ` R oauthTokenR `db:"-" `
} }
@ -52,27 +56,31 @@ type oauthTokenR struct {
func buildOauthTokenColumns(alias string) oauthTokenColumns { func buildOauthTokenColumns(alias string) oauthTokenColumns {
return oauthTokenColumns{ return oauthTokenColumns{
ColumnsExpr: expr.NewColumnsExpr( ColumnsExpr: expr.NewColumnsExpr(
"id", "access_token", "expires", "refresh_token", "username", "user_id", "id", "access_token", "expires", "refresh_token", "username", "user_id", "arcgis_id", "arcgis_license_type_id",
).WithParent("oauth_token"), ).WithParent("oauth_token"),
tableAlias: alias, tableAlias: alias,
ID: psql.Quote(alias, "id"), ID: psql.Quote(alias, "id"),
AccessToken: psql.Quote(alias, "access_token"), AccessToken: psql.Quote(alias, "access_token"),
Expires: psql.Quote(alias, "expires"), Expires: psql.Quote(alias, "expires"),
RefreshToken: psql.Quote(alias, "refresh_token"), RefreshToken: psql.Quote(alias, "refresh_token"),
Username: psql.Quote(alias, "username"), Username: psql.Quote(alias, "username"),
UserID: psql.Quote(alias, "user_id"), UserID: psql.Quote(alias, "user_id"),
ArcgisID: psql.Quote(alias, "arcgis_id"),
ArcgisLicenseTypeID: psql.Quote(alias, "arcgis_license_type_id"),
} }
} }
type oauthTokenColumns struct { type oauthTokenColumns struct {
expr.ColumnsExpr expr.ColumnsExpr
tableAlias string tableAlias string
ID psql.Expression ID psql.Expression
AccessToken psql.Expression AccessToken psql.Expression
Expires psql.Expression Expires psql.Expression
RefreshToken psql.Expression RefreshToken psql.Expression
Username psql.Expression Username psql.Expression
UserID psql.Expression UserID psql.Expression
ArcgisID psql.Expression
ArcgisLicenseTypeID psql.Expression
} }
func (c oauthTokenColumns) Alias() string { func (c oauthTokenColumns) Alias() string {
@ -87,16 +95,18 @@ func (oauthTokenColumns) AliasedAs(alias string) oauthTokenColumns {
// All values are optional, and do not have to be set // All values are optional, and do not have to be set
// Generated columns are not included // Generated columns are not included
type OauthTokenSetter struct { type OauthTokenSetter struct {
ID omit.Val[int32] `db:"id,pk" ` ID omit.Val[int32] `db:"id,pk" `
AccessToken omit.Val[string] `db:"access_token" ` AccessToken omit.Val[string] `db:"access_token" `
Expires omit.Val[time.Time] `db:"expires" ` Expires omit.Val[time.Time] `db:"expires" `
RefreshToken omit.Val[string] `db:"refresh_token" ` RefreshToken omit.Val[string] `db:"refresh_token" `
Username omit.Val[string] `db:"username" ` Username omit.Val[string] `db:"username" `
UserID omit.Val[int32] `db:"user_id" ` UserID omit.Val[int32] `db:"user_id" `
ArcgisID omitnull.Val[string] `db:"arcgis_id" `
ArcgisLicenseTypeID omitnull.Val[string] `db:"arcgis_license_type_id" `
} }
func (s OauthTokenSetter) SetColumns() []string { func (s OauthTokenSetter) SetColumns() []string {
vals := make([]string, 0, 6) vals := make([]string, 0, 8)
if s.ID.IsValue() { if s.ID.IsValue() {
vals = append(vals, "id") vals = append(vals, "id")
} }
@ -115,6 +125,12 @@ func (s OauthTokenSetter) SetColumns() []string {
if s.UserID.IsValue() { if s.UserID.IsValue() {
vals = append(vals, "user_id") vals = append(vals, "user_id")
} }
if !s.ArcgisID.IsUnset() {
vals = append(vals, "arcgis_id")
}
if !s.ArcgisLicenseTypeID.IsUnset() {
vals = append(vals, "arcgis_license_type_id")
}
return vals return vals
} }
@ -137,6 +153,12 @@ func (s OauthTokenSetter) Overwrite(t *OauthToken) {
if s.UserID.IsValue() { if s.UserID.IsValue() {
t.UserID = s.UserID.MustGet() t.UserID = s.UserID.MustGet()
} }
if !s.ArcgisID.IsUnset() {
t.ArcgisID = s.ArcgisID.MustGetNull()
}
if !s.ArcgisLicenseTypeID.IsUnset() {
t.ArcgisLicenseTypeID = s.ArcgisLicenseTypeID.MustGetNull()
}
} }
func (s *OauthTokenSetter) Apply(q *dialect.InsertQuery) { func (s *OauthTokenSetter) Apply(q *dialect.InsertQuery) {
@ -145,7 +167,7 @@ func (s *OauthTokenSetter) Apply(q *dialect.InsertQuery) {
}) })
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) { q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
vals := make([]bob.Expression, 6) vals := make([]bob.Expression, 8)
if s.ID.IsValue() { if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet()) vals[0] = psql.Arg(s.ID.MustGet())
} else { } else {
@ -182,6 +204,18 @@ func (s *OauthTokenSetter) Apply(q *dialect.InsertQuery) {
vals[5] = psql.Raw("DEFAULT") vals[5] = psql.Raw("DEFAULT")
} }
if !s.ArcgisID.IsUnset() {
vals[6] = psql.Arg(s.ArcgisID.MustGetNull())
} else {
vals[6] = psql.Raw("DEFAULT")
}
if !s.ArcgisLicenseTypeID.IsUnset() {
vals[7] = psql.Arg(s.ArcgisLicenseTypeID.MustGetNull())
} else {
vals[7] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
})) }))
} }
@ -191,7 +225,7 @@ func (s OauthTokenSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
} }
func (s OauthTokenSetter) Expressions(prefix ...string) []bob.Expression { func (s OauthTokenSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 6) exprs := make([]bob.Expression, 0, 8)
if s.ID.IsValue() { if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -235,6 +269,20 @@ func (s OauthTokenSetter) Expressions(prefix ...string) []bob.Expression {
}}) }})
} }
if !s.ArcgisID.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "arcgis_id")...),
psql.Arg(s.ArcgisID),
}})
}
if !s.ArcgisLicenseTypeID.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "arcgis_license_type_id")...),
psql.Arg(s.ArcgisLicenseTypeID),
}})
}
return exprs return exprs
} }
@ -534,12 +582,14 @@ func (oauthToken0 *OauthToken) AttachUserUser(ctx context.Context, exec bob.Exec
} }
type oauthTokenWhere[Q psql.Filterable] struct { type oauthTokenWhere[Q psql.Filterable] struct {
ID psql.WhereMod[Q, int32] ID psql.WhereMod[Q, int32]
AccessToken psql.WhereMod[Q, string] AccessToken psql.WhereMod[Q, string]
Expires psql.WhereMod[Q, time.Time] Expires psql.WhereMod[Q, time.Time]
RefreshToken psql.WhereMod[Q, string] RefreshToken psql.WhereMod[Q, string]
Username psql.WhereMod[Q, string] Username psql.WhereMod[Q, string]
UserID psql.WhereMod[Q, int32] UserID psql.WhereMod[Q, int32]
ArcgisID psql.WhereNullMod[Q, string]
ArcgisLicenseTypeID psql.WhereNullMod[Q, string]
} }
func (oauthTokenWhere[Q]) AliasedAs(alias string) oauthTokenWhere[Q] { func (oauthTokenWhere[Q]) AliasedAs(alias string) oauthTokenWhere[Q] {
@ -548,12 +598,14 @@ func (oauthTokenWhere[Q]) AliasedAs(alias string) oauthTokenWhere[Q] {
func buildOauthTokenWhere[Q psql.Filterable](cols oauthTokenColumns) oauthTokenWhere[Q] { func buildOauthTokenWhere[Q psql.Filterable](cols oauthTokenColumns) oauthTokenWhere[Q] {
return oauthTokenWhere[Q]{ return oauthTokenWhere[Q]{
ID: psql.Where[Q, int32](cols.ID), ID: psql.Where[Q, int32](cols.ID),
AccessToken: psql.Where[Q, string](cols.AccessToken), AccessToken: psql.Where[Q, string](cols.AccessToken),
Expires: psql.Where[Q, time.Time](cols.Expires), Expires: psql.Where[Q, time.Time](cols.Expires),
RefreshToken: psql.Where[Q, string](cols.RefreshToken), RefreshToken: psql.Where[Q, string](cols.RefreshToken),
Username: psql.Where[Q, string](cols.Username), Username: psql.Where[Q, string](cols.Username),
UserID: psql.Where[Q, int32](cols.UserID), UserID: psql.Where[Q, int32](cols.UserID),
ArcgisID: psql.WhereNull[Q, string](cols.ArcgisID),
ArcgisLicenseTypeID: psql.WhereNull[Q, string](cols.ArcgisLicenseTypeID),
} }
} }

View file

@ -25,8 +25,10 @@ import (
// Organization is an object representing the database table. // Organization is an object representing the database table.
type Organization struct { type Organization struct {
ID int32 `db:"id,pk" ` ID int32 `db:"id,pk" `
Name null.Val[string] `db:"name" ` Name null.Val[string] `db:"name" `
ArcgisID null.Val[string] `db:"arcgis_id" `
ArcgisName null.Val[string] `db:"arcgis_name" `
R organizationR `db:"-" ` R organizationR `db:"-" `
} }
@ -49,11 +51,13 @@ type organizationR struct {
func buildOrganizationColumns(alias string) organizationColumns { func buildOrganizationColumns(alias string) organizationColumns {
return organizationColumns{ return organizationColumns{
ColumnsExpr: expr.NewColumnsExpr( ColumnsExpr: expr.NewColumnsExpr(
"id", "name", "id", "name", "arcgis_id", "arcgis_name",
).WithParent("organization"), ).WithParent("organization"),
tableAlias: alias, tableAlias: alias,
ID: psql.Quote(alias, "id"), ID: psql.Quote(alias, "id"),
Name: psql.Quote(alias, "name"), Name: psql.Quote(alias, "name"),
ArcgisID: psql.Quote(alias, "arcgis_id"),
ArcgisName: psql.Quote(alias, "arcgis_name"),
} }
} }
@ -62,6 +66,8 @@ type organizationColumns struct {
tableAlias string tableAlias string
ID psql.Expression ID psql.Expression
Name psql.Expression Name psql.Expression
ArcgisID psql.Expression
ArcgisName psql.Expression
} }
func (c organizationColumns) Alias() string { func (c organizationColumns) Alias() string {
@ -76,18 +82,26 @@ func (organizationColumns) AliasedAs(alias string) organizationColumns {
// All values are optional, and do not have to be set // All values are optional, and do not have to be set
// Generated columns are not included // Generated columns are not included
type OrganizationSetter struct { type OrganizationSetter struct {
ID omit.Val[int32] `db:"id,pk" ` ID omit.Val[int32] `db:"id,pk" `
Name omitnull.Val[string] `db:"name" ` Name omitnull.Val[string] `db:"name" `
ArcgisID omitnull.Val[string] `db:"arcgis_id" `
ArcgisName omitnull.Val[string] `db:"arcgis_name" `
} }
func (s OrganizationSetter) SetColumns() []string { func (s OrganizationSetter) SetColumns() []string {
vals := make([]string, 0, 2) vals := make([]string, 0, 4)
if s.ID.IsValue() { if s.ID.IsValue() {
vals = append(vals, "id") vals = append(vals, "id")
} }
if !s.Name.IsUnset() { if !s.Name.IsUnset() {
vals = append(vals, "name") vals = append(vals, "name")
} }
if !s.ArcgisID.IsUnset() {
vals = append(vals, "arcgis_id")
}
if !s.ArcgisName.IsUnset() {
vals = append(vals, "arcgis_name")
}
return vals return vals
} }
@ -98,6 +112,12 @@ func (s OrganizationSetter) Overwrite(t *Organization) {
if !s.Name.IsUnset() { if !s.Name.IsUnset() {
t.Name = s.Name.MustGetNull() t.Name = s.Name.MustGetNull()
} }
if !s.ArcgisID.IsUnset() {
t.ArcgisID = s.ArcgisID.MustGetNull()
}
if !s.ArcgisName.IsUnset() {
t.ArcgisName = s.ArcgisName.MustGetNull()
}
} }
func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) { func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) {
@ -106,7 +126,7 @@ func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) {
}) })
q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) { q.AppendValues(bob.ExpressionFunc(func(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
vals := make([]bob.Expression, 2) vals := make([]bob.Expression, 4)
if s.ID.IsValue() { if s.ID.IsValue() {
vals[0] = psql.Arg(s.ID.MustGet()) vals[0] = psql.Arg(s.ID.MustGet())
} else { } else {
@ -119,6 +139,18 @@ func (s *OrganizationSetter) Apply(q *dialect.InsertQuery) {
vals[1] = psql.Raw("DEFAULT") vals[1] = psql.Raw("DEFAULT")
} }
if !s.ArcgisID.IsUnset() {
vals[2] = psql.Arg(s.ArcgisID.MustGetNull())
} else {
vals[2] = psql.Raw("DEFAULT")
}
if !s.ArcgisName.IsUnset() {
vals[3] = psql.Arg(s.ArcgisName.MustGetNull())
} else {
vals[3] = psql.Raw("DEFAULT")
}
return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "") return bob.ExpressSlice(ctx, w, d, start, vals, "", ", ", "")
})) }))
} }
@ -128,7 +160,7 @@ func (s OrganizationSetter) UpdateMod() bob.Mod[*dialect.UpdateQuery] {
} }
func (s OrganizationSetter) Expressions(prefix ...string) []bob.Expression { func (s OrganizationSetter) Expressions(prefix ...string) []bob.Expression {
exprs := make([]bob.Expression, 0, 2) exprs := make([]bob.Expression, 0, 4)
if s.ID.IsValue() { if s.ID.IsValue() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{ exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
@ -144,6 +176,20 @@ func (s OrganizationSetter) Expressions(prefix ...string) []bob.Expression {
}}) }})
} }
if !s.ArcgisID.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "arcgis_id")...),
psql.Arg(s.ArcgisID),
}})
}
if !s.ArcgisName.IsUnset() {
exprs = append(exprs, expr.Join{Sep: " = ", Exprs: []bob.Expression{
psql.Quote(append(prefix, "arcgis_name")...),
psql.Arg(s.ArcgisName),
}})
}
return exprs return exprs
} }
@ -463,8 +509,10 @@ func (organization0 *Organization) AttachUser(ctx context.Context, exec bob.Exec
} }
type organizationWhere[Q psql.Filterable] struct { type organizationWhere[Q psql.Filterable] struct {
ID psql.WhereMod[Q, int32] ID psql.WhereMod[Q, int32]
Name psql.WhereNullMod[Q, string] Name psql.WhereNullMod[Q, string]
ArcgisID psql.WhereNullMod[Q, string]
ArcgisName psql.WhereNullMod[Q, string]
} }
func (organizationWhere[Q]) AliasedAs(alias string) organizationWhere[Q] { func (organizationWhere[Q]) AliasedAs(alias string) organizationWhere[Q] {
@ -473,8 +521,10 @@ func (organizationWhere[Q]) AliasedAs(alias string) organizationWhere[Q] {
func buildOrganizationWhere[Q psql.Filterable](cols organizationColumns) organizationWhere[Q] { func buildOrganizationWhere[Q psql.Filterable](cols organizationColumns) organizationWhere[Q] {
return organizationWhere[Q]{ return organizationWhere[Q]{
ID: psql.Where[Q, int32](cols.ID), ID: psql.Where[Q, int32](cols.ID),
Name: psql.WhereNull[Q, string](cols.Name), Name: psql.WhereNull[Q, string](cols.Name),
ArcgisID: psql.WhereNull[Q, string](cols.ArcgisID),
ArcgisName: psql.WhereNull[Q, string](cols.ArcgisName),
} }
} }

View file

@ -10,6 +10,7 @@ import (
"iter" "iter"
"time" "time"
"github.com/aarondl/opt/null"
"github.com/stephenafamo/bob" "github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql" "github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect" "github.com/stephenafamo/bob/dialect/psql/dialect"
@ -20,7 +21,7 @@ import (
//go:embed oauth_by_user_id.bob.sql //go:embed oauth_by_user_id.bob.sql
var formattedQueries_oauth_by_user_id string var formattedQueries_oauth_by_user_id string
var oauthTokenByUserIdSQL = formattedQueries_oauth_by_user_id[156:440] var oauthTokenByUserIdSQL = formattedQueries_oauth_by_user_id[156:550]
type OauthTokenByUserIdQuery = orm.ModQuery[*dialect.SelectQuery, oauthTokenByUserId, OauthTokenByUserIdRow, []OauthTokenByUserIdRow, oauthTokenByUserIdTransformer] type OauthTokenByUserIdQuery = orm.ModQuery[*dialect.SelectQuery, oauthTokenByUserId, OauthTokenByUserIdRow, []OauthTokenByUserIdRow, oauthTokenByUserIdTransformer]
@ -47,6 +48,8 @@ func OauthTokenByUserId(UserID int32) *OauthTokenByUserIdQuery {
row.ScheduleScanByIndex(3, &t.RefreshToken) row.ScheduleScanByIndex(3, &t.RefreshToken)
row.ScheduleScanByIndex(4, &t.Username) row.ScheduleScanByIndex(4, &t.Username)
row.ScheduleScanByIndex(5, &t.UserID) row.ScheduleScanByIndex(5, &t.UserID)
row.ScheduleScanByIndex(6, &t.ArcgisID)
row.ScheduleScanByIndex(7, &t.ArcgisLicenseTypeID)
return &t, nil return &t, nil
}, func(v any) (OauthTokenByUserIdRow, error) { }, func(v any) (OauthTokenByUserIdRow, error) {
return *(v.(*OauthTokenByUserIdRow)), nil return *(v.(*OauthTokenByUserIdRow)), nil
@ -54,20 +57,22 @@ func OauthTokenByUserId(UserID int32) *OauthTokenByUserIdQuery {
}, },
}, },
Mod: bob.ModFunc[*dialect.SelectQuery](func(q *dialect.SelectQuery) { Mod: bob.ModFunc[*dialect.SelectQuery](func(q *dialect.SelectQuery) {
q.AppendSelect(expressionTypArgs.subExpr(7, 247)) q.AppendSelect(expressionTypArgs.subExpr(7, 357))
q.SetTable(expressionTypArgs.subExpr(253, 264)) q.SetTable(expressionTypArgs.subExpr(363, 374))
q.AppendWhere(expressionTypArgs.subExpr(272, 284)) q.AppendWhere(expressionTypArgs.subExpr(382, 394))
}), }),
} }
} }
type OauthTokenByUserIdRow = struct { type OauthTokenByUserIdRow = struct {
ID int32 `db:"id"` ID int32 `db:"id"`
AccessToken string `db:"access_token"` AccessToken string `db:"access_token"`
Expires time.Time `db:"expires"` Expires time.Time `db:"expires"`
RefreshToken string `db:"refresh_token"` RefreshToken string `db:"refresh_token"`
Username string `db:"username"` Username string `db:"username"`
UserID int32 `db:"user_id"` UserID int32 `db:"user_id"`
ArcgisID null.Val[string] `db:"arcgis_id"`
ArcgisLicenseTypeID null.Val[string] `db:"arcgis_license_type_id"`
} }
type oauthTokenByUserIdTransformer = bob.SliceTransformer[OauthTokenByUserIdRow, []OauthTokenByUserIdRow] type oauthTokenByUserIdTransformer = bob.SliceTransformer[OauthTokenByUserIdRow, []OauthTokenByUserIdRow]
@ -80,8 +85,8 @@ func (o oauthTokenByUserId) args() iter.Seq[orm.ArgWithPosition] {
return func(yield func(arg orm.ArgWithPosition) bool) { return func(yield func(arg orm.ArgWithPosition) bool) {
if !yield(orm.ArgWithPosition{ if !yield(orm.ArgWithPosition{
Name: "userID", Name: "userID",
Start: 282, Start: 392,
Stop: 284, Stop: 394,
Expression: o.UserID, Expression: o.UserID,
}) { }) {
return return

View file

@ -2,5 +2,5 @@
-- This file is meant to be re-generated in place and/or deleted at any time. -- This file is meant to be re-generated in place and/or deleted at any time.
-- OauthTokenByUserId -- OauthTokenByUserId
SELECT "oauth_token"."id" AS "id", "oauth_token"."access_token" AS "access_token", "oauth_token"."expires" AS "expires", "oauth_token"."refresh_token" AS "refresh_token", "oauth_token"."username" AS "username", "oauth_token"."user_id" AS "user_id" FROM oauth_token WHERE SELECT "oauth_token"."id" AS "id", "oauth_token"."access_token" AS "access_token", "oauth_token"."expires" AS "expires", "oauth_token"."refresh_token" AS "refresh_token", "oauth_token"."username" AS "username", "oauth_token"."user_id" AS "user_id", "oauth_token"."arcgis_id" AS "arcgis_id", "oauth_token"."arcgis_license_type_id" AS "arcgis_license_type_id" FROM oauth_token WHERE
user_id = $1; user_id = $1;

View file

@ -84,8 +84,8 @@ func TestOauthTokenByUserId(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if len(columns) != 6 { if len(columns) != 8 {
t.Fatalf("expected %d columns, got %d", 6, len(columns)) t.Fatalf("expected %d columns, got %d", 8, len(columns))
} }
if columns[0] != "id" { if columns[0] != "id" {
@ -111,5 +111,13 @@ func TestOauthTokenByUserId(t *testing.T) {
if columns[5] != "user_id" { if columns[5] != "user_id" {
t.Fatalf("expected column %d to be %s, got %s", 5, "user_id", columns[5]) t.Fatalf("expected column %d to be %s, got %s", 5, "user_id", columns[5])
} }
if columns[6] != "arcgis_id" {
t.Fatalf("expected column %d to be %s, got %s", 6, "arcgis_id", columns[6])
}
if columns[7] != "arcgis_license_type_id" {
t.Fatalf("expected column %d to be %s, got %s", 7, "arcgis_license_type_id", columns[7])
}
}) })
} }

View file

@ -0,0 +1,95 @@
// Code generated by BobGen psql v0.41.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package sql
import (
"context"
_ "embed"
"io"
"iter"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
"github.com/stephenafamo/bob/dialect/psql/dialect"
"github.com/stephenafamo/bob/orm"
)
//go:embed update_oauth_org.bob.sql
var formattedQueries_update_oauth_org string
var updateOauthTokenOrgSQL = formattedQueries_update_oauth_org[157:249]
type UpdateOauthTokenOrgQuery = orm.ModExecQuery[*dialect.UpdateQuery, updateOauthTokenOrg]
func UpdateOauthTokenOrg(ArcgisID string, ArcgisLicenseTypeID string, RefreshToken string) *UpdateOauthTokenOrgQuery {
var expressionTypArgs updateOauthTokenOrg
expressionTypArgs.ArcgisID = psql.Arg(ArcgisID)
expressionTypArgs.ArcgisLicenseTypeID = psql.Arg(ArcgisLicenseTypeID)
expressionTypArgs.RefreshToken = psql.Arg(RefreshToken)
return &UpdateOauthTokenOrgQuery{
ExecQuery: orm.ExecQuery[updateOauthTokenOrg]{
BaseQuery: bob.BaseQuery[updateOauthTokenOrg]{
Expression: expressionTypArgs,
Dialect: dialect.Dialect,
QueryType: bob.QueryTypeUpdate,
},
},
Mod: bob.ModFunc[*dialect.UpdateQuery](func(q *dialect.UpdateQuery) {
q.Table.Expression = expressionTypArgs.subExpr(7, 18)
q.AppendSet(expressionTypArgs.subExpr(23, 66))
q.AppendWhere(expressionTypArgs.subExpr(74, 92))
}),
}
}
type updateOauthTokenOrg struct {
ArcgisID bob.Expression
ArcgisLicenseTypeID bob.Expression
RefreshToken bob.Expression
}
func (o updateOauthTokenOrg) args() iter.Seq[orm.ArgWithPosition] {
return func(yield func(arg orm.ArgWithPosition) bool) {
if !yield(orm.ArgWithPosition{
Name: "arcgisID",
Start: 35,
Stop: 37,
Expression: o.ArcgisID,
}) {
return
}
if !yield(orm.ArgWithPosition{
Name: "arcgisLicenseTypeID",
Start: 64,
Stop: 66,
Expression: o.ArcgisLicenseTypeID,
}) {
return
}
if !yield(orm.ArgWithPosition{
Name: "refreshToken",
Start: 90,
Stop: 92,
Expression: o.RefreshToken,
}) {
return
}
}
}
func (o updateOauthTokenOrg) raw(from, to int) string {
return updateOauthTokenOrgSQL[from:to]
}
func (o updateOauthTokenOrg) subExpr(from, to int) bob.Expression {
return orm.ArgsToExpression(updateOauthTokenOrgSQL, from, to, o.args())
}
func (o updateOauthTokenOrg) WriteSQL(ctx context.Context, w io.Writer, d bob.Dialect, start int) ([]any, error) {
return o.subExpr(0, len(updateOauthTokenOrgSQL)).WriteSQL(ctx, w, d, start)
}

View file

@ -0,0 +1,6 @@
-- Code generated by BobGen psql v0.41.1. DO NOT EDIT.
-- This file is meant to be re-generated in place and/or deleted at any time.
-- UpdateOauthTokenOrg
UPDATE oauth_token SET arcgis_id = $1, arcgis_license_type_id = $2
WHERE refresh_token = $3;

View file

@ -0,0 +1,76 @@
// Code generated by BobGen psql v0.41.1. DO NOT EDIT.
// This file is meant to be re-generated in place and/or deleted at any time.
package sql
import (
"context"
"fmt"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stephenafamo/bob"
"github.com/stephenafamo/bob/dialect/psql"
testutils "github.com/stephenafamo/bob/test/utils"
)
func TestUpdateOauthTokenOrg(t *testing.T) {
t.Run("Base", func(t *testing.T) {
var sb strings.Builder
query := UpdateOauthTokenOrg(random_string(nil), random_string(nil), random_string(nil))
if _, err := query.WriteQuery(t.Context(), &sb, 1); err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(updateOauthTokenOrgSQL, sb.String()); diff != "" {
t.Fatalf("unexpected result (-got +want):\n%s", diff)
}
})
t.Run("Mod", func(t *testing.T) {
var sb strings.Builder
query := UpdateOauthTokenOrg(random_string(nil), random_string(nil), random_string(nil))
if _, err := psql.Update(query).WriteQuery(t.Context(), &sb, 1); err != nil {
t.Fatal(err)
}
queryDiff, err := testutils.QueryDiff(updateOauthTokenOrgSQL, sb.String(), formatQuery)
if err != nil {
t.Fatal(err)
}
if queryDiff != "" {
fmt.Println(sb.String())
t.Fatalf("unexpected result (-got +want):\n%s", queryDiff)
}
})
t.Run("Exec", func(t *testing.T) {
if testDB == nil {
t.Skip("skipping test, no DSN provided")
}
ctxTx, cancel := context.WithCancel(t.Context())
defer cancel()
tx, err := testDB.Begin(ctxTx)
if err != nil {
t.Fatalf("Error starting transaction: %v", err)
}
defer func() {
if err := tx.Rollback(ctxTx); err != nil {
t.Fatalf("Error rolling back transaction: %v", err)
}
}()
query := psql.Update(UpdateOauthTokenOrg(random_string(nil), random_string(nil), random_string(nil)))
if _, err := bob.Exec(ctxTx, tx, query); err != nil {
t.Fatal(err)
}
})
}

3
sql/update_oauth_org.sql Normal file
View file

@ -0,0 +1,3 @@
-- UpdateOauthTokenOrg
UPDATE oauth_token SET arcgis_id = $1, arcgis_license_type_id = $2
WHERE refresh_token = $3;