// New create a new executable plan given a semantic BQL statement. func New(store storage.Store, stm *semantic.Statement) (Excecutor, error) { switch stm.Type() { case semantic.Query: return newQueryPlan(store, stm) case semantic.Insert: return &insertPlan{ stm: stm, store: store, }, nil case semantic.Delete: return &deletePlan{ stm: stm, store: store, }, nil case semantic.Create: return &createPlan{ stm: stm, store: store, }, nil case semantic.Drop: return &dropPlan{ stm: stm, store: store, }, nil default: return nil, fmt.Errorf("planner.New: unknown statement type in statement %v", stm) } }
func update(stm *semantic.Statement, store storage.Store, f updater) error { var ( mu sync.Mutex wg sync.WaitGroup errs []string ) appendError := func(err error) { mu.Lock() defer mu.Unlock() errs = append(errs, err.Error()) } for _, graphBinding := range stm.Graphs() { wg.Add(1) go func(graph string) { defer wg.Done() g, err := store.Graph(graph) if err != nil { appendError(err) return } err = f(g, stm.Data()) if err != nil { appendError(err) } }(graphBinding) } wg.Wait() if len(errs) > 0 { return errors.New(strings.Join(errs, "; ")) } return nil }
// newQueryPlan returns a new query plan ready to be excecuted. func newQueryPlan(store storage.Store, stm *semantic.Statement) (*queryPlan, error) { bs := []string{} for _, b := range stm.Bindings() { bs = append(bs, b) } t, err := table.New([]string{}) if err != nil { return nil, err } var gs []storage.Graph for _, g := range stm.Graphs() { ng, err := store.Graph(g) if err != nil { return nil, err } gs = append(gs, ng) } return &queryPlan{ stm: stm, store: store, bndgs: bs, grfs: gs, grfsNames: stm.Graphs(), cls: stm.SortedGraphPatternClauses(), tbl: t, }, nil }