PHP_METHOD(MongoDB, createCollection) { zval *data = NULL, *temp, *options = NULL; char *collection; int collection_len; zend_bool capped = 0; long size = 0, max = 0; if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|bll", &collection, &collection_len, &capped, &size, &max) == SUCCESS) { MAKE_STD_ZVAL(data); array_init(data); add_assoc_stringl(data, "create", collection, collection_len, 1); if (size) { add_assoc_long(data, "size", size); } if (capped) { php_error_docref(NULL TSRMLS_CC, MONGO_E_DEPRECATED, "This method now accepts arguments as an options array instead of the three optional arguments for capped, size and max elements"); add_assoc_bool(data, "capped", 1); if (max) { add_assoc_long(data, "max", max); } } } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &collection, &collection_len, &options) == SUCCESS) { zval *tmp_copy; /* We create a new array here, instead of just tagging "create" => * <name> at the end of the array. This is because MongoDB wants the * name of the command as first element in the array. */ MAKE_STD_ZVAL(data); array_init(data); add_assoc_stringl(data, "create", collection, collection_len, 1); if (options) { zend_hash_merge(Z_ARRVAL_P(data), Z_ARRVAL_P(options), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *), 0); } } else { return; } MAKE_STD_ZVAL(temp); MONGO_METHOD1(MongoDB, command, temp, getThis(), data); zval_ptr_dtor(&temp); zval_ptr_dtor(&data); if (!EG(exception)) { zval *zcollection; /* get the collection we just created */ MAKE_STD_ZVAL(zcollection); ZVAL_STRINGL(zcollection, collection, collection_len, 1); MONGO_METHOD1(MongoDB, selectCollection, return_value, getThis(), zcollection); zval_ptr_dtor(&zcollection); } }
PHP_METHOD(MongoDB, execute) { zval *code = NULL, *args = NULL, *options = NULL, *zdata; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|aa", &code, &args, &options) == FAILURE) { return; } /* turn the first argument into MongoCode */ if (Z_TYPE_P(code) != IS_OBJECT || Z_OBJCE_P(code) != mongo_ce_Code) { if (Z_TYPE_P(code) == IS_STRING) { zval *obj; MAKE_STD_ZVAL(obj); object_init_ex(obj, mongo_ce_Code); MONGO_METHOD1(MongoCode, __construct, return_value, obj, code); code = obj; } else { /* This is broken code */ php_error_docref(NULL TSRMLS_CC, E_ERROR, "The argument is neither an object of MongoCode or a string"); return; } } else { zval_add_ref(&code); } if (!args) { MAKE_STD_ZVAL(args); array_init(args); } else { zval_add_ref(&args); } /* create { $eval : code, args : [] } */ MAKE_STD_ZVAL(zdata); array_init(zdata); add_assoc_zval(zdata, "$eval", code); add_assoc_zval(zdata, "args", args); /* Check whether we have nolock as an option */ if (options) { zval **nolock; if (zend_hash_find(HASH_P(options), "nolock", strlen("nolock") + 1, (void**) &nolock) == SUCCESS) { convert_to_boolean_ex(nolock); zval_add_ref(nolock); add_assoc_zval(zdata, "nolock", *nolock); } } MONGO_METHOD1(MongoDB, command, return_value, getThis(), zdata); zval_ptr_dtor(&zdata); }
PHP_METHOD(MongoDB, getProfilingLevel) { zval l; Z_TYPE(l) = IS_LONG; Z_LVAL(l) = -1; MONGO_METHOD1(MongoDB, setProfilingLevel, return_value, getThis(), &l); }
PHP_METHOD(MongoDB, execute) { zval *code = 0, *args = 0, *zdata; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &code, &args) == FAILURE) { return; } // turn the first argument into MongoCode if (Z_TYPE_P(code) != IS_OBJECT || Z_OBJCE_P(code) != mongo_ce_Code) { if (Z_TYPE_P(code) == IS_STRING) { zval *obj; MAKE_STD_ZVAL(obj); object_init_ex(obj, mongo_ce_Code); MONGO_METHOD1(MongoCode, __construct, return_value, obj, code); code = obj; } else { /* This is broken code */ php_error_docref(NULL TSRMLS_CC, E_ERROR, "The argument is neither an object of MongoCode or a string"); return; } } else { zval_add_ref(&code); } if (!args) { MAKE_STD_ZVAL(args); array_init(args); } else { zval_add_ref(&args); } // create { $eval : code, args : [] } MAKE_STD_ZVAL(zdata); array_init(zdata); add_assoc_zval(zdata, "$eval", code); add_assoc_zval(zdata, "args", args); MONGO_METHOD1(MongoDB, command, return_value, getThis(), zdata); zval_ptr_dtor(&zdata); }
PHP_METHOD(MongoDB, getGridFS) { zval temp; zval *arg1 = 0, *arg2 = 0; // arg2 is deprecated if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE) { return; } object_init_ex(return_value, mongo_ce_GridFS); if (!arg1) { MONGO_METHOD1(MongoGridFS, __construct, &temp, return_value, getThis()); } else { MONGO_METHOD2(MongoGridFS, __construct, &temp, return_value, getThis(), arg1); } }
PHP_METHOD(MongoDB, getGridFS) { zval temp; zval *arg1 = 0, *arg2 = 0; // arg2 is deprecated if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE) { return; } if (arg2) { php_error_docref(NULL TSRMLS_CC, MONGO_E_DEPRECATED, "This argument doesn't do anything. Please stop sending it"); } object_init_ex(return_value, mongo_ce_GridFS); if (!arg1) { MONGO_METHOD1(MongoGridFS, __construct, &temp, return_value, getThis()); } else { MONGO_METHOD2(MongoGridFS, __construct, &temp, return_value, getThis(), arg1); } }
PHP_METHOD(MongoDB, getGridFS) { zval temp; zval *arg1 = 0, *arg2 = 0; /* arg2 is deprecated */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE) { return; } if (arg2) { php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The 'chunks' argument is deprecated and ignored"); } object_init_ex(return_value, mongo_ce_GridFS); if (!arg1) { MONGO_METHOD1(MongoGridFS, __construct, &temp, return_value, getThis()); } else { MONGO_METHOD2(MongoGridFS, __construct, &temp, return_value, getThis(), arg1); } }
PHP_METHOD(MongoDB, dropCollection) { zval *collection; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &collection) == FAILURE) { return; } if (Z_TYPE_P(collection) != IS_OBJECT || Z_OBJCE_P(collection) != mongo_ce_Collection) { zval *temp; MAKE_STD_ZVAL(temp); MONGO_METHOD1(MongoDB, selectCollection, temp, getThis(), collection); collection = temp; } else { zval_add_ref(&collection); } MONGO_METHOD(MongoCollection, drop, return_value, collection); zval_ptr_dtor(&collection); }
PHP_METHOD(MongoDB, createCollection) { zval *collection, *data, *temp; zend_bool capped=0; long size=0, max=0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bll", &collection, &capped, &size, &max) == FAILURE) { return; } MAKE_STD_ZVAL(data); array_init(data); convert_to_string(collection); add_assoc_zval(data, "create", collection); zval_add_ref(&collection); if (size) { add_assoc_long(data, "size", size); } if (capped) { add_assoc_bool(data, "capped", 1); if (max) { add_assoc_long(data, "max", max); } } MAKE_STD_ZVAL(temp); MONGO_CMD(temp, getThis()); zval_ptr_dtor(&temp); zval_ptr_dtor(&data); if (!EG(exception)) { // get the collection we just created MONGO_METHOD1(MongoDB, selectCollection, return_value, getThis(), collection); } }
static void php_mongo_enumerate_collections(INTERNAL_FUNCTION_PARAMETERS, int full_collection) { zend_bool system_col = 0; zval *nss, *collection, *cursor, *list, *next; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &system_col) == FAILURE) { return; } // select db.system.namespaces collection MAKE_STD_ZVAL(nss); ZVAL_STRING(nss, "system.namespaces", 1); MAKE_STD_ZVAL(collection); MONGO_METHOD1(MongoDB, selectCollection, collection, getThis(), nss); // list to return MAKE_STD_ZVAL(list); array_init(list); // do find MAKE_STD_ZVAL(cursor); MONGO_METHOD(MongoCollection, find, cursor, collection); // populate list MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); while (!IS_SCALAR_P(next)) { zval *c, *zname; zval **collection; char *name, *first_dot, *system; // check that the ns is valid and not an index (contains $) if (zend_hash_find(HASH_P(next), "name", 5, (void**)&collection) == FAILURE || strchr(Z_STRVAL_PP(collection), '$')) { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } first_dot = strchr(Z_STRVAL_PP(collection), '.'); system = strstr(Z_STRVAL_PP(collection), ".system."); // check that this isn't a system ns if (!system_col && (system && first_dot == system) || (name = strchr(Z_STRVAL_PP(collection), '.')) == 0) { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } // take a substring after the first "." name++; // "foo." was allowed in earlier versions if (name == '\0') { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } if (full_collection) { MAKE_STD_ZVAL(c); ZVAL_NULL(c); MAKE_STD_ZVAL(zname); ZVAL_NULL(zname); // name must be copied because it is a substring of // a string that will be garbage collected in a sec ZVAL_STRING(zname, name, 1); MONGO_METHOD1(MongoDB, selectCollection, c, getThis(), zname); add_next_index_zval(list, c); zval_ptr_dtor(&zname); } else { add_next_index_string(list, name, 1); } zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); } zval_ptr_dtor(&next); zval_ptr_dtor(&nss); zval_ptr_dtor(&cursor); zval_ptr_dtor(&collection); RETURN_ZVAL(list, 0, 1); }
/* {{{ MongoDBRef::get() */ PHP_METHOD(MongoDBRef, get) { zval *db, *ref, *collection, *query; zval **ns, **id, **dbname; zend_bool alloced_db = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oz", &db, mongo_ce_DB, &ref) == FAILURE) { return; } if ( IS_SCALAR_P(ref) || zend_hash_find(HASH_P(ref), "$ref", strlen("$ref") + 1, (void**)&ns) == FAILURE || zend_hash_find(HASH_P(ref), "$id", strlen("$id") + 1, (void**)&id) == FAILURE ) { RETURN_NULL(); } if (Z_TYPE_PP(ns) != IS_STRING) { zend_throw_exception(mongo_ce_Exception, "MongoDBRef::get: $ref field must be a string", 10 TSRMLS_CC); return; } /* if this reference contains a db name, we have to switch dbs */ if (zend_hash_find(HASH_P(ref), "$db", strlen("$db") + 1, (void**)&dbname) == SUCCESS) { mongo_db *temp_db = (mongo_db*)zend_object_store_get_object(db TSRMLS_CC); /* just to be paranoid, make sure dbname is a string */ if (Z_TYPE_PP(dbname) != IS_STRING) { zend_throw_exception(mongo_ce_Exception, "MongoDBRef::get: $db field must be a string", 11 TSRMLS_CC); return; } /* if the name in the $db field doesn't match the current db, make up * a new db */ if (strcmp(Z_STRVAL_PP(dbname), Z_STRVAL_P(temp_db->name)) != 0) { zval *new_db_z; MAKE_STD_ZVAL(new_db_z); ZVAL_NULL(new_db_z); MONGO_METHOD1(MongoClient, selectDB, new_db_z, temp_db->link, *dbname); /* make the new db the current one */ db = new_db_z; /* so we can dtor this later */ alloced_db = 1; } } /* get the collection */ MAKE_STD_ZVAL(collection); MONGO_METHOD1(MongoDB, selectCollection, collection, db, *ns); /* query for the $id */ MAKE_STD_ZVAL(query); array_init(query); add_assoc_zval(query, "_id", *id); zval_add_ref(id); /* return whatever's there */ MONGO_METHOD1(MongoCollection, findOne, return_value, collection, query); /* cleanup */ zval_ptr_dtor(&collection); zval_ptr_dtor(&query); if (alloced_db) { zval_ptr_dtor(&db); } }
/* {{{ proto int MongoGridFSFile::write([string filename = null]) Writes this file to the filesystem */ PHP_METHOD(MongoGridFSFile, write) { char *filename = 0; int filename_len, total = 0; zval *gridfs, *file, *chunks, *query, *cursor, *sort, tmp; zval **id, **size; int len; FILE *fp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &filename, &filename_len) == FAILURE) { return; } gridfs = zend_read_property(mongo_ce_GridFSFile, getThis(), "gridfs", strlen("gridfs"), NOISY TSRMLS_CC); file = zend_read_property(mongo_ce_GridFSFile, getThis(), "file", strlen("file"), NOISY TSRMLS_CC); if (zend_hash_find(HASH_P(file), "length", strlen("length") + 1, (void**)&size) == FAILURE) { zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size", 14 TSRMLS_CC); return; } if (Z_TYPE_PP(size) == IS_DOUBLE) { len = (int)Z_DVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_LONG) { len = Z_LVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_OBJECT && (Z_OBJCE_PP(size) == mongo_ce_Int32 || Z_OBJCE_PP(size) == mongo_ce_Int64)) { zval *sizet = zend_read_property(mongo_ce_Int64, *size, "value", strlen("value"), NOISY TSRMLS_CC); if (Z_TYPE_P(sizet) != IS_STRING) { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, value object broken", 0 TSRMLS_CC); return; } len = atoi(Z_STRVAL_P(sizet)); } else { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, property invalid", 0 TSRMLS_CC); return; } /* Make sure that there's an index on chunks so we can sort by chunk num */ chunks = zend_read_property(mongo_ce_GridFS, gridfs, "chunks", strlen("chunks"), NOISY TSRMLS_CC); php_mongo_ensure_gridfs_index(&tmp, chunks TSRMLS_CC); zval_dtor(&tmp); if (!filename) { zval **temp; if (zend_hash_find(HASH_P(file), "filename", strlen("filename") + 1, (void**) &temp) == SUCCESS) { convert_to_string_ex(temp); filename = Z_STRVAL_PP(temp); } else { zend_throw_exception(mongo_ce_GridFSException, "Cannot find filename", 15 TSRMLS_CC); return; } } fp = fopen(filename, "wb"); if (!fp) { zend_throw_exception_ex(mongo_ce_GridFSException, 16 TSRMLS_CC, "could not open destination file %s", filename); return; } zend_hash_find(HASH_P(file), "_id", strlen("_id") + 1, (void**)&id); MAKE_STD_ZVAL(query); array_init(query); zval_add_ref(id); add_assoc_zval(query, "files_id", *id); MAKE_STD_ZVAL(cursor); MONGO_METHOD1(MongoCollection, find, cursor, chunks, query); MAKE_STD_ZVAL(sort); array_init(sort); add_assoc_long(sort, "n", 1); MONGO_METHOD1(MongoCursor, sort, cursor, cursor, sort); if ((total = apply_to_cursor(cursor, copy_file, fp, len TSRMLS_CC)) == FAILURE) { zend_throw_exception(mongo_ce_GridFSException, "error reading chunk of file", 17 TSRMLS_CC); } fclose(fp); zval_ptr_dtor(&cursor); zval_ptr_dtor(&sort); zval_ptr_dtor(&query); RETURN_LONG(total); }
PHP_METHOD(MongoCursor, count) { zval *db_z, *coll, *query; mongo_cursor *cursor; mongo_collection *c; mongo_db *db; zend_bool all = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &all) == FAILURE) { return; } PHP_MONGO_GET_CURSOR(getThis()); // fake a MongoDB object MAKE_STD_ZVAL(db_z); object_init_ex(db_z, mongo_ce_DB); db = (mongo_db*)zend_object_store_get_object(db_z TSRMLS_CC); db->link = cursor->resource; MAKE_STD_ZVAL(db->name); ZVAL_STRING(db->name, estrndup(cursor->ns, strchr(cursor->ns, '.') - cursor->ns), 0); // fake a MongoCollection object MAKE_STD_ZVAL(coll); object_init_ex(coll, mongo_ce_Collection); c = (mongo_collection*)zend_object_store_get_object(coll TSRMLS_CC); MAKE_STD_ZVAL(c->ns); ZVAL_STRING(c->ns, estrdup(cursor->ns), 0); MAKE_STD_ZVAL(c->name); ZVAL_STRING(c->name, estrdup(cursor->ns + (strchr(cursor->ns, '.') - cursor->ns) + 1), 0); c->parent = db_z; if (cursor->query) { zval **inner_query = 0; if (!cursor->special) { query = cursor->query; zval_add_ref(&query); } else if (zend_hash_find(HASH_P(cursor->query), "$query", strlen("$query")+1, (void**)&inner_query) == SUCCESS) { query = *inner_query; zval_add_ref(&query); } } else { MAKE_STD_ZVAL(query); array_init(query); } if (all) { zval *limit_z, *skip_z; MAKE_STD_ZVAL(limit_z); MAKE_STD_ZVAL(skip_z); ZVAL_LONG(limit_z, cursor->limit); ZVAL_LONG(skip_z, cursor->skip); MONGO_METHOD3(MongoCollection, count, return_value, coll, query, limit_z, skip_z); zval_ptr_dtor(&limit_z); zval_ptr_dtor(&skip_z); } else { MONGO_METHOD1(MongoCollection, count, return_value, coll, query); } zval_ptr_dtor(&query); c->parent = 0; zend_objects_store_del_ref(coll TSRMLS_CC); zval_ptr_dtor(&coll); db->link = 0; zend_objects_store_del_ref(db_z TSRMLS_CC); zval_ptr_dtor(&db_z); }
PHP_METHOD(MongoDB, command) { zval limit, *temp, *cmd, *cursor, *ns, *options = 0; mongo_db *db; mongoclient *link; char *cmd_ns; mongo_cursor *cursor_tmp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &cmd, &options) == FAILURE) { return; } MUST_BE_ARRAY_OR_OBJECT(1, cmd); PHP_MONGO_GET_DB(getThis()); // create db.$cmd MAKE_STD_ZVAL(ns); cmd_ns = get_cmd_ns(Z_STRVAL_P(db->name), Z_STRLEN_P(db->name)); ZVAL_STRING(ns, cmd_ns, 0); // create cursor MAKE_STD_ZVAL(cursor); object_init_ex(cursor, mongo_ce_Cursor); MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD3(MongoCursor, __construct, temp, cursor, db->link, ns, cmd); zval_ptr_dtor(&ns); zval_ptr_dtor(&temp); MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); // limit Z_TYPE(limit) = IS_LONG; Z_LVAL(limit) = -1; MONGO_METHOD1(MongoCursor, limit, temp, cursor, &limit); zval_ptr_dtor(&temp); if (options) { zval **timeout; if (zend_hash_find(HASH_P(options), "timeout", strlen("timeout")+1, (void**)&timeout) == SUCCESS) { MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD1(MongoCursor, timeout, temp, cursor, *timeout); zval_ptr_dtor(&temp); } } /* Make sure commands aren't be sent to slaves */ /* TODO: The read preferences spec has a list of commands that *can* be send * to slave */ /* This should be refactored alongside with the getLastError redirection in * collection.c/append_getlasterror. The Cursor creation should be done through * an init method. */ PHP_MONGO_GET_LINK(db->link); cursor_tmp = (mongo_cursor*)zend_object_store_get_object(cursor TSRMLS_CC); mongo_manager_log(link->manager, MLOG_CON, MLOG_INFO, "forcing primary for command"); php_mongo_connection_force_primary(cursor_tmp); // query MONGO_METHOD(MongoCursor, getNext, return_value, cursor); clear_exception(return_value TSRMLS_CC); zend_objects_store_del_ref(cursor TSRMLS_CC); zval_ptr_dtor(&cursor); }
PHP_METHOD(MongoDB, listCollections) { // select db.system.namespaces collection zval *nss, *collection, *cursor, *list, *next; MAKE_STD_ZVAL(nss); ZVAL_STRING(nss, "system.namespaces", 1); MAKE_STD_ZVAL(collection); MONGO_METHOD1(MongoDB, selectCollection, collection, getThis(), nss); // list to return MAKE_STD_ZVAL(list); array_init(list); // do find MAKE_STD_ZVAL(cursor); MONGO_METHOD(MongoCollection, find, cursor, collection); // populate list MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); while (!IS_SCALAR_P(next)) { zval *c, *zname; zval **collection; char *name, *first_dot, *system; // check that the ns is valid and not an index (contains $) if (zend_hash_find(HASH_P(next), "name", 5, (void**)&collection) == FAILURE || strchr(Z_STRVAL_PP(collection), '$')) { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } first_dot = strchr(Z_STRVAL_PP(collection), '.'); system = strstr(Z_STRVAL_PP(collection), ".system."); // check that this isn't a system ns if ((system && first_dot == system) || (name = strchr(Z_STRVAL_PP(collection), '.')) == 0) { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } // take a substring after the first "." name++; // "foo." was allowed in earlier versions if (name == '\0') { zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); ZVAL_NULL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); continue; } MAKE_STD_ZVAL(c); ZVAL_NULL(c); MAKE_STD_ZVAL(zname); ZVAL_NULL(zname); // name must be copied because it is a substring of // a string that will be garbage collected in a sec ZVAL_STRING(zname, name, 1); MONGO_METHOD1(MongoDB, selectCollection, c, getThis(), zname); add_next_index_zval(list, c); zval_ptr_dtor(&zname); zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); } zval_ptr_dtor(&next); zval_ptr_dtor(&nss); zval_ptr_dtor(&cursor); zval_ptr_dtor(&collection); RETURN_ZVAL(list, 0, 1); }
PHP_METHOD(MongoDB, command) { zval limit, *temp, *cmd, *cursor, *ns, *options = 0; mongo_db *db; mongo_link *link; char *cmd_ns; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|a", &cmd, &options) == FAILURE) { return; } if (IS_SCALAR_P(cmd)) { zend_error(E_WARNING, "MongoDB::command() expects parameter 1 to be an array or object"); return; } PHP_MONGO_GET_DB(getThis()); // create db.$cmd MAKE_STD_ZVAL(ns); cmd_ns = get_cmd_ns(Z_STRVAL_P(db->name), Z_STRLEN_P(db->name)); ZVAL_STRING(ns, cmd_ns, 0); // create cursor MAKE_STD_ZVAL(cursor); object_init_ex(cursor, mongo_ce_Cursor); MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD3(MongoCursor, __construct, temp, cursor, db->link, ns, cmd); zval_ptr_dtor(&ns); zval_ptr_dtor(&temp); MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); // limit Z_TYPE(limit) = IS_LONG; Z_LVAL(limit) = -1; MONGO_METHOD1(MongoCursor, limit, temp, cursor, &limit); zval_ptr_dtor(&temp); if (options) { zval **timeout; if (zend_hash_find(HASH_P(options), "timeout", strlen("timeout")+1, (void**)&timeout) == SUCCESS) { MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD1(MongoCursor, timeout, temp, cursor, *timeout); zval_ptr_dtor(&temp); } } // make sure commands aren't be sent to slaves PHP_MONGO_GET_LINK(db->link); if (link->rs) { zval slave_okay; Z_TYPE(slave_okay) = IS_BOOL; Z_LVAL(slave_okay) = 0; MAKE_STD_ZVAL(temp); ZVAL_NULL(temp); MONGO_METHOD1(MongoCursor, slaveOkay, temp, cursor, &slave_okay); zval_ptr_dtor(&temp); } // query MONGO_METHOD(MongoCursor, getNext, return_value, cursor); clear_exception(return_value TSRMLS_CC); zend_objects_store_del_ref(cursor TSRMLS_CC); zval_ptr_dtor(&cursor); }
/* {{{ proto string MongoGridFSFile::getBytes() Returns this file's contents as a string of bytes */ PHP_METHOD(MongoGridFSFile, getBytes) { zval *file, *gridfs, *chunks, *query, *cursor, *sort, *temp; zval **id, **size; char *str, *str_ptr; int len; mongo_cursor *cursorobj; zval *flags; file = zend_read_property(mongo_ce_GridFSFile, getThis(), "file", strlen("file"), NOISY TSRMLS_CC); zend_hash_find(HASH_P(file), "_id", strlen("_id") + 1, (void**)&id); if (zend_hash_find(HASH_P(file), "length", strlen("length") + 1, (void**)&size) == FAILURE) { zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size", 14 TSRMLS_CC); return; } /* make sure that there's an index on chunks so we can sort by chunk num */ gridfs = zend_read_property(mongo_ce_GridFSFile, getThis(), "gridfs", strlen("gridfs"), NOISY TSRMLS_CC); chunks = zend_read_property(mongo_ce_GridFS, gridfs, "chunks", strlen("chunks"), NOISY TSRMLS_CC); MAKE_STD_ZVAL(temp); php_mongo_ensure_gridfs_index(temp, chunks TSRMLS_CC); zval_dtor(temp); /* query for chunks */ MAKE_STD_ZVAL(query); array_init(query); zval_add_ref(id); add_assoc_zval(query, "files_id", *id); MAKE_STD_ZVAL(cursor); MONGO_METHOD1(MongoCollection, find, cursor, chunks, query); /* Copy the flags from the original cursor and apply it to this one */ flags = zend_read_property(mongo_ce_GridFSFile, getThis(), "flags", strlen("flags"), NOISY TSRMLS_CC); cursorobj = (mongo_cursor*)zend_object_store_get_object(cursor TSRMLS_CC); convert_to_long(flags); cursorobj->opts = Z_LVAL_P(flags); MAKE_STD_ZVAL(sort); array_init(sort); add_assoc_long(sort, "n", 1); MONGO_METHOD1(MongoCursor, sort, temp, cursor, sort); zval_ptr_dtor(&temp); zval_ptr_dtor(&query); zval_ptr_dtor(&sort); if (Z_TYPE_PP(size) == IS_DOUBLE) { len = (int)Z_DVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_LONG) { len = Z_LVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_OBJECT && (Z_OBJCE_PP(size) == mongo_ce_Int32 || Z_OBJCE_PP(size) == mongo_ce_Int64)) { zval *sizet = zend_read_property(mongo_ce_Int64, *size, "value", strlen("value"), NOISY TSRMLS_CC); if (Z_TYPE_P(sizet) != IS_STRING) { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, value object broken", 0 TSRMLS_CC); return; } len = atoi(Z_STRVAL_P(sizet)); } else { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, property invalid", 0 TSRMLS_CC); return; } str = (char *)ecalloc(len + 1, 1); str_ptr = str; if (apply_to_cursor(cursor, copy_bytes, &str, len + 1 TSRMLS_CC) == FAILURE) { zval_ptr_dtor(&cursor); efree(str_ptr); if (EG(exception)) { return; } zend_throw_exception(mongo_ce_GridFSException, "error reading chunk of file", 17 TSRMLS_CC); return; } zval_ptr_dtor(&cursor); str_ptr[len] = '\0'; RETURN_STRINGL(str_ptr, len, 0); }