// Delete using a Where Expression func (m *dbConn) DeleteExpression(where expr.Node) (int, error) { //return 0, fmt.Errorf("not implemented") evaluator := vm.Evaluator(where) var deletedKeys []schema.Key txn := m.db.Txn(true) iter, err := txn.Get(m.md.tbl.Name, m.md.primaryIndex) if err != nil { txn.Abort() u.Errorf("could not get values %v", err) return 0, err } deleteLoop: for { item := iter.Next() if item == nil { break } msg, ok := item.(datasource.SqlDriverMessage) if !ok { u.Warnf("wat? %T %#v", item, item) err = fmt.Errorf("unexpected message type %T", item) break } whereValue, ok := evaluator(msg.ToMsgMap(m.md.tbl.FieldPositions)) if !ok { u.Debugf("could not evaluate where: %v", msg) } switch whereVal := whereValue.(type) { case value.BoolValue: if whereVal.Val() == false { //this means do NOT delete } else { // Delete! if err = txn.Delete(m.md.tbl.Name, msg); err != nil { u.Errorf("could not delete %v", err) break deleteLoop } indexVal := msg.Vals[0] deletedKeys = append(deletedKeys, schema.NewKeyUint(makeId(indexVal))) } case nil: // ?? u.Warnf("this should be fine, couldn't evaluate so don't delete %v", msg) default: if whereVal.Nil() { // Doesn't match, so don't delete } else { u.Warnf("unknown where eval result? %T", whereVal) } } } if err != nil { txn.Abort() return 0, err } txn.Commit() return len(deletedKeys), nil }
func whereFilter(where expr.Node, task TaskRunner, cols map[string]*expr.Column) MessageHandler { out := task.MessageOut() evaluator := vm.Evaluator(where) return func(ctx *Context, msg datasource.Message) bool { var whereValue value.Value var ok bool switch mt := msg.(type) { case *datasource.SqlDriverMessage: //u.Debugf("WHERE: T:%T vals:%#v", msg, mt.Vals) //u.Debugf("cols: %#v", cols) msgReader := datasource.NewValueContextWrapper(mt, cols) whereValue, ok = evaluator(msgReader) case *datasource.SqlDriverMessageMap: whereValue, ok = evaluator(mt) //u.Debugf("WHERE: result:%v T:%T vals:%#v", whereValue, msg, mt.Values()) //u.Debugf("cols: %#v", cols) default: if msgReader, ok := msg.(expr.ContextReader); ok { whereValue, ok = evaluator(msgReader) } else { u.Errorf("could not convert to message reader: %T", msg) } } //u.Debugf("msg: %#v", msgReader) //u.Infof("evaluating: ok?%v result=%v where expr:%v", ok, whereValue.ToString(), where.StringAST()) if !ok { u.Debugf("could not evaluate: %v", msg) return false } switch whereVal := whereValue.(type) { case value.BoolValue: if whereVal.Val() == false { //u.Debugf("Filtering out: T:%T v:%#v", whereVal, whereVal) return true } case nil: return false default: if whereVal.Nil() { return false } } //u.Debugf("about to send from where to forward: %#v", msg) select { case out <- msg: return true case <-task.SigChan(): return false } } }
// Delete using a Where Expression func (m *StaticDataSource) DeleteExpression(where expr.Node) (int, error) { //return 0, fmt.Errorf("not implemented") evaluator := vm.Evaluator(where) deletedKeys := make([]*Key, 0) m.bt.Ascend(func(a btree.Item) bool { di, ok := a.(*DriverItem) if !ok { u.Warnf("wat? %T %#v", a, a) return false } msgCtx := di.SqlDriverMessageMap whereValue, ok := evaluator(msgCtx) if !ok { u.Debugf("could not evaluate where: %v", msgCtx.Values()) //return deletedCt, fmt.Errorf("Could not evaluate where clause") return true } switch whereVal := whereValue.(type) { case value.BoolValue: if whereVal.Val() == false { //this means do NOT delete } else { // Delete! indexVal := msgCtx.Values()[m.indexCol] deletedKeys = append(deletedKeys, NewKey(makeId(indexVal))) } case nil: // ?? default: if whereVal.Nil() { // Doesn't match, so don't delete } else { u.Warnf("unknown type? %T", whereVal) } } return true }) for _, deleteKey := range deletedKeys { //u.Debugf("calling delete: %v", deleteKey) if ct, err := m.Delete(deleteKey); err != nil { u.Errorf("Could not delete key: %v", deleteKey) } else if ct != 1 { u.Errorf("delete should have removed 1 key %v", deleteKey) } } return len(deletedKeys), nil }
func whereFilter(where expr.Node, task TaskRunner) MessageHandler { out := task.MessageOut() evaluator := vm.Evaluator(where) return func(ctx *Context, msg datasource.Message) bool { // defer func() { // if r := recover(); r != nil { // u.Errorf("crap, %v", r) // } // }() if msgReader, ok := msg.Body().(expr.ContextReader); ok { whereValue, ok := evaluator(msgReader) //u.Debugf("msg: %#v", msgReader) //u.Infof("evaluating: ok?%v result=%v where expr:%v", ok, whereValue.ToString(), where.StringAST()) if !ok { u.Errorf("could not evaluate: %v", msg) return false } switch whereVal := whereValue.(type) { case value.BoolValue: if whereVal.Val() == false { //u.Debugf("Filtering out") return true } else { //u.Debugf("NOT FILTERED OUT") } default: u.Warnf("unknown type? %T", whereVal) } } else { u.Errorf("could not convert to message reader: %T", msg.Body()) } //u.Debug("about to send from where to forward") select { case out <- msg: return true case <-task.SigChan(): return false } } }