コード例 #1
0
ファイル: PPDropTrigger.cpp プロジェクト: bitkeeper/sedna
void PPDropTrigger::do_execute()
{
    tuple_cell tc;
    xqp_tuple t(1);
    trigger_name.op->next(t);
    if (t.is_eos()) throw USER_EXCEPTION(SE1071);

    tc = trigger_name.get(t);
    if (!tc.is_atomic() || tc.get_atomic_type() != xs_string)
        throw USER_EXCEPTION(SE1071);

    trigger_name.op->next(t);
    if (!t.is_eos()) throw USER_EXCEPTION(SE1071);

    tc = tuple_cell::make_sure_light_atomic(tc);

    local_lock_mrg->put_lock_on_trigger(tc.get_str_mem());

    if(find_trigger(tc.get_str_mem()) == XNULL)
        throw USER_EXCEPTION2(SE3211, (std::string("Trigger '") + tc.get_str_mem() + "'").c_str());

    auth_for_drop_object(tc.get_str_mem(), "trigger", false);

    delete_trigger(tc.get_str_mem());
}
コード例 #2
0
ファイル: triggers.c プロジェクト: jimmyskull/Wooki
void activate_trigger(const char *name, void **list, const int num) {
    \
    struct trigger_info        *info;
    struct user_trigger        *tr;
    wobject_i                *obj;
    int                        index;

    debug(3 , _("activate_trigger(\"%s\", %p, %u)\n"), name, list, num);
    if (rtl.current_obj == NO_SELECTED_OBJECT) {
        error(_("You must select a object before use commands.\n"));
        return;
    }
    index = find_trigger(name);
    if (index == TRNOT_FOUND) {
        debug(2, _("Trigger not found.\n"));
        return;
    }
    obj = rtl.objects.list[rtl.current_obj];
    if (obj->object == NULL && !cmp("new", name)) {
        if (!rtl.safe_working)
            out(_("%s%sWarning%s: object is null!\n"), CC_BOLD,
                CC_RED, CC_RESTORE);
        else {
            error(_("%s%sError%s: operation blocked by safe_working. "
                    "(object is null)\n"), CC_BOLD,
                  CC_RED, CC_RESTORE);
            return;
        }
    }
    tr = obj->triggers[index];
    if (tr->minparam != NOLIMIT && num < tr->minparam) {
        debug(2, _("Skipping trigger: number of parameteres do not"
                   " reach minimum allowed.\n"));
        return;
    }
    if (tr->maxparam != NOLIMIT && num > tr->maxparam) {
        debug(2, _("Skipping trigger: number of parameteres ultrapass"
                   " maximum allowed.\n"));
        return;
    }
    info = TALLOC(struct trigger_info);
    assert(info != NULL);
    info->debug_level = rtl.debuglevel;
    info->item_size = getsizeof(rtl.type);
    info->list = list;
    info->list_num = (size_t) num;
    info->opcode = (char *) name;
    info->object = obj->object;


    debug(3, _("Calling user trigger..\n"));
    tr->function(info);

    if (info->object != obj->object) {
        debug(3, _("\tUpdating object pointer from %p to %p\n"),
              obj->object, info->object);
        obj->object = info->object;
    }
    free(info);
}
コード例 #3
0
ファイル: triggers.cpp プロジェクト: sedna/sedna
void delete_trigger (const char *trigger_title)
{
    trigger_cell_cptr trc = find_trigger(trigger_title);
    if (trc.found())
    {
        down_concurrent_micro_ops_number();
        hl_logical_log_trigger(
            trc->trigger_time,
            trc->trigger_event,
            trc->trigger_path,
            trc->trigger_granularity,
            trc->trigger_action,
            trc->innode,
            trc->path_to_parent,
            trc->trigger_title,
            trc->doc_name,
            trc->is_doc,
            false);

        trc->drop();

        up_concurrent_micro_ops_number();
    }
}
コード例 #4
0
ファイル: triggers.cpp プロジェクト: sedna/sedna
trigger_cell_xptr create_trigger (enum trigger_time tr_time,
                                  enum trigger_event tr_event,
                                  xpath::PathExpression *trigger_path,
                                  enum trigger_granularity tr_gran,
                                  scheme_list* action,
                                  inserting_node innode,
                                  xpath::PathExpression *path_to_parent,
                                  doc_schema_node_xptr schemaroot,
                                  const char * trigger_title,
                                  const char* doc_name,
                                  bool is_doc)
{
    // I. Create and fill new trigger cell
    if (find_trigger(trigger_title) != XNULL)
    {
        throw USER_EXCEPTION(SE3200);
    }
    down_concurrent_micro_ops_number();

    trigger_cell_cptr trc(trigger_cell_object::create(trigger_title, schemaroot), true);

    schemaroot.modify()->full_trigger_list->add(trc.ptr());
    trc->trigger_path        = trigger_path;
    trc->trigger_event       = tr_event;
    trc->trigger_time        = tr_time;
    trc->trigger_granularity = tr_gran;

    if (rcv_tac != NULL) // recovery mode
    {
        trc->trigger_action = rcv_tac; // trigger_action_cell sequence has already been recovered from logical log
        rcv_tac = NULL;
    }
    else
    {
        trc->trigger_action = (trigger_action_cell*)malloc(sizeof(trigger_action_cell));
        trigger_action_cell* trac = trc->trigger_action;
        for (std::vector<scm_elem>::size_type i = 0; i < action->size(); i++)
        {
            trac->statement = (char*)malloc(strlen(action->at(i).internal.str)+1);
            strcpy(trac->statement,action->at(i).internal.str);

            if (i == action->size() - 1)
                trac->next = NULL;
            else
                trac->next = (trigger_action_cell*)malloc(sizeof(trigger_action_cell));

            trac = trac->next;
            RECOVERY_CRASH;
        }
    }

    // if the trigger is on before insert and statement level
    if((trc->trigger_event == TRIGGER_INSERT_EVENT) &&
       (trc->trigger_time == TRIGGER_BEFORE) &&
       (trc->trigger_granularity == TRIGGER_FOR_EACH_NODE)&&
       (path_to_parent))
    {
        trc->path_to_parent = path_to_parent;
        trc->innode = inserting_node(innode.name, innode.type);
    }
    else
    {
        trc->path_to_parent = NULL;
    }
    trc->doc_name = (char*)malloc(strlen(doc_name)+1);
    strcpy(trc->doc_name,doc_name);
    trc->is_doc=is_doc;

    hl_logical_log_trigger(tr_time, tr_event, trigger_path, tr_gran, trc->trigger_action, trc->innode, path_to_parent, trigger_title, doc_name, is_doc, true);

    //II. Execute abs path (object_path) on the desriptive schema
    t_scmnodes sobj;
    executePathExpression(schemaroot, *trigger_path, &sobj, NULL, NULL);

    //III. For each schema node found (sn_obj)
    std::vector<xptr> start_nodes;
    for (size_t i = 0; i < sobj.size(); i++)
    {
        sobj[i].modify()->trigger_list->add(trc.ptr());
        RECOVERY_CRASH;
    }

    up_concurrent_micro_ops_number();

    return trc.ptr();
}
コード例 #5
0
void trigger(void *cvoid, 
             zctx_t * context, 
             void * control) {
  triggerconfig_t * c = (triggerconfig_t*) cvoid;
  //set up msgpack stuff
  zclock_log("watch_port started!");
  msgpack_zone mempool;
  msgpack_zone_init(&mempool, 2048);

  // TODO
  char * user_id = "17"; 
  // TODO get broker in somehow
  char * broker = "tcp://au.ninjablocks.com:5773";

  mdcli_t * client = mdcli_new(broker, 1); //VERBOSE

  triggermemory_t trigger_memory;
  msgpack_object * addins_obj = parse_msgpack(&mempool, c->addins);

  if(!parse_addins(addins_obj, &trigger_memory)) {
    //bad message
    zclock_log("bad trigger definition");
    msgpack_object_print(stdout, *addins_obj);
    send_sync("bad trigger", control);
    return;
  }
  zclock_log("Creating trigger: target %s, rule_id %s, name %s", 
             c->target_worker, c->rule_id, c->trigger_name);
  dump_trigger(&trigger_memory);
  triggerfunction trigger_func;
  if(!(trigger_func = find_trigger(c->channel, c->trigger_name))) {

    zclock_log("no trigger found for channel %s, trigger %s",
               c->channel, c->trigger_name);
    send_sync("no such trigger", control);
    return;
  }

  void * line = zsocket_new(context, ZMQ_SUB);


  // what line are we on?
  // this comes in the addins. 
  char * linesocket = to_linesocket(trigger_memory.line_id);
  zclock_log("trigger is connecting to listen on %s", linesocket);
  zsocket_connect(line, linesocket);

  zsockopt_set_unsubscribe(line, "");
  zsockopt_set_subscribe(line, "VALUE");
  recv_sync("ping", control);
  send_sync("pong", control);
  
  zmq_pollitem_t items [] = {
    { line, 0, ZMQ_POLLIN, 0 },
    { control, 0, ZMQ_POLLIN, 0 }
  };
  while(1) {
    // listen on control and line
    zmq_poll (items, 2, -1);
    if (items[1].revents & ZMQ_POLLIN) {
      zclock_log("rule %s received message on control pipe", c->rule_id);
      // control message
      // really only expecting DESTROY
      zmsg_t * msg = zmsg_recv(control);
      char * str = zmsg_popstr(msg);
      zmsg_destroy(&msg);
      
      if (strcmp("Destroy", str) == 0) {
        zclock_log("rule %s will quit on request", c->rule_id);
        free(str);
        send_sync("ok", control);
        zclock_log("rule %s quitting on request", c->rule_id);
        break;
      } else  {
        zclock_log("unexpected command %s for rule %s", str, c->rule_id);
        free(str);
        send_sync("ok", control);
      }
    }

    if (items[0].revents & ZMQ_POLLIN) {
      // serial update
      zmsg_t * msg = zmsg_recv(line);
      zframe_t * cmd = zmsg_pop(msg);
      if(zframe_streq(cmd, "CHANNEL_CHANGE")) {
        // TODO
        // must have been dormant to have gotten this
        char * new_channel = zmsg_popstr(msg);

        if(strcmp(c->channel, new_channel) == 0) {
        // oh, happy day! We're relevant again.
        // reactivate and start looking at reset levels.
          zclock_log("line %d: changed channel from %s to %s: trigger coming back to life", trigger_memory.line_id, c->channel, new_channel);
          zsockopt_set_subscribe(line, "VALUE");
          zsockopt_set_unsubscribe(line, "CHANNEL_CHANGE");
        }
        free(new_channel);
      } else if (zframe_streq(cmd, "VALUE")) {
        zframe_t * vframe = zmsg_pop(msg);
        int value;
        memcpy(&value, zframe_data(vframe), sizeof(int));
        char * update_channel = zmsg_popstr(msg);

        if(strcmp(c->channel, update_channel) != 0) {
          // channel changed,  go dormant
          // this is legit according to my tests at
          // https://gist.github.com/2042350

          zclock_log("line %d: changed channel from %s to %s: trigger going dormant", trigger_memory.line_id, c->channel, update_channel);
          zsockopt_set_subscribe(line, "CHANNEL_CHANGE");
          zsockopt_set_unsubscribe(line, "VALUE");
        } 
        
        else if(trigger_func(&trigger_memory, value)) {
          send_trigger(client, c->target_worker, c->rule_id, value, user_id);
        }           

        free(update_channel);
      } else {
        // shouldn't ever happen.
        zclock_log("shouldn't have received command %s\n", zframe_strdup(cmd));
      }
      zmsg_destroy(&msg);
      zframe_destroy(&cmd);
    }
    
  }

  msgpack_zone_destroy(&mempool);
}