/*doc Memcached stats Returns a Map with servers' statistics. Keys are server addresses, values are maps with actual stats. */ IoObject *IoMemcached_stats(IoMemcached *self, IoObject *locals, IoMessage *m) { IoMap *results_map = IoMap_new(IOSTATE); int errors = 0; uint32_t pos = 0; while(pos < memcached_server_count(DATA(self)->mc)) { memcached_server_instance_st server = memcached_server_instance_by_position(DATA(self)->mc, pos); if(server == NULL) continue; const char *hostname = memcached_server_name(server); const in_port_t port = memcached_server_port(server); memcached_stat_st stats; memcached_return_t rc = memcached_stat_servername(&stats, "", hostname, port); if(rc != MEMCACHED_SUCCESS) { errors++; continue; } char **ckeys = memcached_stat_get_keys(DATA(self)->mc, &stats, &rc); if(rc != MEMCACHED_SUCCESS) { errors++; continue; } IoMap *per_server_map = IoMap_new(IOSTATE); char *ckey = *ckeys; while(ckey != NULL) { char *cvalue = memcached_stat_get_value(DATA(self)->mc, &stats, ckey, &rc); if(rc != MEMCACHED_SUCCESS) { errors++; continue; } IoMap_rawAtPut(per_server_map, IOSYMBOL(ckey), IOSYMBOL(cvalue)); free(cvalue); ckey++; } free(ckeys); // "127.0.0.1:11211" char *server_key = (char *) malloc((strlen(hostname) + 1 + 5 + 1) * sizeof(char)); sprintf(server_key, "%s:%d", hostname, port); IoMap_rawAtPut(results_map, IOSYMBOL(server_key), per_server_map); free(server_key); pos++; } if(errors > 0) IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, MEMCACHED_SOME_ERRORS)); return results_map; }
IoCFFIPointer *IoCFFIPointer_proto(void *state) { IoObject *self = IoCFFIDataType_new(state); IoObject_tag_(self, IoCFFIPointer_newTag(state)); IoObject_setSlot_to_(self, IOSYMBOL("pointers"), IoMap_new(state)); IoObject_setDataPointer_(self, calloc(1, sizeof(IoCFFIPointerData))); memset(DATA(self), 0, sizeof(IoCFFIPointerData)); DATA(self)->valuePointer = &(DATA(self)->ptr); IoState_registerProtoWithFunc_(state, self, IoCFFIPointer_proto); { IoMethodTable methodTable[] = { {"address", IoCFFIPointer_address}, {"asBuffer", IoCFFIPointer_asBuffer}, {"at", IoCFFIPointer_at}, {"atPut", IoCFFIPointer_atPut}, {"castTo", IoCFFIPointer_castTo}, {"value", IoCFFIPointer_value}, {"setValue", IoCFFIPointer_setValue}, {"toType", IoCFFIPointer_toType}, {NULL, NULL}, }; IoObject_addMethodTable_(self, methodTable); } return self; }
static int IoSQLite3_resultRow(void *context, int argc, char **argv, char **azColName) { IoSQLite3 *self = context; IoState_pushRetainPool(IOSTATE); { IoMap *map = IoMap_new(IOSTATE); PHash *hash = IoMap_rawHash(map); int i; IoSymbol *key, *value; for(i = 0; i < argc; i ++) { key = IOSYMBOL(azColName[i]); if (argv[i]) { value = IOSYMBOL(argv[i]); } else { value = IOSYMBOL((char *)"NULL"); } PHash_at_put_(hash, key, value); /*printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); */ } IoList_rawAppend_(DATA(self)->results, map); } IoState_popRetainPool(IOSTATE); return 0; }
IoCInvokeStructure *IoCInvokeStructure_rawClone(IoCInvokeStructure *proto) { IoObject *self = IoObject_rawClonePrimitive(proto); IoObject_setDataPointer_(self, calloc(1, sizeof(IoCInvokeStructureData))); IoObject_setSlot_to_(self, IOSYMBOL("memberTypes"), IoMap_new(IOSTATE)); return self; }
IoObject *IoRegex_namedCaptures(IoRegex *self, IoObject *locals, IoMessage *m) { /*doc Regex namedCaptures Returns a Map that contains the index of each named group. */ IoMap *map = DATA(self)->namedCaptures; NamedCapture *namedCaptures = 0, *capture = 0; if (map) return map; map = DATA(self)->namedCaptures = IOREF(IoMap_new(IOSTATE)); capture = namedCaptures = Regex_namedCaptures(IoRegex_rawRegex(self)); if (!namedCaptures) return map; while (capture->name) { IoMap_rawAtPut(map, IOSYMBOL(capture->name), IONUMBER(capture->index)); capture++; } free(namedCaptures); return map; }
/*doc Memcached getMulti(keys) Asks memcached to retrieve data corresponding to the list of keys. Returns a Map with the results. If some of the keys appearing in a retrieval request are not sent back by the server in the item list this means that the server does not hold items with such keys */ IoObject *IoMemcached_getMulti(IoMemcached *self, IoObject *locals, IoMessage *m) { IoList *keys_list = IoMessage_locals_listArgAt_(m, locals, 0); size_t keys_list_size = IoList_rawSize(keys_list); IoObject *results_map = IoMap_new(IOSTATE); if(keys_list_size == 0) return results_map; int i; for(i = 0; i < keys_list_size; i++) { IoSeq *key = IoList_rawAt_(keys_list, i); IOASSERT(ISSEQ(key), "key must be a Sequence"); IOASSERT(IOSEQ_LENGTH(key) > 0, "key cannot be an empty Sequence"); IOASSERT(IOSEQ_LENGTH(key) < MEMCACHED_MAX_KEY, "key is too long"); } const char **ckeys = (const char **) malloc(sizeof(const char *) * keys_list_size); size_t *ckey_lengths = (size_t *) malloc(sizeof(size_t) * keys_list_size); for(i = 0; i < keys_list_size; i++) { ckeys[i] = CSTRING(IoList_rawAt_(keys_list, i)); ckey_lengths[i] = strlen(ckeys[i]); } memcached_return_t rc = memcached_mget(DATA(self)->mc, ckeys, ckey_lengths, keys_list_size); free(ckeys); free(ckey_lengths); char returned_key[MEMCACHED_MAX_KEY], *returned_value; size_t returned_key_length, returned_value_length; uint32_t flags; returned_value = memcached_fetch(DATA(self)->mc, returned_key, &returned_key_length, &returned_value_length, &flags, &rc ); while(returned_value != NULL) { IoMap_rawAtPut(results_map, IoSeq_newSymbolWithData_length_(IOSTATE, returned_key, returned_key_length), IoMemcached_deserialize(self, returned_value, returned_value_length, flags) ); free(returned_value); returned_value = memcached_fetch(DATA(self)->mc, returned_key, &returned_key_length, &returned_value_length, &flags, &rc ); } return results_map; }
IoMap *IoState_createAssignOperatorTable(IoState *state) { IoMap *self = IoMap_new(state); IoMap_rawAtPut(self, IOSYMBOL(":="), IOSYMBOL("setSlot")); IoMap_rawAtPut(self, IOSYMBOL("="), IOSYMBOL("updateSlot")); IoMap_rawAtPut(self, IOSYMBOL("::="), IOSYMBOL("newSlot")); return self; }
IoSyslog *IoSyslog_proto(void *state) { IoSyslog *self = IoObject_new(state); IoObject_tag_(self, IoSyslog_newTag(state)); IoObject_setDataPointer_(self, calloc(1, sizeof(IoSyslogData))); DATA(self)->syslog_opened = 0; DATA(self)->priority = IONUMBER(LOG_INFO); DATA(self)->facility = IONUMBER(LOG_LOCAL0); DATA(self)->syslog_mask = 0; DATA(self)->ident = IOSYMBOL(""); DATA(self)->optionsMap = IoMap_new(IOSTATE); DATA(self)->facilityMap = IoMap_new(IOSTATE); DATA(self)->priorityMap = IoMap_new(IOSTATE); DATA(self)->maskMap = IoMap_new(IOSTATE); IoState_registerProtoWithFunc_(state, self, IoSyslog_proto); { IoMethodTable methodTable[] = { {"open", IoSyslog_open}, {"reopen", IoSyslog_reopen}, {"isOpen", IoSyslog_isOpen}, {"close", IoSyslog_close}, {"identity", IoSyslog_identity}, {"options", IoSyslog_options}, {"optionsMap", IoSyslog_optionsMap}, {"facility", IoSyslog_facility}, {"facilityMap", IoSyslog_facilityMap}, {"priority", IoSyslog_priority}, {"priorityMap", IoSyslog_priorityMap}, {"mask", IoSyslog_mask}, {"maskMap", IoSyslog_maskMap}, {"log", IoSyslog_log}, {NULL, NULL}, }; IoObject_addMethodTable_(self, methodTable); } return self; }
IoObject* IoMySQL_query(IoObject* self, IoObject* locals, IoMessage* m) { /*doc MySQL query(aQueryString) Perform a SQL query and return a list of results. <pre> db query("SELECT * FROM accounts") foreach(println) </pre> */ IoObject * queryString = 0x0; bool useMap; MYSQL* conn = &DATA(self)->connection; MYSQL_RES* result; MYSQL_ROW row; MYSQL_FIELD* column; char** columnNames; unsigned c, colLength; unsigned long* colLengths; IoObject *list, *rowObject; //, *tmpObject; if(IoMessage_argCount(m) < 1 || !ISSEQ(queryString = IoMessage_locals_quickValueArgAt_(m, locals, 0))) IoState_error_(IOSTATE, m, "argument 0 to method 'query' must be a Sequence"); useMap = IoMessage_argCount(m) > 1 && ISTRUE(IoMessage_locals_quickValueArgAt_(m, locals, 1)); if(!DATA(self)->connected) //printf("not connected?\n"); IoState_error_(IOSTATE, m, "not connected yet"); if(mysql_real_query(conn, CSTRING(queryString), IOSEQ_LENGTH(queryString))) IoState_error_(IOSTATE, m, "query error(%d): %s", mysql_errno(&DATA(self)->connection), mysql_error(&DATA(self)->connection)); if((result = mysql_store_result(conn)) && (colLength = mysql_num_fields(result))) { list = IoList_new(IOSTATE); if(useMap) { columnNames = (char**) malloc(colLength * sizeof(char*)); for(c = 0; c < colLength && (column = mysql_fetch_field(result)); ++c) columnNames[c] = column->name; while((row = mysql_fetch_row(result))) { colLengths = mysql_fetch_lengths(result); rowObject = IoMap_new(IOSTATE); for(c = 0; c < colLength; ++c) IoMap_rawAtPut(rowObject, IOSYMBOL(columnNames[c]), IOSEQ((unsigned char *)row[c], (size_t)colLengths[c])); IoList_rawAppend_(list, rowObject); } free(columnNames); } else { while((row = mysql_fetch_row(result))) { colLengths = mysql_fetch_lengths(result); rowObject = IoList_new(IOSTATE); for(c = 0; c < colLength; ++c) IoList_rawAppend_(rowObject, IOSEQ((unsigned char *)row[c], (size_t)colLengths[c])); IoList_rawAppend_(list, rowObject); } } mysql_free_result(result); return list; } else return IONUMBER(mysql_affected_rows(conn)); }
IoMap *IoState_createOperatorTable(IoState *state) { typedef struct OpTable { char *symbol; int precedence; } OpTable; OpTable ops[] = { {"@", 0}, {"@@", 0}, {"?", 0}, {"**", 1}, {"*", 2}, {"/", 2}, {"%", 2}, {"+", 3}, {"-", 3}, {"<<", 4}, {">>", 4}, {">", 5}, {"<", 5}, {"<=", 5}, {">=", 5}, {"==", 6}, {"!=", 6}, {"&", 7}, {"^", 8}, {"|", 9}, {"and", 10}, {"&&", 10}, {"or", 11}, {"||", 11}, {"..", 12}, {"+=", 13}, {"-=", 13}, {"*=", 13}, {"/=", 13}, {"%=", 13}, {"&=", 13}, {"^=", 13}, {"|=", 13}, {"<<=", 13}, {">>=", 13}, {"return", 14}, {NULL, 0}, }; IoMap *self = IoMap_new(state); OpTable *op = ops; while (op->symbol) { IoMap_rawAtPut(self, IOSYMBOL(op->symbol), IONUMBER(op->precedence)); op ++; } return self; }