Compare commits
3 Commits
var-url-fo
...
chore/time
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1900eb8455 | ||
|
|
bbd21eba42 | ||
|
|
f09d8734a1 |
@@ -5,15 +5,18 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
var (
|
||||
Identity = "id"
|
||||
Integer = "bigint"
|
||||
Text = "text"
|
||||
Identity = "id"
|
||||
Integer = "bigint"
|
||||
Text = "text"
|
||||
Timestamptz = "timestamptz"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -446,3 +449,92 @@ func (dialect *dialect) DropColumnWithForeignKeyConstraint(ctx context.Context,
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dialect *dialect) MakeTimeAuditableTZAwareAndNonNullable(ctx context.Context, bunIDB bun.IDB, tableName string) error {
|
||||
columnType, err := dialect.GetColumnType(ctx, bunIDB, tableName, "created_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if columnType == Timestamptz {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = bunIDB.NewAddColumn().ColumnExpr("created_at_tz TIMESTAMPTZ").Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bunIDB.NewAddColumn().ColumnExpr("updated_at_tz TIMESTAMPTZ").Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type timeAuditableWithID struct {
|
||||
ID valuer.UUID `bun:"id"`
|
||||
CreatedAt time.Time `bun:"created_at,type:timestamptz,nullzero" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at,type:timestamptz,nullzero" json:"updatedAt"`
|
||||
}
|
||||
|
||||
timeAuditables := make([]*timeAuditableWithID, 0)
|
||||
err = bunIDB.
|
||||
NewSelect().
|
||||
Table(tableName).
|
||||
Column("created_at").
|
||||
Column("updated_at").
|
||||
Scan(ctx, &timeAuditables)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
for _, record := range timeAuditables {
|
||||
if record.CreatedAt.IsZero() {
|
||||
record.CreatedAt = now
|
||||
}
|
||||
if record.UpdatedAt.IsZero() {
|
||||
record.UpdatedAt = now
|
||||
}
|
||||
}
|
||||
|
||||
if len(timeAuditables) > 0 {
|
||||
_, err = bunIDB.
|
||||
NewUpdate().
|
||||
With("_data", bunIDB.NewValues(&timeAuditables)).
|
||||
Set("created_at_tz = _data.created_at").
|
||||
Set("updated_at_tz = _data.updated_at").
|
||||
Table(tableName).Where("id = _data.id").
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = dialect.DropColumn(ctx, bunIDB, tableName, "created_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dialect.DropColumn(ctx, bunIDB, tableName, "updated_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = dialect.RenameColumn(ctx, bunIDB, tableName, "created_at_tz", "created_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dialect.RenameColumn(ctx, bunIDB, tableName, "updated_at_tz", "updated_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bunIDB.ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s ALTER COLUMN created_at SET NOT NULL", tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bunIDB.ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s ALTER COLUMN updated_at SET NOT NULL", tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ func NewSQLMigrationProviderFactories(sqlstore sqlstore.SQLStore) factory.NamedM
|
||||
sqlmigration.NewCreateQuickFiltersFactory(sqlstore),
|
||||
sqlmigration.NewUpdateQuickFiltersFactory(sqlstore),
|
||||
sqlmigration.NewAuthRefactorFactory(sqlstore),
|
||||
sqlmigration.NewAddTimestamptzFactory(sqlstore),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ type updateInvites struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable19 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type existingInvite struct {
|
||||
bun.BaseModel `bun:"table:invites"`
|
||||
|
||||
@@ -33,7 +38,7 @@ type newInvite struct {
|
||||
bun.BaseModel `bun:"table:user_invite"`
|
||||
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable19
|
||||
Name string `bun:"name,type:text,notnull" json:"name"`
|
||||
Email string `bun:"email,type:text,notnull,unique" json:"email"`
|
||||
Token string `bun:"token,type:text,notnull" json:"token"`
|
||||
@@ -117,7 +122,7 @@ func (migration *updateInvites) CopyOldInvitesToNewInvites(existingInvites []*ex
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable19: timeAuditable19{
|
||||
CreatedAt: invite.CreatedAt,
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
|
||||
@@ -17,6 +17,11 @@ type updateAlertmanager struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable21 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type existingChannel struct {
|
||||
bun.BaseModel `bun:"table:notification_channels"`
|
||||
ID int `json:"id" bun:"id,pk,autoincrement"`
|
||||
@@ -31,7 +36,7 @@ type existingChannel struct {
|
||||
type newChannel struct {
|
||||
bun.BaseModel `bun:"table:notification_channel"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable21
|
||||
Name string `json:"name" bun:"name"`
|
||||
Type string `json:"type" bun:"type"`
|
||||
Data string `json:"data" bun:"data"`
|
||||
@@ -51,7 +56,7 @@ type existingAlertmanagerConfig struct {
|
||||
type newAlertmanagerConfig struct {
|
||||
bun.BaseModel `bun:"table:alertmanager_config_new"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable21
|
||||
Config string `bun:"config,notnull,type:text"`
|
||||
Hash string `bun:"hash,notnull,type:text"`
|
||||
OrgID string `bun:"org_id,notnull,unique"`
|
||||
@@ -70,7 +75,7 @@ type existingAlertmanagerState struct {
|
||||
type newAlertmanagerState struct {
|
||||
bun.BaseModel `bun:"table:alertmanager_state_new"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable21
|
||||
Silences string `bun:"silences,nullzero,type:text"`
|
||||
NFLog string `bun:"nflog,nullzero,type:text"`
|
||||
OrgID string `bun:"org_id,notnull,unique"`
|
||||
@@ -217,7 +222,7 @@ func (migration *updateAlertmanager) CopyOldChannelToNewChannel(existingChannels
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable21: timeAuditable21{
|
||||
CreatedAt: channel.CreatedAt,
|
||||
UpdatedAt: channel.UpdatedAt,
|
||||
},
|
||||
@@ -238,7 +243,7 @@ func (migration *updateAlertmanager) CopyOldConfigToNewConfig(existingAlertmanag
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable21: timeAuditable21{
|
||||
CreatedAt: config.CreatedAt,
|
||||
UpdatedAt: config.UpdatedAt,
|
||||
},
|
||||
@@ -258,7 +263,7 @@ func (migration *updateAlertmanager) CopyOldStateToNewState(existingAlertmanager
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable21: timeAuditable21{
|
||||
CreatedAt: state.CreatedAt,
|
||||
UpdatedAt: state.UpdatedAt,
|
||||
},
|
||||
|
||||
@@ -19,6 +19,11 @@ type updateApdexTtl struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable23 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type existingApdexSettings struct {
|
||||
bun.BaseModel `bun:"table:apdex_settings"`
|
||||
OrgID string `bun:"org_id,pk,type:text" json:"orgId"`
|
||||
@@ -51,7 +56,7 @@ type existingTTLStatus struct {
|
||||
type newTTLStatus struct {
|
||||
bun.BaseModel `bun:"table:ttl_setting"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable23
|
||||
TransactionID string `bun:"transaction_id,type:text,notnull"`
|
||||
TableName string `bun:"table_name,type:text,notnull"`
|
||||
TTL int `bun:"ttl,notnull,default:0"`
|
||||
@@ -210,7 +215,7 @@ func (migration *updateApdexTtl) CopyExistingTTLStatusToNewTTLStatus(existingTTL
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable23: timeAuditable23{
|
||||
CreatedAt: ttl.CreatedAt,
|
||||
UpdatedAt: ttl.UpdatedAt,
|
||||
},
|
||||
|
||||
@@ -3,6 +3,7 @@ package sqlmigration
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
@@ -16,6 +17,11 @@ type updateResetPassword struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable24 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type existingResetPasswordRequest struct {
|
||||
bun.BaseModel `bun:"table:reset_password_request"`
|
||||
ID int `bun:"id,pk,autoincrement" json:"id"`
|
||||
@@ -32,7 +38,7 @@ type newResetPasswordRequest struct {
|
||||
|
||||
type existingPersonalAccessToken struct {
|
||||
bun.BaseModel `bun:"table:personal_access_tokens"`
|
||||
types.TimeAuditable
|
||||
timeAuditable24
|
||||
OrgID string `json:"orgId" bun:"org_id,type:text,notnull"`
|
||||
ID int `json:"id" bun:"id,pk,autoincrement"`
|
||||
Role string `json:"role" bun:"role,type:text,notnull,default:'ADMIN'"`
|
||||
@@ -48,7 +54,7 @@ type existingPersonalAccessToken struct {
|
||||
type newPersonalAccessToken struct {
|
||||
bun.BaseModel `bun:"table:personal_access_token"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable24
|
||||
OrgID string `json:"orgId" bun:"org_id,type:text,notnull"`
|
||||
Role string `json:"role" bun:"role,type:text,notnull,default:'ADMIN'"`
|
||||
UserID string `json:"userId" bun:"user_id,type:text,notnull"`
|
||||
@@ -174,7 +180,7 @@ func (migration *updateResetPassword) CopyExistingPATsToNewPATs(existingPATs []*
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable24: timeAuditable24{
|
||||
CreatedAt: pat.CreatedAt,
|
||||
UpdatedAt: pat.UpdatedAt,
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ package sqlmigration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
@@ -12,6 +13,11 @@ import (
|
||||
|
||||
type addVirtualFields struct{}
|
||||
|
||||
type timeAuditable25 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
func NewAddVirtualFieldsFactory() factory.ProviderFactory[SQLMigration, Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("add_virtual_fields"), newAddVirtualFields)
|
||||
}
|
||||
@@ -35,7 +41,7 @@ func (migration *addVirtualFields) Up(ctx context.Context, db *bun.DB) error {
|
||||
bun.BaseModel `bun:"table:virtual_field"`
|
||||
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable25
|
||||
types.UserAuditable
|
||||
|
||||
Name string `bun:"name,type:text,notnull"`
|
||||
|
||||
@@ -19,6 +19,11 @@ type updateIntegrations struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable26 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
func NewUpdateIntegrationsFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("update_integrations"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
|
||||
return newUpdateIntegrations(ctx, ps, c, sqlstore)
|
||||
@@ -71,7 +76,7 @@ type newCloudIntegration struct {
|
||||
bun.BaseModel `bun:"table:cloud_integration"`
|
||||
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable26
|
||||
Provider string `json:"provider" bun:"provider,type:text"`
|
||||
Config string `json:"config" bun:"config,type:text"`
|
||||
AccountID string `json:"account_id" bun:"account_id,type:text"`
|
||||
@@ -94,7 +99,7 @@ type newCloudIntegrationService struct {
|
||||
bun.BaseModel `bun:"table:cloud_integration_service,alias:cis"`
|
||||
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable26
|
||||
Type string `bun:"type,type:text,notnull,unique:cloud_integration_id_type"`
|
||||
Config string `bun:"config,type:text"`
|
||||
CloudIntegrationID string `bun:"cloud_integration_id,type:text,notnull,unique:cloud_integration_id_type"`
|
||||
@@ -103,7 +108,7 @@ type newCloudIntegrationService struct {
|
||||
type StorablePersonalAccessToken struct {
|
||||
bun.BaseModel `bun:"table:personal_access_token"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable26
|
||||
OrgID string `json:"orgId" bun:"org_id,type:text,notnull"`
|
||||
Role string `json:"role" bun:"role,type:text,notnull,default:'ADMIN'"`
|
||||
UserID string `json:"userId" bun:"user_id,type:text,notnull"`
|
||||
@@ -298,7 +303,7 @@ func (migration *updateIntegrations) CopyOldCloudIntegrationsToNewCloudIntegrati
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable26: timeAuditable26{
|
||||
CreatedAt: integration.CreatedAt,
|
||||
UpdatedAt: integration.CreatedAt,
|
||||
},
|
||||
@@ -337,7 +342,7 @@ func (migration *updateIntegrations) CopyOldCloudIntegrationServicesToNewCloudIn
|
||||
Identifiable: types.Identifiable{
|
||||
ID: valuer.GenerateUUID(),
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable26: timeAuditable26{
|
||||
CreatedAt: service.CreatedAt,
|
||||
UpdatedAt: service.CreatedAt,
|
||||
},
|
||||
@@ -354,7 +359,7 @@ func (migration *updateIntegrations) copyOldAwsIntegrationUser(tx bun.IDB, orgID
|
||||
type oldUser struct {
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
|
||||
types.TimeAuditable
|
||||
timeAuditable26
|
||||
ID string `bun:"id,pk,type:text" json:"id"`
|
||||
Name string `bun:"name,type:text,notnull" json:"name"`
|
||||
Email string `bun:"email,type:text,notnull,unique" json:"email"`
|
||||
@@ -381,7 +386,7 @@ func (migration *updateIntegrations) copyOldAwsIntegrationUser(tx bun.IDB, orgID
|
||||
// new user
|
||||
newUser := &oldUser{
|
||||
ID: uuid.New().String(),
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable26: timeAuditable26{
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
@@ -410,7 +415,7 @@ func (migration *updateIntegrations) copyOldAwsIntegrationUser(tx bun.IDB, orgID
|
||||
// new pat
|
||||
newPAT := &StorablePersonalAccessToken{
|
||||
Identifiable: types.Identifiable{ID: valuer.GenerateUUID()},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable26: timeAuditable26{
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
|
||||
@@ -21,6 +21,11 @@ type updateRules struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable27 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type AlertIds []string
|
||||
|
||||
func (a *AlertIds) Scan(src interface{}) error {
|
||||
@@ -48,7 +53,7 @@ type existingRule struct {
|
||||
type newRule struct {
|
||||
bun.BaseModel `bun:"table:rule"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable27
|
||||
types.UserAuditable
|
||||
Deleted int `bun:"deleted,notnull,default:0"`
|
||||
Data string `bun:"data,type:text,notnull"`
|
||||
@@ -71,7 +76,7 @@ type existingMaintenance struct {
|
||||
type newMaintenance struct {
|
||||
bun.BaseModel `bun:"table:planned_maintenance_new"`
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable27
|
||||
types.UserAuditable
|
||||
Name string `bun:"name,type:text,notnull"`
|
||||
Description string `bun:"description,type:text"`
|
||||
@@ -283,7 +288,7 @@ func (migration *updateRules) CopyExistingRulesToNewRules(existingRules []*exist
|
||||
Identifiable: types.Identifiable{
|
||||
ID: uuid,
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable27: timeAuditable27{
|
||||
CreatedAt: rule.CreatedAt,
|
||||
UpdatedAt: rule.UpdatedAt,
|
||||
},
|
||||
@@ -310,7 +315,7 @@ func (migration *updateRules) CopyExistingMaintenancesToNewMaintenancesAndRules(
|
||||
Identifiable: types.Identifiable{
|
||||
ID: maintenanceUUID,
|
||||
},
|
||||
TimeAuditable: types.TimeAuditable{
|
||||
timeAuditable27: timeAuditable27{
|
||||
CreatedAt: maintenance.CreatedAt,
|
||||
UpdatedAt: maintenance.UpdatedAt,
|
||||
},
|
||||
|
||||
@@ -2,10 +2,10 @@ package sqlmigration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/types"
|
||||
"github.com/uptrace/bun"
|
||||
"github.com/uptrace/bun/migrate"
|
||||
)
|
||||
@@ -14,6 +14,11 @@ type dropGroups struct {
|
||||
sqlstore sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable29 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
func NewDropGroupsFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("drop_groups"), func(ctx context.Context, providerSettings factory.ProviderSettings, config Config) (SQLMigration, error) {
|
||||
return newDropGroups(ctx, providerSettings, config, sqlstore)
|
||||
@@ -36,7 +41,7 @@ func (migration *dropGroups) Up(ctx context.Context, db *bun.DB) error {
|
||||
type Group struct {
|
||||
bun.BaseModel `bun:"table:groups"`
|
||||
|
||||
types.TimeAuditable
|
||||
timeAuditable29
|
||||
OrgID string `bun:"org_id,type:text"`
|
||||
ID string `bun:"id,pk,type:text" json:"id"`
|
||||
Name string `bun:"name,type:text,notnull,unique" json:"name"`
|
||||
@@ -66,7 +71,7 @@ func (migration *dropGroups) Up(ctx context.Context, db *bun.DB) error {
|
||||
type existingUser struct {
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
|
||||
types.TimeAuditable
|
||||
timeAuditable29
|
||||
ID string `bun:"id,pk,type:text" json:"id"`
|
||||
Name string `bun:"name,type:text,notnull" json:"name"`
|
||||
Email string `bun:"email,type:text,notnull,unique" json:"email"`
|
||||
@@ -105,7 +110,7 @@ func (migration *dropGroups) Up(ctx context.Context, db *bun.DB) error {
|
||||
if err := migration.sqlstore.Dialect().DropColumnWithForeignKeyConstraint(ctx, tx, new(struct {
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
|
||||
types.TimeAuditable
|
||||
timeAuditable29
|
||||
ID string `bun:"id,pk,type:text"`
|
||||
Name string `bun:"name,type:text,notnull"`
|
||||
Email string `bun:"email,type:text,notnull,unique"`
|
||||
|
||||
@@ -3,6 +3,8 @@ package sqlmigration
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
@@ -17,13 +19,18 @@ type createQuickFilters struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable30 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type quickFilter struct {
|
||||
bun.BaseModel `bun:"table:quick_filter"`
|
||||
types.Identifiable
|
||||
OrgID string `bun:"org_id,notnull,unique:org_id_signal,type:text"`
|
||||
Filter string `bun:"filter,notnull,type:text"`
|
||||
Signal string `bun:"signal,notnull,unique:org_id_signal,type:text"`
|
||||
types.TimeAuditable
|
||||
timeAuditable30
|
||||
types.UserAuditable
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package sqlmigration
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
@@ -16,6 +17,11 @@ type authRefactor struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type timeAuditable32 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
func NewAuthRefactorFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("auth_refactor"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
|
||||
return newAuthRefactor(ctx, ps, c, sqlstore)
|
||||
@@ -37,7 +43,7 @@ func (migration *authRefactor) Register(migrations *migrate.Migrations) error {
|
||||
type existingUser32 struct {
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
|
||||
types.TimeAuditable
|
||||
timeAuditable32
|
||||
ID string `bun:"id,pk,type:text" json:"id"`
|
||||
Name string `bun:"name,type:text,notnull" json:"name"`
|
||||
Email string `bun:"email,type:text,notnull,unique" json:"email"`
|
||||
@@ -51,7 +57,7 @@ type factorPassword32 struct {
|
||||
bun.BaseModel `bun:"table:factor_password"`
|
||||
|
||||
types.Identifiable
|
||||
types.TimeAuditable
|
||||
timeAuditable32
|
||||
Password string `bun:"password,type:text,notnull" json:"password"`
|
||||
Temporary bool `bun:"temporary,type:boolean,notnull" json:"temporary"`
|
||||
UserID string `bun:"user_id,type:text,notnull" json:"userID"`
|
||||
|
||||
229
pkg/sqlmigration/033_add_timestamptz.go
Normal file
229
pkg/sqlmigration/033_add_timestamptz.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package sqlmigration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/factory"
|
||||
"github.com/SigNoz/signoz/pkg/sqlstore"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/uptrace/bun"
|
||||
"github.com/uptrace/bun/migrate"
|
||||
)
|
||||
|
||||
type addTimestamptz struct {
|
||||
store sqlstore.SQLStore
|
||||
}
|
||||
|
||||
type identifiable33 struct {
|
||||
ID valuer.UUID `json:"id" bun:"id,pk,type:text"`
|
||||
}
|
||||
|
||||
type existingTimeAuditable33 struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type newTimeAuditable33 struct {
|
||||
CreatedAt time.Time `bun:"created_at,type:timestamptz,nullzero,notnull" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at,type:timestamptz,nullzero,notnull" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type existingOrganization33 struct {
|
||||
bun.BaseModel `bun:"table:organizations"`
|
||||
existingTimeAuditable33
|
||||
identifiable33
|
||||
Name string `bun:"name,type:text,nullzero" json:"name"`
|
||||
Alias string `bun:"alias,type:text,nullzero" json:"alias"`
|
||||
DisplayName string `bun:"display_name,type:text,notnull" json:"displayName"`
|
||||
}
|
||||
|
||||
type newOrganization33 struct {
|
||||
bun.BaseModel `bun:"table:organizations_tmp"`
|
||||
newTimeAuditable33
|
||||
identifiable33
|
||||
Name string `bun:"name,type:text,nullzero" json:"name"`
|
||||
Alias string `bun:"alias,type:text,nullzero" json:"alias"`
|
||||
DisplayName string `bun:"display_name,type:text,notnull" json:"displayName"`
|
||||
}
|
||||
|
||||
type existingUser33 struct {
|
||||
bun.BaseModel `bun:"table:users"`
|
||||
|
||||
identifiable33
|
||||
existingTimeAuditable33
|
||||
DisplayName string `bun:"display_name,type:text,notnull" json:"displayName"`
|
||||
Email string `bun:"email,type:text,notnull,unique:org_email" json:"email"`
|
||||
Role string `bun:"role,type:text,notnull" json:"role"`
|
||||
OrgID string `bun:"org_id,type:text,notnull,unique:org_email,references:org(id),on_delete:CASCADE" json:"orgId"`
|
||||
}
|
||||
|
||||
type newUser33 struct {
|
||||
bun.BaseModel `bun:"table:users_tmp"`
|
||||
|
||||
identifiable33
|
||||
newTimeAuditable33
|
||||
DisplayName string `bun:"display_name,type:text,notnull" json:"displayName"`
|
||||
Email string `bun:"email,type:text,notnull,unique:org_email" json:"email"`
|
||||
Role string `bun:"role,type:text,notnull" json:"role"`
|
||||
OrgID string `bun:"org_id,type:text,notnull,unique:org_email,references:org(id),on_delete:CASCADE" json:"orgId"`
|
||||
}
|
||||
|
||||
func NewAddTimestamptzFactory(sqlstore sqlstore.SQLStore) factory.ProviderFactory[SQLMigration, Config] {
|
||||
return factory.NewProviderFactory(factory.MustNewName("add_timestamptz"), func(ctx context.Context, ps factory.ProviderSettings, c Config) (SQLMigration, error) {
|
||||
return newAddTimestamptz(ctx, ps, c, sqlstore)
|
||||
})
|
||||
}
|
||||
|
||||
func newAddTimestamptz(_ context.Context, _ factory.ProviderSettings, _ Config, store sqlstore.SQLStore) (SQLMigration, error) {
|
||||
return &addTimestamptz{store: store}, nil
|
||||
}
|
||||
|
||||
func (migration *addTimestamptz) Register(migrations *migrate.Migrations) error {
|
||||
if err := migrations.Register(migration.Up, migration.Down); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (migration *addTimestamptz) Up(ctx context.Context, db *bun.DB) error {
|
||||
err := migration.store.Dialect().ToggleForeignKeyConstraint(ctx, db, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err := db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
organizations := make([]*existingOrganization33, 0)
|
||||
newOrganizations := make([]*newOrganization33, 0)
|
||||
err = tx.NewSelect().Model(&organizations).Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, organization := range organizations {
|
||||
if organization.CreatedAt.IsZero() {
|
||||
organization.CreatedAt = time.Now()
|
||||
}
|
||||
if organization.UpdatedAt.IsZero() {
|
||||
organization.UpdatedAt = time.Now()
|
||||
}
|
||||
newOrganizations = append(newOrganizations, &newOrganization33{
|
||||
newTimeAuditable33: newTimeAuditable33{
|
||||
CreatedAt: organization.CreatedAt,
|
||||
UpdatedAt: organization.UpdatedAt,
|
||||
},
|
||||
identifiable33: identifiable33{
|
||||
ID: organization.ID,
|
||||
},
|
||||
Name: organization.Name,
|
||||
Alias: organization.Alias,
|
||||
DisplayName: organization.DisplayName,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
_, err = tx.NewCreateTable().IfNotExists().Model(new(newOrganization33)).Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(newOrganizations) > 0 {
|
||||
_, err = tx.NewInsert().Model(&newOrganizations).Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.NewDropTable().Model(new(existingOrganization33)).IfExists().Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldTableName := tx.Dialect().Tables().Get(reflect.TypeOf(new(existingOrganization33))).Name
|
||||
_, err = tx.
|
||||
ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s RENAME TO %s", oldTableName+"_tmp", oldTableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/// ---
|
||||
|
||||
users := make([]*existingUser33, 0)
|
||||
newUsers := make([]*newUser33, 0)
|
||||
err = tx.NewSelect().Model(&users).Scan(ctx)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, user := range users {
|
||||
if user.CreatedAt.IsZero() {
|
||||
user.CreatedAt = time.Now()
|
||||
}
|
||||
if user.UpdatedAt.IsZero() {
|
||||
user.UpdatedAt = time.Now()
|
||||
}
|
||||
newUsers = append(newUsers, &newUser33{
|
||||
newTimeAuditable33: newTimeAuditable33{
|
||||
CreatedAt: user.CreatedAt,
|
||||
UpdatedAt: user.UpdatedAt,
|
||||
},
|
||||
identifiable33: identifiable33{
|
||||
ID: user.ID,
|
||||
},
|
||||
DisplayName: user.DisplayName,
|
||||
Email: user.Email,
|
||||
Role: user.Role,
|
||||
OrgID: user.OrgID,
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
_, err = tx.NewCreateTable().IfNotExists().Model(new(newUser33)).Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(newUsers) > 0 {
|
||||
_, err = tx.NewInsert().Model(&newUsers).Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err = tx.NewDropTable().Model(new(existingUser33)).IfExists().Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldTableName = tx.Dialect().Tables().Get(reflect.TypeOf(new(existingUser33))).Name
|
||||
_, err = tx.
|
||||
ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s RENAME TO %s", oldTableName+"_tmp", oldTableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer tx.Rollback()
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = migration.store.Dialect().ToggleForeignKeyConstraint(ctx, db, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (migration *addTimestamptz) Down(context.Context, *bun.DB) error {
|
||||
return nil
|
||||
}
|
||||
@@ -6,15 +6,18 @@ import (
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
const (
|
||||
Identity string = "id"
|
||||
Integer string = "INTEGER"
|
||||
Text string = "TEXT"
|
||||
Identity string = "id"
|
||||
Integer string = "INTEGER"
|
||||
Text string = "TEXT"
|
||||
Timestamptz string = "TIMESTAMPTZ"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -499,3 +502,95 @@ func (dialect *dialect) ToggleForeignKeyConstraint(ctx context.Context, bun *bun
|
||||
_, err := bun.ExecContext(ctx, "PRAGMA foreign_keys = OFF")
|
||||
return err
|
||||
}
|
||||
|
||||
func (dialect *dialect) MakeTimeAuditableTZAwareAndNonNullable(ctx context.Context, bunIDB bun.IDB, tableName string) error {
|
||||
columnType, err := dialect.GetColumnType(ctx, bunIDB, tableName, "created_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if columnType == Timestamptz {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = bunIDB.NewAddColumn().Table(tableName).ColumnExpr("created_at_tz TIMESTAMPTZ").Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bunIDB.NewAddColumn().Table(tableName).ColumnExpr("updated_at_tz TIMESTAMPTZ").Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type timeAuditableWithID struct {
|
||||
ID valuer.UUID `bun:"id"`
|
||||
CreatedAt time.Time `bun:"created_at,type:timestamptz,nullzero" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at,type:timestamptz,nullzero" json:"updatedAt"`
|
||||
}
|
||||
|
||||
timeAuditables := make([]*timeAuditableWithID, 0)
|
||||
err = bunIDB.
|
||||
NewSelect().
|
||||
Table(tableName).
|
||||
Column("created_at").
|
||||
Column("updated_at").
|
||||
Column("id").
|
||||
Scan(ctx, &timeAuditables)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
for _, record := range timeAuditables {
|
||||
if record.CreatedAt.IsZero() {
|
||||
record.CreatedAt = now
|
||||
}
|
||||
if record.UpdatedAt.IsZero() {
|
||||
record.UpdatedAt = now
|
||||
}
|
||||
}
|
||||
|
||||
if len(timeAuditables) > 0 {
|
||||
_, err = bunIDB.
|
||||
NewUpdate().
|
||||
With("updates", bunIDB.NewValues(&timeAuditables)).
|
||||
ModelTableExpr(tableName + " AS t").
|
||||
Table("updates").
|
||||
Set("created_at_tz = updates.created_at").
|
||||
Set("updated_at_tz = updates.updated_at").
|
||||
Where("t.id = updates.id").
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = dialect.DropColumn(ctx, bunIDB, tableName, "created_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dialect.DropColumn(ctx, bunIDB, tableName, "updated_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = dialect.RenameColumn(ctx, bunIDB, tableName, "created_at_tz", "created_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dialect.RenameColumn(ctx, bunIDB, tableName, "updated_at_tz", "updated_at")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = bunIDB.ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s ALTER COLUMN created_at SET NOT NULL", tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bunIDB.ExecContext(ctx, fmt.Sprintf("ALTER TABLE %s ALTER COLUMN updated_at SET NOT NULL", tableName))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -89,4 +89,6 @@ type SQLDialect interface {
|
||||
// Toggles foreign key constraint for the given database. This makes sense only for sqlite. This cannot take a transaction as an argument and needs to take the db
|
||||
// as an argument.
|
||||
ToggleForeignKeyConstraint(ctx context.Context, bun *bun.DB, enable bool) error
|
||||
|
||||
MakeTimeAuditableTZAwareAndNonNullable(context.Context, bun.IDB, string) error
|
||||
}
|
||||
|
||||
@@ -68,3 +68,7 @@ func (dialect *dialect) TableExists(ctx context.Context, bun bun.IDB, table inte
|
||||
func (dialect *dialect) ToggleForeignKeyConstraint(ctx context.Context, bun *bun.DB, enable bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dialect *dialect) MakeTimeAuditableTZAwareAndNonNullable(ctx context.Context, bunIDB bun.IDB, tableName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package types
|
||||
import "time"
|
||||
|
||||
type TimeAuditable struct {
|
||||
CreatedAt time.Time `bun:"created_at" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at" json:"updatedAt"`
|
||||
CreatedAt time.Time `bun:"created_at,type:timestamptz,nullzero" json:"createdAt"`
|
||||
UpdatedAt time.Time `bun:"updated_at,type:timestamptz,nullzero" json:"updatedAt"`
|
||||
}
|
||||
|
||||
type UserAuditable struct {
|
||||
|
||||
Reference in New Issue
Block a user