Ejemplo n.º 1
0
/*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;
}
Ejemplo n.º 2
0
IO_METHOD(IoSandbox, doSandboxString)
{
	/*doc Sandbox doSandboxString(aString)
	Evaluate aString inside the Sandbox.
	*/

	IoState *boxState = IoSandbox_boxState(self);
	char *s = IoMessage_locals_cStringArgAt_(m, locals, 0);

	IoObject *result = IoState_doSandboxCString_(boxState, s);

	if (ISSYMBOL(result))
	{
		return IOSYMBOL(CSTRING(result));
	}

	if (ISSEQ(result))
	{
		return IOSEQ(IOSEQ_BYTES(result), IOSEQ_LENGTH(result));
	}

	if (ISNUMBER(result))
	{
		return IONUMBER(CNUMBER(result));
	}

	return IONIL(self);
}
Ejemplo n.º 3
0
/*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
}
Ejemplo n.º 4
0
/*doc Memcached prepend(key, value)
Asks memcached to add this value to an existing key before existing value.
Returns true on success, otherwise raises an exception.
value should be a Sequence.
Supported by memcached 1.2.4+
*/
IoObject *IoMemcached_prepend(IoMemcached *self, IoObject *locals, IoMessage *m)
{
	IoSeq *key   = IoMessage_locals_seqArgAt_(m, locals, 0);
	IoSeq *value = IoMessage_locals_seqArgAt_(m, locals, 1);

	memcached_return_t rc;
	rc = memcached_prepend(DATA(self)->mc,
		CSTRING(key),   IOSEQ_LENGTH(key),
		CSTRING(value), IOSEQ_LENGTH(value),
		0, 0
	);

	if(rc != MEMCACHED_SUCCESS)
		IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, rc));

	return IOSTATE->ioTrue;
}
Ejemplo n.º 5
0
Archivo: IoSHA1.c Proyecto: ADTSH/io
IoObject *IoSHA1_hmac(IoSHA1 *self, IoObject *locals, IoMessage *m)
{
	/*doc SHA1 hmac(key, data)
	Returns a hmac signature sequence or nil on error.
	*/
	
	IoSeq *key = IoMessage_locals_seqArgAt_(m, locals, 0);
	IoSeq *inSeq = IoMessage_locals_seqArgAt_(m, locals, 1);
	char resbuf[20];
	int ok;
	memset(resbuf, 0x0, 20);
	ok = hmac_sha1(
		IOSEQ_BYTES(key), IOSEQ_LENGTH(key),
		IOSEQ_BYTES(inSeq), IOSEQ_LENGTH(inSeq), 
		(void *)resbuf);
	if(ok != 0) return IONIL(self);
	return IOSEQ(resbuf, 20);

}
Ejemplo n.º 6
0
// Serialize/Deserialize
char *IoMemcached_serialize(IoMemcached *self, IoObject *locals, IoObject *object, size_t *size, uint32_t *flags) {
	char *cvalue;

	if(ISSEQ(object)) {
		*flags = _FLAG_SEQUENCE;
		*size = IOSEQ_LENGTH(object);
		cvalue = (char *) malloc(*size);
		strncpy(cvalue, CSTRING(object), *size);
	}
	else if(ISNUMBER(object)) {
		*flags = _FLAG_NUMBER;
		double cnumber = IoNumber_asDouble(object);
		cvalue = (char *) malloc(128 * sizeof(char));
		*size = snprintf(cvalue, 127, "%.16f", cnumber);
	}
	else if(ISNIL(object)) {
		*flags = _FLAG_NIL;
		*size = 3;
		cvalue = (char *) malloc(3 * sizeof(char));
		strncpy(cvalue, "nil", 3);
	}
	else if(ISBOOL(object)) {
		*flags = _FLAG_BOOLEAN;
		*size = 1;
		cvalue = (char *) malloc(sizeof(char));
		if(object == IOSTATE->ioTrue)  strncpy(cvalue, "1", 1);
		if(object == IOSTATE->ioFalse) strncpy(cvalue, "0", 1);
	}
	else {
		*flags = _FLAG_OBJECT;
		IoMessage *serialize = IoMessage_newWithName_(IOSTATE, IOSYMBOL("serialized"));
		IoSeq *serialized = IoMessage_locals_performOn_(serialize, locals, object);
		*size = IOSEQ_LENGTH(serialized);
		cvalue = (char *) malloc(*size);
		strncpy(cvalue, CSTRING(serialized), *size);
	}

	return cvalue;
}
Ejemplo n.º 7
0
/*doc Memcached decr([offset])
Asks memcached to decrement data for some item in place. The data for the item is
treated as decimal representation of a 64-bit unsigned integer. If the
current data value does not conform to such a representation, the
commands behave as if the value were 0.
Default offset is 1.
Returns the new value.
*/
IoObject *IoMemcached_decr(IoMemcached *self, IoObject *locals, IoMessage *m)
{
	IoSeq *key = IoMessage_locals_seqArgAt_(m, locals, 0);

	uint32_t offset = IoMessage_argCount(m) == 2 ? IoMessage_locals_intArgAt_(m, locals, 1) : 1;

	uint64_t new_value;

	memcached_return_t rc;
	rc = memcached_decrement(DATA(self)->mc,
		CSTRING(key), IOSEQ_LENGTH(key),
		offset, &new_value
	);

	if(rc != MEMCACHED_SUCCESS)
		IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, rc));

	return IONUMBER(new_value);
}
Ejemplo n.º 8
0
/*doc Memcached delete(key[, time])
Asks memcached to delete an item with the given key.
time is the amount of time in seconds (or Unix time until which)
the client wishes the server to refuse "add" and "replace" commands
with this key.
Returns true on success, false if there is no item with the given key.
Otherwise raises an exception.
*/
IoObject *IoMemcached_delete(IoMemcached *self, IoObject *locals, IoMessage *m)
{
	IoSeq *key = IoMessage_locals_seqArgAt_(m, locals, 0);

	time_t time = IoMessage_argCount(m) == 2 ? IoMessage_locals_intArgAt_(m, locals, 1) : 0;

	memcached_return_t rc;
	rc = memcached_delete(DATA(self)->mc,
		CSTRING(key), IOSEQ_LENGTH(key),
		time
	);

	if(rc != MEMCACHED_SUCCESS && rc != MEMCACHED_NOTFOUND)
		IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, rc));

	if(rc == MEMCACHED_NOTFOUND)
		return IOSTATE->ioFalse;

	return IOSTATE->ioTrue; // MEMCACHED_SUCCESS
}
Ejemplo n.º 9
0
/*doc Memcached get(key)
Asks memcached to retrieve data corresponding to the key.
Raises "NOT FOUND" if the data is not there.
*/
IoObject *IoMemcached_get(IoMemcached *self, IoObject *locals, IoMessage *m)
{
	IoObject *key = IoMessage_locals_seqArgAt_(m, locals, 0);

	size_t size;
	uint32_t flags;
	memcached_return_t rc;

	char *cvalue;
	cvalue = memcached_get(DATA(self)->mc,
		CSTRING(key), IOSEQ_LENGTH(key),
		&size, &flags, &rc
	);

	if(cvalue == NULL)
		IoState_error_(IOSTATE, m, memcached_strerror(DATA(self)->mc, rc));

	IoObject *result = IoMemcached_deserialize(self, cvalue, size, flags);

	free(cvalue);

	return result;
}
Ejemplo n.º 10
0
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));
}