From 551370e5418d14d862cef4709f7757ba7f4e041c Mon Sep 17 00:00:00 2001 From: Noah Metz Date: Fri, 21 Jul 2023 15:16:35 -0600 Subject: [PATCH] Split gql_graph.go to gql_*.go --- gql_graph.go | 1087 ---------------------------------------------- gql_mutation.go | 138 ++++++ gql_query.go | 30 ++ gql_resolvers.go | 322 ++++++++++++++ gql_subscribe.go | 82 ++++ gql_types.go | 536 +++++++++++++++++++++++ 6 files changed, 1108 insertions(+), 1087 deletions(-) delete mode 100644 gql_graph.go create mode 100644 gql_mutation.go create mode 100644 gql_query.go create mode 100644 gql_resolvers.go create mode 100644 gql_subscribe.go create mode 100644 gql_types.go diff --git a/gql_graph.go b/gql_graph.go deleted file mode 100644 index d97530d..0000000 --- a/gql_graph.go +++ /dev/null @@ -1,1087 +0,0 @@ -package graphvent - -import ( - "github.com/graphql-go/graphql" - "reflect" - "fmt" -) - -var gql_interface_graph_node *graphql.Interface = nil -func GQLInterfaceNode() *graphql.Interface { - if gql_interface_graph_node == nil { - gql_interface_graph_node = graphql.NewInterface(graphql.InterfaceConfig{ - Name: "Node", - ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil - } - - valid_nodes := ctx.GQL.ValidNodes - node_type := ctx.GQL.NodeType - p_type := reflect.TypeOf(p.Value) - - for key, value := range(valid_nodes) { - if p_type == key { - return value - } - } - - if p_type.Implements(node_type) { - return GQLTypeGraphNode() - } - - return nil - }, - Fields: graphql.Fields{}, - }) - - gql_interface_graph_node.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - }) - } - - return gql_interface_graph_node -} - -var gql_list_thread *graphql.List = nil -func GQLListThread() *graphql.List { - if gql_list_thread == nil { - gql_list_thread = graphql.NewList(GQLInterfaceThread()) - } - return gql_list_thread -} - -var gql_interface_thread *graphql.Interface = nil -func GQLInterfaceThread() *graphql.Interface { - if gql_interface_thread == nil { - gql_interface_thread = graphql.NewInterface(graphql.InterfaceConfig{ - Name: "Thread", - ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil - } - - valid_threads := ctx.GQL.ValidThreads - thread_type := ctx.GQL.ThreadType - p_type := reflect.TypeOf(p.Value) - - for key, value := range(valid_threads) { - if p_type == key { - return value - } - } - - if p_type.Implements(thread_type) { - return GQLTypeSimpleThread() - } - - ctx.Log.Logf("gql", "Found no type that matches %+v: %+v", p_type, p_type.Implements(thread_type)) - return nil - }, - Fields: graphql.Fields{}, - }) - - gql_interface_thread.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - }) - - gql_interface_thread.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - }) - - gql_interface_thread.AddFieldConfig("State", &graphql.Field{ - Type: graphql.String, - }) - - gql_interface_thread.AddFieldConfig("Children", &graphql.Field{ - Type: GQLListThread(), - }) - - gql_interface_thread.AddFieldConfig("Parent", &graphql.Field{ - Type: GQLInterfaceThread(), - }) - - gql_interface_thread.AddFieldConfig("Requirements", &graphql.Field{ - Type: GQLListLockable(), - }) - - gql_interface_thread.AddFieldConfig("Dependencies", &graphql.Field{ - Type: GQLListLockable(), - }) - - gql_interface_thread.AddFieldConfig("Owner", &graphql.Field{ - Type: GQLInterfaceLockable(), - }) - } - - return gql_interface_thread -} - -var gql_list_lockable *graphql.List = nil -func GQLListLockable() *graphql.List { - if gql_list_lockable == nil { - gql_list_lockable = graphql.NewList(GQLInterfaceLockable()) - } - return gql_list_lockable -} - -var gql_interface_lockable *graphql.Interface = nil -func GQLInterfaceLockable() *graphql.Interface { - if gql_interface_lockable == nil { - gql_interface_lockable = graphql.NewInterface(graphql.InterfaceConfig{ - Name: "Lockable", - ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil - } - - valid_lockables := ctx.GQL.ValidLockables - lockable_type := ctx.GQL.LockableType - p_type := reflect.TypeOf(p.Value) - - for key, value := range(valid_lockables) { - if p_type == key { - return value - } - } - - if p_type.Implements(lockable_type) { - return GQLTypeSimpleLockable() - } - return nil - }, - Fields: graphql.Fields{}, - }) - - gql_interface_lockable.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - }) - - gql_interface_lockable.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - }) - - if gql_list_lockable == nil { - gql_list_lockable = graphql.NewList(gql_interface_lockable) - } - - gql_interface_lockable.AddFieldConfig("Requirements", &graphql.Field{ - Type: gql_list_lockable, - }) - - gql_interface_lockable.AddFieldConfig("Dependencies", &graphql.Field{ - Type: gql_list_lockable, - }) - - gql_interface_lockable.AddFieldConfig("Owner", &graphql.Field{ - Type: gql_interface_lockable, - }) - - } - - return gql_interface_lockable -} - -func GQLNodeID(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Node) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Node") - } - return node.ID(), nil -} - -func GQLThreadListen(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(*GQLThread) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to GQLThread") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - listen := "" - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - listen = node.Listen - return nil - }) - - if err != nil { - return nil, err - } - - return listen, nil -} - -func GQLThreadParent(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Thread) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Thread") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var parent Thread = nil - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - parent = node.Parent() - return nil - }) - - if err != nil { - return nil, err - } - - return parent, nil -} - -func GQLThreadState(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Thread) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Thread") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var state string - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - state = node.State() - return nil - }) - - if err != nil { - return nil, err - } - - return state, nil -} - -func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Thread) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Thread") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var children []Thread = nil - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - children = node.Children() - return nil - }) - - if err != nil { - return nil, err - } - - return children, nil -} - -func GQLLockableName(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Lockable) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Lockable") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - name := "" - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) error { - name = node.Name() - return nil - }) - - if err != nil { - return nil, err - } - - return name, nil -} - -func GQLLockableRequirements(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Lockable) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Lockable") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var requirements []Lockable = nil - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - requirements = node.Requirements() - return nil - }) - - if err != nil { - return nil, err - } - - return requirements, nil -} - -func GQLLockableDependencies(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Lockable) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Lockable") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var dependencies []Lockable = nil - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - dependencies = node.Dependencies() - return nil - }) - - if err != nil { - return nil, err - } - - return dependencies, nil -} - -func GQLLockableOwner(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(Lockable) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to Lockable") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var owner Node = nil - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { - owner = node.Owner() - return nil - }) - - if err != nil { - return nil, err - } - - return owner, nil -} - -func GQLThreadUsers(p graphql.ResolveParams) (interface{}, error) { - node, ok := p.Source.(*GQLThread) - if ok == false || node == nil { - return nil, fmt.Errorf("Failed to cast source to GQLThread") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to cast context graph_context to Context") - } - - var users []*User - err := UseStates(ctx, []Node{node}, func(nodes NodeMap) error { - users = make([]*User, len(node.Users)) - i := 0 - for _, user := range(node.Users) { - users[i] = user - i += 1 - } - return nil - }) - - if err != nil { - return nil, err - } - - return users, nil -} - -var gql_list_user *graphql.List = nil -func GQLListUser() *graphql.List { - if gql_list_user == nil { - gql_list_user = graphql.NewList(GQLTypeUser()) - } - return gql_list_user -} - -var gql_type_user *graphql.Object = nil -func GQLTypeUser() * graphql.Object { - if gql_type_user == nil { - gql_type_user = graphql.NewObject(graphql.ObjectConfig{ - Name: "User", - Interfaces: []*graphql.Interface{ - GQLInterfaceNode(), - GQLInterfaceLockable(), - }, - IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return false - } - - lockable_type := ctx.GQL.LockableType - value_type := reflect.TypeOf(p.Value) - - if value_type.Implements(lockable_type) { - return true - } - - return false - }, - Fields: graphql.Fields{}, - }) - - gql_type_user.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - Resolve: GQLNodeID, - }) - - gql_type_user.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - Resolve: GQLLockableName, - }) - - gql_type_user.AddFieldConfig("Requirements", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableRequirements, - }) - - gql_type_user.AddFieldConfig("Owner", &graphql.Field{ - Type: GQLInterfaceLockable(), - Resolve: GQLLockableOwner, - }) - - gql_type_user.AddFieldConfig("Dependencies", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableDependencies, - }) - } - return gql_type_user -} - -var gql_type_gql_thread *graphql.Object = nil -func GQLTypeGQLThread() * graphql.Object { - if gql_type_gql_thread == nil { - gql_type_gql_thread = graphql.NewObject(graphql.ObjectConfig{ - Name: "GQLThread", - Interfaces: []*graphql.Interface{ - GQLInterfaceNode(), - GQLInterfaceThread(), - GQLInterfaceLockable(), - }, - IsTypeOf: func(p graphql.IsTypeOfParams) bool { - _, ok := p.Value.(*GQLThread) - return ok - }, - Fields: graphql.Fields{}, - }) - - gql_type_gql_thread.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - Resolve: GQLNodeID, - }) - - gql_type_gql_thread.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - Resolve: GQLLockableName, - }) - - gql_type_gql_thread.AddFieldConfig("State", &graphql.Field{ - Type: graphql.String, - Resolve: GQLThreadState, - }) - - gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{ - Type: GQLListThread(), - Resolve: GQLThreadChildren, - }) - - gql_type_gql_thread.AddFieldConfig("Parent", &graphql.Field{ - Type: GQLInterfaceThread(), - Resolve: GQLThreadParent, - }) - - gql_type_gql_thread.AddFieldConfig("Listen", &graphql.Field{ - Type: graphql.String, - Resolve: GQLThreadListen, - }) - - gql_type_gql_thread.AddFieldConfig("Requirements", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableRequirements, - }) - - gql_type_gql_thread.AddFieldConfig("Owner", &graphql.Field{ - Type: GQLInterfaceLockable(), - Resolve: GQLLockableOwner, - }) - - gql_type_gql_thread.AddFieldConfig("Dependencies", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableDependencies, - }) - - gql_type_gql_thread.AddFieldConfig("Users", &graphql.Field{ - Type: GQLListUser(), - Resolve: GQLThreadUsers, - }) - } - return gql_type_gql_thread -} - -var gql_type_simple_thread *graphql.Object = nil -func GQLTypeSimpleThread() * graphql.Object { - if gql_type_simple_thread == nil { - gql_type_simple_thread = graphql.NewObject(graphql.ObjectConfig{ - Name: "SimpleThread", - Interfaces: []*graphql.Interface{ - GQLInterfaceNode(), - GQLInterfaceThread(), - GQLInterfaceLockable(), - }, - IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return false - } - - thread_type := ctx.GQL.ThreadType - - value_type := reflect.TypeOf(p.Value) - - if value_type.Implements(thread_type) { - return true - } - - return false - }, - Fields: graphql.Fields{}, - }) - gql_type_simple_thread.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - Resolve: GQLNodeID, - }) - - gql_type_simple_thread.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - Resolve: GQLLockableName, - }) - - gql_type_simple_thread.AddFieldConfig("State", &graphql.Field{ - Type: graphql.String, - Resolve: GQLThreadState, - }) - - gql_type_simple_thread.AddFieldConfig("Children", &graphql.Field{ - Type: GQLListThread(), - Resolve: GQLThreadChildren, - }) - - gql_type_simple_thread.AddFieldConfig("Parent", &graphql.Field{ - Type: GQLInterfaceThread(), - Resolve: GQLThreadParent, - }) - - gql_type_simple_thread.AddFieldConfig("Requirements", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableRequirements, - }) - - gql_type_simple_thread.AddFieldConfig("Owner", &graphql.Field{ - Type: GQLInterfaceLockable(), - Resolve: GQLLockableOwner, - }) - - gql_type_simple_thread.AddFieldConfig("Dependencies", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableDependencies, - }) - } - return gql_type_simple_thread -} - -var gql_type_simple_lockable *graphql.Object = nil -func GQLTypeSimpleLockable() * graphql.Object { - if gql_type_simple_lockable == nil { - gql_type_simple_lockable = graphql.NewObject(graphql.ObjectConfig{ - Name: "SimpleLockable", - Interfaces: []*graphql.Interface{ - GQLInterfaceNode(), - GQLInterfaceLockable(), - }, - IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return false - } - - lockable_type := ctx.GQL.LockableType - value_type := reflect.TypeOf(p.Value) - - if value_type.Implements(lockable_type) { - return true - } - - return false - }, - Fields: graphql.Fields{}, - }) - - gql_type_simple_lockable.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - Resolve: GQLNodeID, - }) - - gql_type_simple_lockable.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - Resolve: GQLLockableName, - }) - - gql_type_simple_lockable.AddFieldConfig("Requirements", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableRequirements, - }) - - gql_type_simple_lockable.AddFieldConfig("Owner", &graphql.Field{ - Type: GQLInterfaceLockable(), - Resolve: GQLLockableOwner, - }) - - gql_type_simple_lockable.AddFieldConfig("Dependencies", &graphql.Field{ - Type: GQLListLockable(), - Resolve: GQLLockableDependencies, - }) - } - return gql_type_simple_lockable -} - -var gql_type_simple_node *graphql.Object = nil -func GQLTypeGraphNode() * graphql.Object { - if gql_type_simple_node == nil { - gql_type_simple_node = graphql.NewObject(graphql.ObjectConfig{ - Name: "GraphNode", - Interfaces: []*graphql.Interface{ - GQLInterfaceNode(), - }, - IsTypeOf: func(p graphql.IsTypeOfParams) bool { - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return false - } - - node_type := ctx.GQL.NodeType - value_type := reflect.TypeOf(p.Value) - - if value_type.Implements(node_type) { - return true - } - - return false - }, - Fields: graphql.Fields{}, - }) - - gql_type_simple_node.AddFieldConfig("ID", &graphql.Field{ - Type: graphql.String, - Resolve: GQLNodeID, - }) - - gql_type_simple_node.AddFieldConfig("Name", &graphql.Field{ - Type: graphql.String, - Resolve: GQLLockableName, - }) - } - - return gql_type_simple_node -} - -func GQLSignalFn(p graphql.ResolveParams, fn func(GraphSignal, graphql.ResolveParams)(interface{}, error))(interface{}, error) { - if signal, ok := p.Source.(GraphSignal); ok { - return fn(signal, p) - } - return nil, fmt.Errorf("Failed to cast source to event") -} - -func GQLSignalType(p graphql.ResolveParams) (interface{}, error) { - return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ - return signal.Type(), nil - }) -} - -func GQLSignalSource(p graphql.ResolveParams) (interface{}, error) { - return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ - return signal.Source(), nil - }) -} - -func GQLSignalDirection(p graphql.ResolveParams) (interface{}, error) { - return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ - direction := signal.Direction() - if direction == Up { - return "up", nil - } else if direction == Down { - return "down", nil - } else if direction == Direct { - return "direct", nil - } - return nil, fmt.Errorf("Invalid direction: %+v", direction) - }) -} - -func GQLSignalString(p graphql.ResolveParams) (interface{}, error) { - return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ - return signal.String(), nil - }) -} - - -var gql_type_signal *graphql.Object = nil -func GQLTypeSignal() *graphql.Object { - if gql_type_signal == nil { - gql_type_signal = graphql.NewObject(graphql.ObjectConfig{ - Name: "SignalOut", - IsTypeOf: func(p graphql.IsTypeOfParams) bool { - _, ok := p.Value.(GraphSignal) - return ok - }, - Fields: graphql.Fields{}, - }) - - gql_type_signal.AddFieldConfig("Type", &graphql.Field{ - Type: graphql.String, - Resolve: GQLSignalType, - }) - gql_type_signal.AddFieldConfig("Source", &graphql.Field{ - Type: graphql.String, - Resolve: GQLSignalSource, - }) - gql_type_signal.AddFieldConfig("Direction", &graphql.Field{ - Type: graphql.String, - Resolve: GQLSignalDirection, - }) - gql_type_signal.AddFieldConfig("String", &graphql.Field{ - Type: graphql.String, - Resolve: GQLSignalString, - }) - } - return gql_type_signal -} - -var gql_type_signal_input *graphql.InputObject = nil -func GQLTypeSignalInput() *graphql.InputObject { - if gql_type_signal_input == nil { - gql_type_signal_input = graphql.NewInputObject(graphql.InputObjectConfig{ - Name: "SignalIn", - Fields: graphql.InputObjectConfigFieldMap{}, - }) - gql_type_signal_input.AddFieldConfig("Type", &graphql.InputObjectFieldConfig{ - Type: graphql.String, - DefaultValue: "cancel", - }) - gql_type_signal_input.AddFieldConfig("Direction", &graphql.InputObjectFieldConfig{ - Type: graphql.String, - DefaultValue: "down", - }) - } - return gql_type_signal_input -} - -func GQLSubscribeSignal(p graphql.ResolveParams) (interface{}, error) { - return GQLSubscribeFn(p, false, func(ctx *Context, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { - return signal, nil - }) -} - -func GQLSubscribeSelf(p graphql.ResolveParams) (interface{}, error) { - return GQLSubscribeFn(p, true, func(ctx *Context, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { - return server, nil - }) -} - -func GQLSubscribeFn(p graphql.ResolveParams, send_nil bool, fn func(*Context, *GQLThread, GraphSignal, graphql.ResolveParams)(interface{}, error))(interface{}, error) { - server, ok := p.Context.Value("gql_server").(*GQLThread) - if ok == false { - return nil, fmt.Errorf("Failed to get gql_server from context and cast to GQLServer") - } - - ctx, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, fmt.Errorf("Failed to get graph_context from context and cast to Context") - } - - c := make(chan interface{}) - go func(c chan interface{}, server *GQLThread) { - ctx.Log.Logf("gqlws", "GQL_SUBSCRIBE_THREAD_START") - sig_c := UpdateChannel(server, 1, RandID()) - if send_nil == true { - sig_c <- nil - } - for { - val, ok := <- sig_c - if ok == false { - return - } - ret, err := fn(ctx, server, val, p) - if err != nil { - ctx.Log.Logf("gqlws", "type convertor error %s", err) - return - } - c <- ret - } - }(c, server) - return c, nil -} - -var gql_subscription_self * graphql.Field = nil -func GQLSubscriptionSelf() * graphql.Field { - if gql_subscription_self == nil { - gql_subscription_self = &graphql.Field{ - Type: GQLTypeGQLThread(), - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - return p.Source, nil - }, - Subscribe: GQLSubscribeSelf, - } - } - - return gql_subscription_self -} - -var gql_subscription_update * graphql.Field = nil -func GQLSubscriptionUpdate() * graphql.Field { - if gql_subscription_update == nil { - gql_subscription_update = &graphql.Field{ - Type: GQLTypeSignal(), - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - return p.Source, nil - }, - Subscribe: GQLSubscribeSignal, - } - } - - return gql_subscription_update -} - -func PrepResolve(p graphql.ResolveParams) (*Context, *GQLThread, *User, error) { - context, ok := p.Context.Value("graph_context").(*Context) - if ok == false { - return nil, nil, nil, fmt.Errorf("failed to cast graph_context to *Context") - } - - server, ok := p.Context.Value("gql_server").(*GQLThread) - if ok == false { - return nil, nil, nil, fmt.Errorf("failed to cast gql_server to *GQLThread") - } - - user, ok := p.Context.Value("user").(*User) - if ok == false { - return nil, nil, nil, fmt.Errorf("failed to cast user to *User") - } - - return context, server, user, nil -} - -func ExtractParam[K interface{}](p graphql.ResolveParams, name string) (K, error) { - var zero K - arg_if, ok := p.Args[name] - if ok == false { - return zero, fmt.Errorf("No Arg of name %s", name) - } - - arg, ok := arg_if.(K) - if ok == false { - return zero, fmt.Errorf("Failed to cast arg %s(%+v) to %+v", name, arg_if, reflect.TypeOf(zero)) - } - - return arg, nil -} - -func ExtractID(p graphql.ResolveParams, name string) (NodeID, error) { - id_str, err := ExtractParam[string](p, name) - if err != nil { - return ZeroID, err - } - - id, err := ParseID(id_str) - if err != nil { - return ZeroID, err - } - - return id, nil -} - -var gql_mutation_send_update *graphql.Field = nil -func GQLMutationSendUpdate() *graphql.Field { - if gql_mutation_send_update == nil { - gql_mutation_send_update = &graphql.Field{ - Type: GQLTypeSignal(), - Args: graphql.FieldConfigArgument{ - "id": &graphql.ArgumentConfig{ - Type: graphql.String, - }, - "signal": &graphql.ArgumentConfig{ - Type: GQLTypeSignalInput(), - }, - }, - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - ctx, server, user, err := PrepResolve(p) - if err != nil { - return nil, err - } - - err = server.Allowed("signal", "self", user) - if err != nil { - return nil, err - } - - signal_map, err := ExtractParam[map[string]interface{}](p, "signal") - if err != nil { - return nil, err - } - - var signal GraphSignal = nil - if signal_map["Direction"] == "up" { - signal = NewSignal(server, signal_map["Type"].(string)) - } else if signal_map["Direction"] == "down" { - signal = NewDownSignal(server, signal_map["Type"].(string)) - } else if signal_map["Direction"] == "direct" { - signal = NewDirectSignal(server, signal_map["Type"].(string)) - } else { - return nil, fmt.Errorf("Bad direction: %d", signal_map["Direction"]) - } - - id, err := ExtractID(p, "id") - if err != nil { - return nil, err - } - - var node Node = nil - err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){ - node = FindChild(ctx, server, id, nodes) - if node == nil { - return fmt.Errorf("Failed to find ID: %s as child of server thread", id) - } - node.Signal(ctx, signal, nodes) - return nil - }) - if err != nil { - return nil, err - } - - return signal, nil - }, - } - } - - return gql_mutation_send_update -} - -var gql_mutation_start_child *graphql.Field = nil -func GQLMutationStartChild() *graphql.Field { - if gql_mutation_start_child == nil { - gql_mutation_start_child = &graphql.Field{ - Type: GQLTypeSignal(), - Args: graphql.FieldConfigArgument{ - "parent_id": &graphql.ArgumentConfig{ - Type: graphql.String, - }, - "child_id": &graphql.ArgumentConfig{ - Type: graphql.String, - }, - "action": &graphql.ArgumentConfig{ - Type: graphql.String, - DefaultValue: "start", - }, - }, - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - ctx, server, user, err := PrepResolve(p) - if err != nil { - return nil, err - } - - err = server.Allowed("start_child", "self", user) - if err != nil { - return nil, err - } - - parent_id, err := ExtractID(p, "parent_id") - if err != nil { - return nil, err - } - - child_id, err := ExtractID(p, "child_id") - if err != nil { - return nil, err - } - - action, err := ExtractParam[string](p, "action") - if err != nil { - return nil, err - } - - var signal GraphSignal - err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){ - node := FindChild(ctx, server, parent_id, nodes) - if node == nil { - return fmt.Errorf("Failed to find ID: %s as child of server thread", parent_id) - } - return UseMoreStates(ctx, []Node{node}, nodes, func(NodeMap) error { - signal = NewStartChildSignal(server, child_id, action) - return node.Signal(ctx, signal, nodes) - }) - }) - if err != nil { - return nil, err - } - - // TODO: wait for the result of the signal to send back instead of just the signal - return signal, nil - }, - } - } - - return gql_mutation_start_child -} - -var gql_query_self *graphql.Field = nil -func GQLQuerySelf() *graphql.Field { - if gql_query_self == nil { - gql_query_self = &graphql.Field{ - Type: GQLTypeGQLThread(), - Resolve: func(p graphql.ResolveParams) (interface{}, error) { - _, server, user, err := PrepResolve(p) - - if err != nil { - return nil, err - } - - err = server.Allowed("enumerate", "self", user) - if err != nil { - return nil, fmt.Errorf("User %s is not allowed to perform self.enumerate on %s", user.ID(), server.ID()) - } - - return server, nil - }, - } - } - - return gql_query_self -} diff --git a/gql_mutation.go b/gql_mutation.go new file mode 100644 index 0000000..47d013b --- /dev/null +++ b/gql_mutation.go @@ -0,0 +1,138 @@ +package graphvent +import ( + "fmt" + "github.com/graphql-go/graphql" +) + +var gql_mutation_send_update *graphql.Field = nil +func GQLMutationSendUpdate() *graphql.Field { + if gql_mutation_send_update == nil { + gql_mutation_send_update = &graphql.Field{ + Type: GQLTypeSignal(), + Args: graphql.FieldConfigArgument{ + "id": &graphql.ArgumentConfig{ + Type: graphql.String, + }, + "signal": &graphql.ArgumentConfig{ + Type: GQLTypeSignalInput(), + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + ctx, server, user, err := PrepResolve(p) + if err != nil { + return nil, err + } + + err = server.Allowed("signal", "self", user) + if err != nil { + return nil, err + } + + signal_map, err := ExtractParam[map[string]interface{}](p, "signal") + if err != nil { + return nil, err + } + + var signal GraphSignal = nil + if signal_map["Direction"] == "up" { + signal = NewSignal(server, signal_map["Type"].(string)) + } else if signal_map["Direction"] == "down" { + signal = NewDownSignal(server, signal_map["Type"].(string)) + } else if signal_map["Direction"] == "direct" { + signal = NewDirectSignal(server, signal_map["Type"].(string)) + } else { + return nil, fmt.Errorf("Bad direction: %d", signal_map["Direction"]) + } + + id, err := ExtractID(p, "id") + if err != nil { + return nil, err + } + + var node Node = nil + err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){ + node = FindChild(ctx, server, id, nodes) + if node == nil { + return fmt.Errorf("Failed to find ID: %s as child of server thread", id) + } + node.Signal(ctx, signal, nodes) + return nil + }) + if err != nil { + return nil, err + } + + return signal, nil + }, + } + } + + return gql_mutation_send_update +} + +var gql_mutation_start_child *graphql.Field = nil +func GQLMutationStartChild() *graphql.Field { + if gql_mutation_start_child == nil { + gql_mutation_start_child = &graphql.Field{ + Type: GQLTypeSignal(), + Args: graphql.FieldConfigArgument{ + "parent_id": &graphql.ArgumentConfig{ + Type: graphql.String, + }, + "child_id": &graphql.ArgumentConfig{ + Type: graphql.String, + }, + "action": &graphql.ArgumentConfig{ + Type: graphql.String, + DefaultValue: "start", + }, + }, + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + ctx, server, user, err := PrepResolve(p) + if err != nil { + return nil, err + } + + err = server.Allowed("start_child", "self", user) + if err != nil { + return nil, err + } + + parent_id, err := ExtractID(p, "parent_id") + if err != nil { + return nil, err + } + + child_id, err := ExtractID(p, "child_id") + if err != nil { + return nil, err + } + + action, err := ExtractParam[string](p, "action") + if err != nil { + return nil, err + } + + var signal GraphSignal + err = UseStates(ctx, []Node{server}, func(nodes NodeMap) (error){ + node := FindChild(ctx, server, parent_id, nodes) + if node == nil { + return fmt.Errorf("Failed to find ID: %s as child of server thread", parent_id) + } + return UseMoreStates(ctx, []Node{node}, nodes, func(NodeMap) error { + signal = NewStartChildSignal(server, child_id, action) + return node.Signal(ctx, signal, nodes) + }) + }) + if err != nil { + return nil, err + } + + // TODO: wait for the result of the signal to send back instead of just the signal + return signal, nil + }, + } + } + + return gql_mutation_start_child +} diff --git a/gql_query.go b/gql_query.go new file mode 100644 index 0000000..26a4f03 --- /dev/null +++ b/gql_query.go @@ -0,0 +1,30 @@ +package graphvent +import ( + "fmt" + "github.com/graphql-go/graphql" +) + +var gql_query_self *graphql.Field = nil +func GQLQuerySelf() *graphql.Field { + if gql_query_self == nil { + gql_query_self = &graphql.Field{ + Type: GQLTypeGQLThread(), + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + _, server, user, err := PrepResolve(p) + + if err != nil { + return nil, err + } + + err = server.Allowed("enumerate", "self", user) + if err != nil { + return nil, fmt.Errorf("User %s is not allowed to perform self.enumerate on %s", user.ID(), server.ID()) + } + + return server, nil + }, + } + } + + return gql_query_self +} diff --git a/gql_resolvers.go b/gql_resolvers.go new file mode 100644 index 0000000..674866e --- /dev/null +++ b/gql_resolvers.go @@ -0,0 +1,322 @@ +package graphvent +import ( + "fmt" + "reflect" + "github.com/graphql-go/graphql" +) + +func PrepResolve(p graphql.ResolveParams) (*Context, *GQLThread, *User, error) { + context, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, nil, nil, fmt.Errorf("failed to cast graph_context to *Context") + } + + server, ok := p.Context.Value("gql_server").(*GQLThread) + if ok == false { + return nil, nil, nil, fmt.Errorf("failed to cast gql_server to *GQLThread") + } + + user, ok := p.Context.Value("user").(*User) + if ok == false { + return nil, nil, nil, fmt.Errorf("failed to cast user to *User") + } + + return context, server, user, nil +} + +func ExtractParam[K interface{}](p graphql.ResolveParams, name string) (K, error) { + var zero K + arg_if, ok := p.Args[name] + if ok == false { + return zero, fmt.Errorf("No Arg of name %s", name) + } + + arg, ok := arg_if.(K) + if ok == false { + return zero, fmt.Errorf("Failed to cast arg %s(%+v) to %+v", name, arg_if, reflect.TypeOf(zero)) + } + + return arg, nil +} + +func ExtractID(p graphql.ResolveParams, name string) (NodeID, error) { + id_str, err := ExtractParam[string](p, name) + if err != nil { + return ZeroID, err + } + + id, err := ParseID(id_str) + if err != nil { + return ZeroID, err + } + + return id, nil +} + +func GQLNodeID(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Node) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Node") + } + return node.ID(), nil +} + +func GQLThreadListen(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(*GQLThread) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to GQLThread") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + listen := "" + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + listen = node.Listen + return nil + }) + + if err != nil { + return nil, err + } + + return listen, nil +} + +func GQLThreadParent(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Thread) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Thread") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var parent Thread = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + parent = node.Parent() + return nil + }) + + if err != nil { + return nil, err + } + + return parent, nil +} + +func GQLThreadState(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Thread) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Thread") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var state string + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + state = node.State() + return nil + }) + + if err != nil { + return nil, err + } + + return state, nil +} + +func GQLThreadChildren(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Thread) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Thread") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var children []Thread = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + children = node.Children() + return nil + }) + + if err != nil { + return nil, err + } + + return children, nil +} + +func GQLLockableName(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Lockable) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Lockable") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + name := "" + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) error { + name = node.Name() + return nil + }) + + if err != nil { + return nil, err + } + + return name, nil +} + +func GQLLockableRequirements(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Lockable) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Lockable") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var requirements []Lockable = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + requirements = node.Requirements() + return nil + }) + + if err != nil { + return nil, err + } + + return requirements, nil +} + +func GQLLockableDependencies(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Lockable) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Lockable") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var dependencies []Lockable = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + dependencies = node.Dependencies() + return nil + }) + + if err != nil { + return nil, err + } + + return dependencies, nil +} + +func GQLLockableOwner(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(Lockable) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to Lockable") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var owner Node = nil + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) (error) { + owner = node.Owner() + return nil + }) + + if err != nil { + return nil, err + } + + return owner, nil +} + +func GQLThreadUsers(p graphql.ResolveParams) (interface{}, error) { + node, ok := p.Source.(*GQLThread) + if ok == false || node == nil { + return nil, fmt.Errorf("Failed to cast source to GQLThread") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to cast context graph_context to Context") + } + + var users []*User + err := UseStates(ctx, []Node{node}, func(nodes NodeMap) error { + users = make([]*User, len(node.Users)) + i := 0 + for _, user := range(node.Users) { + users[i] = user + i += 1 + } + return nil + }) + + if err != nil { + return nil, err + } + + return users, nil +} + +func GQLSignalFn(p graphql.ResolveParams, fn func(GraphSignal, graphql.ResolveParams)(interface{}, error))(interface{}, error) { + if signal, ok := p.Source.(GraphSignal); ok { + return fn(signal, p) + } + return nil, fmt.Errorf("Failed to cast source to event") +} + +func GQLSignalType(p graphql.ResolveParams) (interface{}, error) { + return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ + return signal.Type(), nil + }) +} + +func GQLSignalSource(p graphql.ResolveParams) (interface{}, error) { + return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ + return signal.Source(), nil + }) +} + +func GQLSignalDirection(p graphql.ResolveParams) (interface{}, error) { + return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ + direction := signal.Direction() + if direction == Up { + return "up", nil + } else if direction == Down { + return "down", nil + } else if direction == Direct { + return "direct", nil + } + return nil, fmt.Errorf("Invalid direction: %+v", direction) + }) +} + +func GQLSignalString(p graphql.ResolveParams) (interface{}, error) { + return GQLSignalFn(p, func(signal GraphSignal, p graphql.ResolveParams)(interface{}, error){ + return signal.String(), nil + }) +} diff --git a/gql_subscribe.go b/gql_subscribe.go new file mode 100644 index 0000000..d1868ad --- /dev/null +++ b/gql_subscribe.go @@ -0,0 +1,82 @@ +package graphvent +import ( + "fmt" + "github.com/graphql-go/graphql" +) + +func GQLSubscribeSignal(p graphql.ResolveParams) (interface{}, error) { + return GQLSubscribeFn(p, false, func(ctx *Context, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { + return signal, nil + }) +} + +func GQLSubscribeSelf(p graphql.ResolveParams) (interface{}, error) { + return GQLSubscribeFn(p, true, func(ctx *Context, server *GQLThread, signal GraphSignal, p graphql.ResolveParams)(interface{}, error) { + return server, nil + }) +} + +func GQLSubscribeFn(p graphql.ResolveParams, send_nil bool, fn func(*Context, *GQLThread, GraphSignal, graphql.ResolveParams)(interface{}, error))(interface{}, error) { + server, ok := p.Context.Value("gql_server").(*GQLThread) + if ok == false { + return nil, fmt.Errorf("Failed to get gql_server from context and cast to GQLServer") + } + + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil, fmt.Errorf("Failed to get graph_context from context and cast to Context") + } + + c := make(chan interface{}) + go func(c chan interface{}, server *GQLThread) { + ctx.Log.Logf("gqlws", "GQL_SUBSCRIBE_THREAD_START") + sig_c := UpdateChannel(server, 1, RandID()) + if send_nil == true { + sig_c <- nil + } + for { + val, ok := <- sig_c + if ok == false { + return + } + ret, err := fn(ctx, server, val, p) + if err != nil { + ctx.Log.Logf("gqlws", "type convertor error %s", err) + return + } + c <- ret + } + }(c, server) + return c, nil +} + +var gql_subscription_self * graphql.Field = nil +func GQLSubscriptionSelf() * graphql.Field { + if gql_subscription_self == nil { + gql_subscription_self = &graphql.Field{ + Type: GQLTypeGQLThread(), + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return p.Source, nil + }, + Subscribe: GQLSubscribeSelf, + } + } + + return gql_subscription_self +} + +var gql_subscription_update * graphql.Field = nil +func GQLSubscriptionUpdate() * graphql.Field { + if gql_subscription_update == nil { + gql_subscription_update = &graphql.Field{ + Type: GQLTypeSignal(), + Resolve: func(p graphql.ResolveParams) (interface{}, error) { + return p.Source, nil + }, + Subscribe: GQLSubscribeSignal, + } + } + + return gql_subscription_update +} + diff --git a/gql_types.go b/gql_types.go new file mode 100644 index 0000000..755b527 --- /dev/null +++ b/gql_types.go @@ -0,0 +1,536 @@ +package graphvent + +import ( + "github.com/graphql-go/graphql" + "reflect" +) + +var gql_interface_graph_node *graphql.Interface = nil +func GQLInterfaceNode() *graphql.Interface { + if gql_interface_graph_node == nil { + gql_interface_graph_node = graphql.NewInterface(graphql.InterfaceConfig{ + Name: "Node", + ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil + } + + valid_nodes := ctx.GQL.ValidNodes + node_type := ctx.GQL.NodeType + p_type := reflect.TypeOf(p.Value) + + for key, value := range(valid_nodes) { + if p_type == key { + return value + } + } + + if p_type.Implements(node_type) { + return GQLTypeGraphNode() + } + + return nil + }, + Fields: graphql.Fields{}, + }) + + gql_interface_graph_node.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + }) + } + + return gql_interface_graph_node +} + +var gql_list_thread *graphql.List = nil +func GQLListThread() *graphql.List { + if gql_list_thread == nil { + gql_list_thread = graphql.NewList(GQLInterfaceThread()) + } + return gql_list_thread +} + +var gql_interface_thread *graphql.Interface = nil +func GQLInterfaceThread() *graphql.Interface { + if gql_interface_thread == nil { + gql_interface_thread = graphql.NewInterface(graphql.InterfaceConfig{ + Name: "Thread", + ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil + } + + valid_threads := ctx.GQL.ValidThreads + thread_type := ctx.GQL.ThreadType + p_type := reflect.TypeOf(p.Value) + + for key, value := range(valid_threads) { + if p_type == key { + return value + } + } + + if p_type.Implements(thread_type) { + return GQLTypeSimpleThread() + } + + ctx.Log.Logf("gql", "Found no type that matches %+v: %+v", p_type, p_type.Implements(thread_type)) + return nil + }, + Fields: graphql.Fields{}, + }) + + gql_interface_thread.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + }) + + gql_interface_thread.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + }) + + gql_interface_thread.AddFieldConfig("State", &graphql.Field{ + Type: graphql.String, + }) + + gql_interface_thread.AddFieldConfig("Children", &graphql.Field{ + Type: GQLListThread(), + }) + + gql_interface_thread.AddFieldConfig("Parent", &graphql.Field{ + Type: GQLInterfaceThread(), + }) + + gql_interface_thread.AddFieldConfig("Requirements", &graphql.Field{ + Type: GQLListLockable(), + }) + + gql_interface_thread.AddFieldConfig("Dependencies", &graphql.Field{ + Type: GQLListLockable(), + }) + + gql_interface_thread.AddFieldConfig("Owner", &graphql.Field{ + Type: GQLInterfaceLockable(), + }) + } + + return gql_interface_thread +} + +var gql_list_lockable *graphql.List = nil +func GQLListLockable() *graphql.List { + if gql_list_lockable == nil { + gql_list_lockable = graphql.NewList(GQLInterfaceLockable()) + } + return gql_list_lockable +} + +var gql_interface_lockable *graphql.Interface = nil +func GQLInterfaceLockable() *graphql.Interface { + if gql_interface_lockable == nil { + gql_interface_lockable = graphql.NewInterface(graphql.InterfaceConfig{ + Name: "Lockable", + ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return nil + } + + valid_lockables := ctx.GQL.ValidLockables + lockable_type := ctx.GQL.LockableType + p_type := reflect.TypeOf(p.Value) + + for key, value := range(valid_lockables) { + if p_type == key { + return value + } + } + + if p_type.Implements(lockable_type) { + return GQLTypeSimpleLockable() + } + return nil + }, + Fields: graphql.Fields{}, + }) + + gql_interface_lockable.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + }) + + gql_interface_lockable.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + }) + + if gql_list_lockable == nil { + gql_list_lockable = graphql.NewList(gql_interface_lockable) + } + + gql_interface_lockable.AddFieldConfig("Requirements", &graphql.Field{ + Type: gql_list_lockable, + }) + + gql_interface_lockable.AddFieldConfig("Dependencies", &graphql.Field{ + Type: gql_list_lockable, + }) + + gql_interface_lockable.AddFieldConfig("Owner", &graphql.Field{ + Type: gql_interface_lockable, + }) + + } + + return gql_interface_lockable +} + +var gql_list_user *graphql.List = nil +func GQLListUser() *graphql.List { + if gql_list_user == nil { + gql_list_user = graphql.NewList(GQLTypeUser()) + } + return gql_list_user +} + +var gql_type_user *graphql.Object = nil +func GQLTypeUser() * graphql.Object { + if gql_type_user == nil { + gql_type_user = graphql.NewObject(graphql.ObjectConfig{ + Name: "User", + Interfaces: []*graphql.Interface{ + GQLInterfaceNode(), + GQLInterfaceLockable(), + }, + IsTypeOf: func(p graphql.IsTypeOfParams) bool { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return false + } + + lockable_type := ctx.GQL.LockableType + value_type := reflect.TypeOf(p.Value) + + if value_type.Implements(lockable_type) { + return true + } + + return false + }, + Fields: graphql.Fields{}, + }) + + gql_type_user.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + Resolve: GQLNodeID, + }) + + gql_type_user.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + Resolve: GQLLockableName, + }) + + gql_type_user.AddFieldConfig("Requirements", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableRequirements, + }) + + gql_type_user.AddFieldConfig("Owner", &graphql.Field{ + Type: GQLInterfaceLockable(), + Resolve: GQLLockableOwner, + }) + + gql_type_user.AddFieldConfig("Dependencies", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableDependencies, + }) + } + return gql_type_user +} + +var gql_type_gql_thread *graphql.Object = nil +func GQLTypeGQLThread() * graphql.Object { + if gql_type_gql_thread == nil { + gql_type_gql_thread = graphql.NewObject(graphql.ObjectConfig{ + Name: "GQLThread", + Interfaces: []*graphql.Interface{ + GQLInterfaceNode(), + GQLInterfaceThread(), + GQLInterfaceLockable(), + }, + IsTypeOf: func(p graphql.IsTypeOfParams) bool { + _, ok := p.Value.(*GQLThread) + return ok + }, + Fields: graphql.Fields{}, + }) + + gql_type_gql_thread.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + Resolve: GQLNodeID, + }) + + gql_type_gql_thread.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + Resolve: GQLLockableName, + }) + + gql_type_gql_thread.AddFieldConfig("State", &graphql.Field{ + Type: graphql.String, + Resolve: GQLThreadState, + }) + + gql_type_gql_thread.AddFieldConfig("Children", &graphql.Field{ + Type: GQLListThread(), + Resolve: GQLThreadChildren, + }) + + gql_type_gql_thread.AddFieldConfig("Parent", &graphql.Field{ + Type: GQLInterfaceThread(), + Resolve: GQLThreadParent, + }) + + gql_type_gql_thread.AddFieldConfig("Listen", &graphql.Field{ + Type: graphql.String, + Resolve: GQLThreadListen, + }) + + gql_type_gql_thread.AddFieldConfig("Requirements", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableRequirements, + }) + + gql_type_gql_thread.AddFieldConfig("Owner", &graphql.Field{ + Type: GQLInterfaceLockable(), + Resolve: GQLLockableOwner, + }) + + gql_type_gql_thread.AddFieldConfig("Dependencies", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableDependencies, + }) + + gql_type_gql_thread.AddFieldConfig("Users", &graphql.Field{ + Type: GQLListUser(), + Resolve: GQLThreadUsers, + }) + } + return gql_type_gql_thread +} + +var gql_type_simple_thread *graphql.Object = nil +func GQLTypeSimpleThread() * graphql.Object { + if gql_type_simple_thread == nil { + gql_type_simple_thread = graphql.NewObject(graphql.ObjectConfig{ + Name: "SimpleThread", + Interfaces: []*graphql.Interface{ + GQLInterfaceNode(), + GQLInterfaceThread(), + GQLInterfaceLockable(), + }, + IsTypeOf: func(p graphql.IsTypeOfParams) bool { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return false + } + + thread_type := ctx.GQL.ThreadType + + value_type := reflect.TypeOf(p.Value) + + if value_type.Implements(thread_type) { + return true + } + + return false + }, + Fields: graphql.Fields{}, + }) + gql_type_simple_thread.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + Resolve: GQLNodeID, + }) + + gql_type_simple_thread.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + Resolve: GQLLockableName, + }) + + gql_type_simple_thread.AddFieldConfig("State", &graphql.Field{ + Type: graphql.String, + Resolve: GQLThreadState, + }) + + gql_type_simple_thread.AddFieldConfig("Children", &graphql.Field{ + Type: GQLListThread(), + Resolve: GQLThreadChildren, + }) + + gql_type_simple_thread.AddFieldConfig("Parent", &graphql.Field{ + Type: GQLInterfaceThread(), + Resolve: GQLThreadParent, + }) + + gql_type_simple_thread.AddFieldConfig("Requirements", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableRequirements, + }) + + gql_type_simple_thread.AddFieldConfig("Owner", &graphql.Field{ + Type: GQLInterfaceLockable(), + Resolve: GQLLockableOwner, + }) + + gql_type_simple_thread.AddFieldConfig("Dependencies", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableDependencies, + }) + } + return gql_type_simple_thread +} + +var gql_type_simple_lockable *graphql.Object = nil +func GQLTypeSimpleLockable() * graphql.Object { + if gql_type_simple_lockable == nil { + gql_type_simple_lockable = graphql.NewObject(graphql.ObjectConfig{ + Name: "SimpleLockable", + Interfaces: []*graphql.Interface{ + GQLInterfaceNode(), + GQLInterfaceLockable(), + }, + IsTypeOf: func(p graphql.IsTypeOfParams) bool { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return false + } + + lockable_type := ctx.GQL.LockableType + value_type := reflect.TypeOf(p.Value) + + if value_type.Implements(lockable_type) { + return true + } + + return false + }, + Fields: graphql.Fields{}, + }) + + gql_type_simple_lockable.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + Resolve: GQLNodeID, + }) + + gql_type_simple_lockable.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + Resolve: GQLLockableName, + }) + + gql_type_simple_lockable.AddFieldConfig("Requirements", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableRequirements, + }) + + gql_type_simple_lockable.AddFieldConfig("Owner", &graphql.Field{ + Type: GQLInterfaceLockable(), + Resolve: GQLLockableOwner, + }) + + gql_type_simple_lockable.AddFieldConfig("Dependencies", &graphql.Field{ + Type: GQLListLockable(), + Resolve: GQLLockableDependencies, + }) + } + return gql_type_simple_lockable +} + +var gql_type_simple_node *graphql.Object = nil +func GQLTypeGraphNode() * graphql.Object { + if gql_type_simple_node == nil { + gql_type_simple_node = graphql.NewObject(graphql.ObjectConfig{ + Name: "GraphNode", + Interfaces: []*graphql.Interface{ + GQLInterfaceNode(), + }, + IsTypeOf: func(p graphql.IsTypeOfParams) bool { + ctx, ok := p.Context.Value("graph_context").(*Context) + if ok == false { + return false + } + + node_type := ctx.GQL.NodeType + value_type := reflect.TypeOf(p.Value) + + if value_type.Implements(node_type) { + return true + } + + return false + }, + Fields: graphql.Fields{}, + }) + + gql_type_simple_node.AddFieldConfig("ID", &graphql.Field{ + Type: graphql.String, + Resolve: GQLNodeID, + }) + + gql_type_simple_node.AddFieldConfig("Name", &graphql.Field{ + Type: graphql.String, + Resolve: GQLLockableName, + }) + } + + return gql_type_simple_node +} + +var gql_type_signal *graphql.Object = nil +func GQLTypeSignal() *graphql.Object { + if gql_type_signal == nil { + gql_type_signal = graphql.NewObject(graphql.ObjectConfig{ + Name: "SignalOut", + IsTypeOf: func(p graphql.IsTypeOfParams) bool { + _, ok := p.Value.(GraphSignal) + return ok + }, + Fields: graphql.Fields{}, + }) + + gql_type_signal.AddFieldConfig("Type", &graphql.Field{ + Type: graphql.String, + Resolve: GQLSignalType, + }) + gql_type_signal.AddFieldConfig("Source", &graphql.Field{ + Type: graphql.String, + Resolve: GQLSignalSource, + }) + gql_type_signal.AddFieldConfig("Direction", &graphql.Field{ + Type: graphql.String, + Resolve: GQLSignalDirection, + }) + gql_type_signal.AddFieldConfig("String", &graphql.Field{ + Type: graphql.String, + Resolve: GQLSignalString, + }) + } + return gql_type_signal +} + +var gql_type_signal_input *graphql.InputObject = nil +func GQLTypeSignalInput() *graphql.InputObject { + if gql_type_signal_input == nil { + gql_type_signal_input = graphql.NewInputObject(graphql.InputObjectConfig{ + Name: "SignalIn", + Fields: graphql.InputObjectConfigFieldMap{}, + }) + gql_type_signal_input.AddFieldConfig("Type", &graphql.InputObjectFieldConfig{ + Type: graphql.String, + DefaultValue: "cancel", + }) + gql_type_signal_input.AddFieldConfig("Direction", &graphql.InputObjectFieldConfig{ + Type: graphql.String, + DefaultValue: "down", + }) + } + return gql_type_signal_input +} +