Giter Club home page Giter Club logo

enthistory's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

enthistory's Issues

Support for custom annotations

Is your feature request related to a problem? Please describe.
When using enthistory together with entgql it would be nice to be able to skip schema/type generation for history tables by supplying the entgql.Skip()-annotation,

Describe the solution you'd like
To be able to specify custom annotations/policies (mixins?) that should be added to the history schemas. Maybe enthistory.Annotations can be used for that?

Separate Generated History Schema From Origin Schema Path.

Add feature to separate origin schema and generated history schema.

An alternative path to hold generated schema files.

my solution
enthistory.WithHistorySchemaPath(schemeHistoryPath),;
enthistory.WithOriginSchemaPath(schemeOriginPath), or just using enthistory.WithSchemaPath(schemePath), for origin schema path.

Errors Raise When Using enthistory.ValueTypeString

Add Line enthistory.WithUpdatedBy("userID", enthistory.ValueTypeString), in enthistory.NewHistoryExtension()

Generated code in xxx/gen/ent/

func (c *Client) WithHistory() {
	if !c.historyActivated {
		for _, hook := range enthistory.HistoryHooks[*SomeModelMutation]() {
			c.SomeModel.Use(hook)
		}
	}
}

And generated code in xxx/gen/ent/mutation.go



// ID returns the ID value in the mutation. Note that the ID is only available
// if it was provided to the builder or after it was returned from the database.
func (m *SomeModelMutation) ID() (id string, exists bool) {
	if m.id == nil {
		return
	}
	return *m.id, true
}

I think the problem in source code hook.go


type Mutation interface {
	ID() (id int, exists bool)
	Op() ent.Op
	CreateHistoryFromCreate(ctx context.Context) error
	CreateHistoryFromUpdate(ctx context.Context) error
	CreateHistoryFromDelete(ctx context.Context) error
}


func HistoryHooks[T Mutation]() []ent.Hook {
	return []ent.Hook{
		On(historyHookCreate[T](), ent.OpCreate),
		On(historyHookUpdate[T](), ent.OpUpdate|ent.OpUpdateOne),
		On(historyHookDelete[T](), ent.OpDelete|ent.OpDeleteOne),
	}
}


When enthistory.WithUpdatedBy(), using parameter enthistory.ValueTypeString result in the issue. as
type Mutation interface has method
ID() (id int, exists bool)
while generated code using ID() (id string, exists bool)

Many to Many Tables

I am trying to see if M2M joins are supported on enthistory. Or if there is a plan to support in the future.

Thanks

Using enthistory together with entgql causes problems

Describe the bug
I'm having some issues using enthistory together with entgql. Please close this issue if you think it's more related to entgql or bad configuration.

First problem:

failed to run ent codegen: execute template "client": template: node.tmpl:315:16: executing "client/fields/additional" at <gqlIDType (filterNodes $.Nodes (skipMode "type")) $.IDType>: error calling gqlIDType: entgql: mixed id types must be type string or implement the graphql.Marshaller/graphql.Unmarshaller interfaces

Seems to be related to the id field being skipped in the history entity since error goes away when commenting out the id check:

for _, field := range original.Fields() {
	// if field.Descriptor().Name != "id" {
		historyFields = append(historyFields, field)
	// }
}

Second problem:

failed to load schema: internal/graphql/schema/query.graphql:6: Undefined type UUID.

Adding the type annotation to the ref field makes the error go away. I suspect there should be some way to configure entgql to use ID for all UUID fields, probably not a problem in enthistory..

field.UUID("ref", uuid.UUID{}).
	Immutable().
	Optional().
	Annotations(
		entgql.Annotation{
			Type: "ID",
		},
	),

Third problem:

cannot use (*enthistory.OpType)(nil) (value of type *enthistory.OpType) as graphql.Unmarshaler value in variable declaration: *enthistory.OpType does not implement graphql.Unmarshaler (missing method UnmarshalGQL)

Adding the methods to OpType makes the error go away:

func (op OpType) MarshalGQL(w io.Writer) {
	io.WriteString(w, op.String())
}

// UnmarshalGQL implements graphql.Unmarshaler interface.
func (op *OpType) UnmarshalGQL(val interface{}) error {
	str, ok := val.(string)
	if !ok {
		return fmt.Errorf("enum %T must be a string", val)
	}
	*op = OpType(str)

	switch *op {
	case OpTypeInsert, OpTypeUpdate, OpTypeDelete:
		return nil
	default:
		return fmt.Errorf("%s is not a valid history operation type", str)
	}
}

To Reproduce
https://github.com/nixxxon/entdemo

Start from the first commit and run go generate . to get the first problem.

Expected behavior
The history entities and GraphQL schema being successfully generated.

Additional context
Thanks for all the great work with this.

auditing.go errors from field.JSON

Describe the bug
With feature Auditing

Generating entc is success.
Errors raise while run main function, like

internal/gen/entscheme/auditing.go:273:15: map[string]interface{} does not satisfy comparable
internal/gen/entscheme/auditing.go:609:15: map[string]interface{} does not satisfy comparable
internal/gen/entscheme/auditing.go:789:15: []string does not satisfy comparable
internal/gen/entscheme/auditing.go:939:15: []map[string]interface{} does not satisfy comparable
internal/gen/entscheme/auditing.go:945:15: map[string]string does not satisfy comparable
internal/gen/entscheme/auditing.go:1029:15: map[string]interface{} does not satisfy comparable
internal/gen/entscheme/auditing.go:1032:15: map[string]interface{} does not satisfy comparable
internal/gen/entscheme/auditing.go:2259:15: map[string]interface{} does not satisfy comparable
internal/gen/entscheme/client.go:310:48: *AssetAdminUserMutation does not satisfy enthistory.Mutation (wrong type for method ID)
		have ID() (string, bool)
		want ID() (int, bool)
internal/gen/entscheme/client.go:313:48: *AssetAssetMutation does not satisfy enthistory.Mutation (wrong type for method ID)
		have ID() (string, bool)
		want ID() (int, bool)
internal/gen/entscheme/client.go:313:48: too many errors
make: *** [start] Error 1

To Reproduce

Add line enthistory.WithAuditing(), in enthistory.NewHistoryExtension()

Add lines in entity like:


func (SomeModel ) Fields() []ent.Field {
	return []ent.Field{

field.JSON("some_map", map[string]any{}).Optional(),
field.JSON("some_list", []string{}).Optional(),

}

enthistory version is v0.8.0.

Code Gen does not use set Schema Path

Describe the bug
When schemas exist in an alternate directory other than /schema like /pkg/database/models. Enthistory fails to write history tables to the set schema directory.

To Reproduce

//go:build ignore
// +build ignore

package main

import (
	"log"

	"entgo.io/ent/entc"
	"entgo.io/ent/entc/gen"
	"github.com/flume/enthistory"
)

func main() {
	if err := entc.Generate("./pkg/database/models", &gen.Config{ 
		Package: ".../pkg/database/ent",
		Target:  "./pkg/database/ent",
		Features: []gen.Feature{
			gen.FeatureLock,
			gen.FeatureUpsert,
		},
	},
		entc.Extensions(
			enthistory.NewHistoryExtension(
				enthistory.WithUpdatedBy("userUUID", enthistory.ValueTypeString),
				enthistory.WithAuditing(),
			),
		),
	); err != nil {
		log.Fatal("running ent codegen:", err)
	}
}

Expected behavior
Expect Enthistory to use the set schema directory to write the new history tables to.

Note I am not even sure ent exposes the schema directory to use so this might not be possible.

History annotations are missing in generated history schema

Describe the bug
When generating the load.Schema structs for the history tables, the annotations are set as

historySchema.Annotations = map[string]any{
	"EntSQL": map[string]any{
		"table": info.TableName,
	},
}

To Reproduce
Generate history tables.

Expected behavior
I would expect the load.Schema model to exactly match the entity files for history tables, which include Annotations for this library.

Additional context
Under certain circumstances, This results in FooHistoryHistory tables being generated when using the schema/snapshot ent feature flag.

UUID support for schema ID field

I've been working with your extension and realized it lacks support for Google UUIDs as schema ID fields, which is something I need for my project. Before diving in to add this support myself, I wanted to check with you: Are there any known challenges or considerations I should be aware of? Would you have any advice or suggestions on integrating this feature?

Schema generation fails for Edge schemas without dedicated ID field

When defining an edge schema like this (taken from https://entgo.io/docs/schema-edges/#edge-schema):

// Like holds the edge schema definition for the Like edge.
type Like struct {
    ent.Schema
}

func (Like) Annotations() []schema.Annotation {
    return []schema.Annotation{
        field.ID("user_id", "tweet_id"),
    }
}

// Fields of the Like.
func (Like) Fields() []ent.Field {
    return []ent.Field{
        field.Time("liked_at").
            Default(time.Now),
        field.Int("user_id"),
        field.Int("tweet_id"),
    }
}

// Edges of the Like.
func (Like) Edges() []ent.Edge {
    return []ent.Edge{
        edge.To("user", User.Type).
            Unique().
            Required().
            Field("user_id"),
        edge.To("tweet", Tweet.Type).
            Unique().
            Required().
            Field("tweet_id"),
    }
}

NOTE: that we want to store additional metadata regarding the relationship in this table - more than what is added in this example

Running ent generation with the enthistory extension added hits a nil dereference error when trying to extract the ID type at this point in enthistory.go:

// enthistory.go
func (h *HistoryExtension) generateHistorySchemas(next gen.Generator) gen.Generator {
    .
    .
    .


	var IdType *field.TypeInfo
	for _, node := range g.Nodes {
		if schema.Name == node.Name {
			IdType = node.ID.Type
		}
	}
    .
    .
    .
}

Resulting in the following error:

Exception has occurred: panic
"runtime error: invalid memory address or nil pointer dereference"

The entc.go file used was this:

//go:build ignore

package main

import (
	"log"

	"entgo.io/ent/entc"
	"entgo.io/ent/entc/gen"
	"github.com/flume/enthistory"
)

func main() {
	mpConfig := &gen.Config{
		Target: "./gen",
	}

	if err := entc.Generate("./schema",
		mpConfig,
		entc.Extensions(
			enthistory.NewHistoryExtension(
				enthistory.WithAuditing(),
			),
		),
	); err != nil {
		log.Fatal("running ent codegen:", err)
	}
}

Support for excluding specific actions from table history via annotations/options

I would like to be able to disable history on certain hooks ( one or two of Create/Update/Delete) for a particular table.

My objective is to prevent the history tables from being populated with create/delete actions but keeping update actions. I'm looking for a way to exclude these actions, ideally through some form of annotation or options.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.