Example #1
0
triggerconfig_t * add_trigger(rulepackage_t * rpkg, zmsg_t * request,zmsg_t * reply) {
    char * rule_id  = zmsg_popstr(request);
    zclock_log("new trigger!");
    
    if (remove_rule(rpkg->context, rpkg->triggers, rule_id)) {
        // already have a rule with that id! 
      zclock_log("Received duplicate rule %s - killing old trigger", rule_id);
    } 
      
    triggerconfig_t * tconf = malloc(sizeof(triggerconfig_t));
    tconf->base_config = rpkg->base_config;
    create_triggerconfig(tconf, request, rpkg->channel, rule_id);
      
    // when we create this trigger, what guarantee do we have that
    // the line listener is active? FIX
    // basically we have none. crap.
    char * created = create_trigger(rpkg->triggers, rule_id, rpkg->context, tconf);
    if(NULL == created) {
      // happy path, so add to db
      zmsg_pushstr(reply, "ok");

    } else {
      zclock_log("create_trigger failed: %s", created);
      free(tconf);
      tconf=NULL;
      zmsg_pushstr(reply, created);
    }
    free(created);
    return tconf;    
    
}
Example #2
0
int load_and_start_trigger(void *rvoid, int argc, char ** argv,  char ** column) {
  triggerconfig_t * tconf = malloc(sizeof(triggerconfig_t));
  rulepackage_t * rpkg = (rulepackage_t *) rvoid;
  load_trigger(tconf, argc, argv, column);
  tconf->channel       = strdup(rpkg->channel);
  tconf->base_config   = rpkg->base_config;
  // this is a bit dodgy. we shouldn't really be creating triggers
  // from anywhere: we don't know that everything is in position to
  // receive triggers. should probably be sending this down the same
  // pipe that gets external requests.
  create_trigger(rpkg->triggers, argv[0], rpkg->context, tconf);
  return 0;
}
Example #3
0
int load_rule(void *rvoid, int argc, char ** argv,  char ** column) {
  int i;
  for(i=0;i<argc;i++) {
    printf("Argument %d is %s\n", i, argv[i]);
  }
  rulepackage_t * rpkg = (rulepackage_t *) rvoid;
  triggerconfig_t * tconf = malloc(sizeof(triggerconfig_t));
  tconf->rule_id       = strdup(argv[0]);
  tconf->trigger_name  = strdup(argv[1]);
  tconf->target_worker = strdup(argv[2]);
  tconf->auth          = strdup(argv[3]);
  tconf->addins        = strdup(argv[4]);
  tconf->channel       = strdup(rpkg->channel);
  // FIXME auth and addins are blobs. how do we pull them out?

  create_trigger(rpkg->rules, argv[0], rpkg->context, tconf);
}
Example #4
0
sql_rel *
rel_psm(mvc *sql, symbol *s)
{
	sql_rel *ret = NULL;

	switch (s->token) {
	case SQL_CREATE_FUNC:
	{
		dlist *l = s->data.lval;
		int type = l->h->next->next->next->next->next->data.i_val;
		int lang = l->h->next->next->next->next->next->next->data.i_val;

		ret = rel_create_func(sql, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.sym, l->h->next->next->next->data.lval, l->h->next->next->next->next->data.lval, type, lang);
		sql->type = Q_SCHEMA;
	} 	break;
	case SQL_DROP_FUNC:
	{
		dlist *l = s->data.lval;
		int type = l->h->next->next->next->next->data.i_val;

		if (STORE_READONLY) 
			return sql_error(sql, 06, "schema statements cannot be executed on a readonly database.");
			
		assert(l->h->next->type == type_int);
		assert(l->h->next->next->next->type == type_int);
		if (l->h->next->data.i_val) /*?l_val?*/
			ret = rel_drop_all_func(sql, l->h->data.lval, l->h->next->next->next->data.i_val, type);
		else
			ret = rel_drop_func(sql, l->h->data.lval, l->h->next->next->data.lval, l->h->next->next->next->data.i_val, type);

		sql->type = Q_SCHEMA;
	}	break;
	case SQL_SET:
		ret = rel_psm_stmt(sql->sa, psm_set_exp(sql, s->data.lval->h));
		sql->type = Q_SCHEMA;
		break;
	case SQL_DECLARE:
		ret = rel_psm_block(sql->sa, rel_psm_declare(sql, s->data.lval->h));
		sql->type = Q_SCHEMA;
		break;
	case SQL_CALL:
		ret = rel_psm_stmt(sql->sa, rel_psm_call(sql, s->data.sym));
		sql->type = Q_UPDATE;
		break;
	case SQL_CREATE_TRIGGER:
	{
		dlist *l = s->data.lval;

		assert(l->h->next->type == type_int);
		ret = create_trigger(sql, l->h->data.lval, l->h->next->data.i_val, l->h->next->next->data.sym, l->h->next->next->next->data.sval, l->h->next->next->next->next->data.lval, l->h->next->next->next->next->next->data.lval);
		sql->type = Q_SCHEMA;
	}
		break;

	case SQL_DROP_TRIGGER:
	{
		dlist *l = s->data.lval;

		ret = drop_trigger(sql, l);
		sql->type = Q_SCHEMA;
	}
		break;

	case SQL_ANALYZE: {
		dlist *l = s->data.lval;

		ret = psm_analyze(sql, l->h->data.lval /* qualified table name */, l->h->next->data.lval /* opt list of column */, l->h->next->next->data.sym /* opt_sample_size */);
		sql->type = Q_UPDATE;
	} 	break;
	default:
		return sql_error(sql, 01, "schema statement unknown symbol(" PTRFMT ")->token = %s", PTRFMTCAST s, token2string(s->token));
	}
	return ret;
}
Example #5
0
void generic_worker(void * cvoid, zctx_t * context, void * pipe) {
  workerconfig_t *config = (workerconfig_t*) cvoid;
  zhash_t * rules = zhash_new();

  child_handshake(pipe);
  zmsg_t *reply = NULL;
  void * rule_pipe = NULL;
  char * ninja = config->base_config->identity;
  char * channel = config->channel;

  char * servicename = malloc(strlen(ninja) +
                              strlen(channel) + 2);
  sprintf(servicename, "%s:%s", ninja,channel);

  // sqlite stuff
  int rc;
  char * tail = NULL;
  sqlite3 *db = init_db(servicename);
  sqlite3_stmt * insert_stmt;
  zclock_log("%s worker preparing rules...", servicename);
  sqlite3_prepare_v2(db, "insert into rules VALUES (@RULEID, @TRIGGER_NAME, @TARGET_WORKER, @AUTH, @ADDINS);", 512, &insert_stmt, NULL);
  zclock_log("%s worker reloading rules...", servicename);
  reload_rules(context, db, servicename, channel, rules);
  zclock_log("%s worker connecting...", servicename);
  mdwrk_t *session = mdwrk_new (config->base_config->broker_endpoint, servicename, 0);
  zclock_log("%s worker connected!", servicename);

  while (1) {
    zclock_log("%s worker waiting for work.", servicename);
    zmsg_t *request = mdwrk_recv (session, &reply);

    if (request == NULL)
      break;              //  Worker was interrupted

    char * command = zmsg_popstr(request);
    char * rule_id = zmsg_popstr(request);

    zclock_log("%s worker servicing request %s for rule %s", servicename,command,rule_id);
    reply = zmsg_new();
    if (strcmp(command, "AddTrigger") == 0) {
      zclock_log("new trigger!");
      if (zhash_lookup(rules, rule_id)) {
        // already have a rule with that id! WTF??
        // FIXME should probably delete this and reinstate
        zclock_log("Received duplicate rule %s, ignoring", rule_id);
        zmsg_destroy(&request);

        zmsg_pushstr(reply, "duplicate");
      } else {
        triggerconfig_t * tconf = malloc(sizeof(triggerconfig_t));
        create_triggerconfig(tconf, request, channel, rule_id);
        char * created = create_trigger(rules, rule_id, context, tconf);
        if(NULL == created) {
          // happy path, so add to db
          sqlite3_bind_text(insert_stmt, 1, tconf->rule_id, -1, SQLITE_TRANSIENT);
          sqlite3_bind_text(insert_stmt, 2, tconf->trigger_name, -1, SQLITE_TRANSIENT);
          sqlite3_bind_text(insert_stmt, 3, tconf->target_worker, -1, SQLITE_TRANSIENT);
          sqlite3_bind_text(insert_stmt, 4, tconf->auth, -1, SQLITE_TRANSIENT);
          sqlite3_bind_text(insert_stmt, 5, tconf->addins, -1, SQLITE_TRANSIENT);
          sqlite3_step(insert_stmt);
          sqlite3_clear_bindings(insert_stmt);
          sqlite3_reset(insert_stmt);

          zmsg_pushstr(reply, "ok");
        } else {
          zclock_log("create_trigger failed: %s", created);
          zmsg_pushstr(reply, created);
        }
        free(created);

      }
    } else if (strcmp(command,"RemoveRule") == 0) {

      if (rule_pipe=zhash_lookup(rules, rule_id)) {
        // found it
        zclock_log("rule %s exists, removing.", rule_id);
        send_sync("Destroy",rule_pipe);
        zclock_log("rule %s waiting for OK from pipe", rule_id);
        recv_sync("ok", rule_pipe);
        zsocket_destroy(context, rule_pipe);
        zhash_delete(rules, rule_id);
        zmsg_pushstr(reply, "ok");
        zclock_log("rule %s completely destroyed", rule_id);
      } else {
        // not there!
        zclock_log("Received delete trigger request for nonexistent rule %s, ignoring", rule_id);
        zmsg_pushstr(reply, "rule not found");
      }
    } else if (strcmp(command, "AddMonitor")==0) {
      // unconditionally fork a monitor for each line
      // they'll die when they get a channel change
      int i;
      for(i=1; i<4; i++) { 
        monitorconfig_t * mconf = malloc(sizeof(monitorconfig_t));
        mconf->line_id = i;
        mconf->source_worker = servicename;
        mconf->out_socket = config->base_config->portwatcher_endpoint;
        mconf->channel = channel;
        void * monitor_pipe = zthread_fork(context, watch_port, (void*)mconf);
        send_sync("ping", monitor_pipe);
        recv_sync("pong", monitor_pipe);
        zsocket_destroy(context, monitor_pipe);
      }
      zmsg_pushstr(reply, "ok");
    } else {
      zclock_log("Can't handle command %s: ignoring", command);
    }
    zmsg_destroy(&request);
  }
  mdwrk_destroy (&session);
  return;
}
Example #6
0
sql_rel *
rel_psm(mvc *sql, symbol *s)
{
	sql_rel *ret = NULL;

	switch (s->token) {
	case SQL_CREATE_FUNC:
	{
		dlist *l = s->data.lval;
		int type = l->h->next->next->next->next->next->data.i_val;
		int lang = l->h->next->next->next->next->next->next->data.i_val;
		int repl = l->h->next->next->next->next->next->next->next->data.i_val;

		ret = rel_create_func(sql, l->h->data.lval, l->h->next->data.lval, l->h->next->next->data.sym, l->h->next->next->next->data.lval, l->h->next->next->next->next->data.lval, type, lang, repl);
		sql->type = Q_SCHEMA;
	} 	break;
	case SQL_DROP_FUNC:
	{
		dlist *l = s->data.lval;
		dlist *qname = l->h->data.lval;
		dlist *typelist = l->h->next->data.lval;
		int type = l->h->next->next->data.i_val;
		int if_exists = l->h->next->next->next->data.i_val;
		int all = l->h->next->next->next->next->data.i_val;
		int drop_action = l->h->next->next->next->next->next->data.i_val;

		if (STORE_READONLY) 
			return sql_error(sql, 06, SQLSTATE(42000) "Schema statements cannot be executed on a readonly database.");
			
		if (all)
			ret = rel_drop_all_func(sql, qname, drop_action, type);
		else {
			ret = rel_drop_func(sql, qname, typelist, drop_action, type, if_exists);
		}

		sql->type = Q_SCHEMA;
	}	break;
	case SQL_SET:
		ret = rel_psm_stmt(sql->sa, psm_set_exp(sql, s->data.lval->h));
		sql->type = Q_SCHEMA;
		break;
	case SQL_DECLARE:
		ret = rel_psm_block(sql->sa, rel_psm_declare(sql, s->data.lval->h));
		sql->type = Q_SCHEMA;
		break;
	case SQL_CALL:
		ret = rel_psm_stmt(sql->sa, rel_psm_call(sql, s->data.sym));
		sql->type = Q_UPDATE;
		break;
	case SQL_CREATE_TABLE_LOADER:
	{
	    dlist *l = s->data.lval;
	    dlist *qname = l->h->data.lval;
	    symbol *sym = l->h->next->data.sym;

	    ret = create_table_from_loader(sql, qname, sym);
	    if (ret == NULL)
		    return NULL;
	    ret = rel_psm_stmt(sql->sa, exp_rel(sql, ret));
	    sql->type = Q_SCHEMA;
	}	break;
	case SQL_CREATE_TRIGGER:
	{
		dlist *l = s->data.lval;

		assert(l->h->next->type == type_int);
		ret = create_trigger(sql, l->h->data.lval, l->h->next->data.i_val, l->h->next->next->data.sym, l->h->next->next->next->data.lval, l->h->next->next->next->next->data.lval, l->h->next->next->next->next->next->data.lval, l->h->next->next->next->next->next->next->data.i_val);
		sql->type = Q_SCHEMA;
	}
		break;

	case SQL_DROP_TRIGGER:
	{
		dlist *l = s->data.lval;
		dlist *qname = l->h->data.lval;
		int if_exists = l->h->next->data.i_val;

		ret = drop_trigger(sql, qname, if_exists);
		sql->type = Q_SCHEMA;
	}
		break;

	case SQL_ANALYZE: {
		dlist *l = s->data.lval;

		ret = psm_analyze(sql, "analyze", l->h->data.lval /* qualified table name */, l->h->next->data.lval /* opt list of column */, l->h->next->next->data.sym /* opt_sample_size */, l->h->next->next->next->data.i_val);
		sql->type = Q_UPDATE;
	} 	break;
	default:
		return sql_error(sql, 01, SQLSTATE(42000) "Schema statement unknown symbol(%p)->token = %s", s, token2string(s->token));
	}
	return ret;
}