/*doc Memcached replace(key, value[, expiration]) Asks memcached to store the value identified by the key, but only if the server *does* already hold data for this key. Returns true on success, false if there is already data for this key. Otherwise raises an exception. */ IoObject *IoMemcached_replace(IoMemcached *self, IoObject *locals, IoMessage *m) { IoSeq *key = IoMessage_locals_seqArgAt_(m, locals, 0); IoObject *value = IoMessage_locals_quickValueArgAt_(m, locals, 1); time_t expiration = IoMessage_argCount(m) == 3 ? IoMessage_locals_intArgAt_(m, locals, 2) : 0; uint32_t flags; size_t size; char *cvalue = IoMemcached_serialize(self, locals, value, &size, &flags); memcached_return_t rc; rc = memcached_replace(DATA(self)->mc, CSTRING(key), IOSEQ_LENGTH(key), cvalue, size, expiration, flags ); free(cvalue); if(rc != MEMCACHED_SUCCESS && rc != MEMCACHED_NOTSTORED) IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, rc)); // MEMCACHED_NOTSTORED is a legitmate error in the case of a collision. if(rc == MEMCACHED_NOTSTORED) return IOSTATE->ioFalse; return IOSTATE->ioTrue; // MEMCACHED_SUCCESS }
IoObject* IoMySQL_connect(IoObject* self, IoObject* locals, IoMessage* m) { IoObject *host = NULL, *user = NULL, *password = NULL, *database = NULL, *port = NULL, *socket = NULL, *ssl = NULL; /*doc MySQL connect(host, user, password, database, port, unixSocket, useSSL) Connect to a MySQL database. */ switch(IoMessage_argCount(m)) { case 7: ssl = IoMessage_locals_quickValueArgAt_(m, locals, 6); case 6: socket = IoMessage_locals_quickValueArgAt_(m, locals, 5); case 5: port = IoMessage_locals_quickValueArgAt_(m, locals, 4); case 4: database = IoMessage_locals_quickValueArgAt_(m, locals, 3); case 3: password = IoMessage_locals_quickValueArgAt_(m, locals, 2); case 2: user = IoMessage_locals_quickValueArgAt_(m, locals, 1); case 1: host = IoMessage_locals_quickValueArgAt_(m, locals, 0); } if(DATA(self)->connected) { mysql_close(&DATA(self)->connection); DATA(self)->connected = 0; } if(mysql_real_connect( &DATA(self)->connection, host && ISSEQ(host) ? IoSeq_asCString(host) : NULL, user && ISSEQ(user) ? IoSeq_asCString(user) : NULL, password && ISSEQ(password) ? IoSeq_asCString(password) : NULL, database && ISSEQ(database) ? IoSeq_asCString(database) : NULL, port && ISNUMBER(port) ? (unsigned) IoNumber_asInt(port) : 0, socket && ISSEQ(socket) ? IoSeq_asCString(socket) : NULL, ssl && ISFALSE(ssl) ? 0 : CLIENT_SSL )) { DATA(self)->connected = 1; IoObject_setSlot_to_(self, IOSYMBOL("host"), host ? host : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("user"), user ? user : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("password"), password ? password : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("database"), database ? database : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("port"), port ? port : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("socket"), socket ? socket : IONIL(self)); IoObject_setSlot_to_(self, IOSYMBOL("usingSSL"), ssl ? IOBOOL(self, ISTRUE(ssl)) : IOFALSE(self)); } else IoState_error_(IOSTATE, m, "connection error(%d): %s", mysql_errno(&DATA(self)->connection), mysql_error(&DATA(self)->connection)); 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)); }