[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pecl-cvs
Subject:    [PECL-CVS] svn: /pecl/mongo/trunk/ bson.c bson.h collection.c config.m4 cursor.c mongo.c package.xml
From:       Kristina_Chodorow <kristina () php ! net>
Date:       2009-09-29 21:16:57
Message-ID: svn-kristina-1254259017-288966-1256341510 () svn ! php ! net
[Download RAW message or body]

kristina                                 Tue, 29 Sep 2009 21:16:57 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=288966

Log:
safe insert, os x build, err funcs

Changed paths:
    U   pecl/mongo/trunk/bson.c
    U   pecl/mongo/trunk/bson.h
    U   pecl/mongo/trunk/collection.c
    U   pecl/mongo/trunk/config.m4
    U   pecl/mongo/trunk/cursor.c
    U   pecl/mongo/trunk/mongo.c
    U   pecl/mongo/trunk/package.xml
    U   pecl/mongo/trunk/php_mongo.h


["svn-diffs-288966.txt" (text/x-diff)]

Modified: pecl/mongo/trunk/bson.c
===================================================================
--- pecl/mongo/trunk/bson.c	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/bson.c	2009-09-29 21:16:57 UTC (rev 288966)
@@ -60,7 +60,7 @@
     data = &newid;
   }

-  serialize_element("_id", data, buf, 0 TSRMLS_CC);
+  php_mongo_serialize_element("_id", data, buf, 0 TSRMLS_CC);

   return SUCCESS;
 }
@@ -96,8 +96,8 @@
 #endif /* ZEND_MODULE_API_NO >= 20090115 */
   }

-  serialize_null(buf);
-  serialize_size(buf->start+start, buf);
+  php_mongo_serialize_null(buf);
+  php_mongo_serialize_size(buf->start+start, buf);
   return num;
 }

@@ -119,11 +119,11 @@
 #endif /* ZEND_MODULE_API_NO < 20090115 */

   if (key->nKeyLength) {
-    return serialize_element(key->arKey, (zval**)data, buf, prep TSRMLS_CC);
+    return php_mongo_serialize_element(key->arKey, (zval**)data, buf, prep \
TSRMLS_CC);  }

   spprintf(&name, 0, "%ld", key->h);
-  retval = serialize_element(name, (zval**)data, buf, prep TSRMLS_CC);
+  retval = php_mongo_serialize_element(name, (zval**)data, buf, prep TSRMLS_CC);
   efree(name);

   // if the key is a number in ascending order, we're still
@@ -135,7 +135,7 @@
   return retval;
 }

-int serialize_element(char *name, zval **data, buffer *buf, int prep TSRMLS_DC) {
+int php_mongo_serialize_element(char *name, zval **data, buffer *buf, int prep \
TSRMLS_DC) {  int name_len = strlen(name);

   if (prep && strcmp(name, "_id") == 0) {
@@ -144,30 +144,30 @@

   switch (Z_TYPE_PP(data)) {
   case IS_NULL:
-    set_type(buf, BSON_NULL);
-    serialize_string(buf, name, name_len);
+    php_mongo_set_type(buf, BSON_NULL);
+    php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
     break;
   case IS_LONG:
-    set_type(buf, BSON_INT);
-    serialize_string(buf, name, name_len);
-    serialize_int(buf, Z_LVAL_PP(data));
+    php_mongo_set_type(buf, BSON_INT);
+    php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
+    php_mongo_serialize_int(buf, Z_LVAL_PP(data));
     break;
   case IS_DOUBLE:
-    set_type(buf, BSON_DOUBLE);
-    serialize_string(buf, name, name_len);
-    serialize_double(buf, Z_DVAL_PP(data));
+    php_mongo_set_type(buf, BSON_DOUBLE);
+    php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
+    php_mongo_serialize_double(buf, Z_DVAL_PP(data));
     break;
   case IS_BOOL:
-    set_type(buf, BSON_BOOL);
-    serialize_string(buf, name, name_len);
-    serialize_bool(buf, Z_BVAL_PP(data));
+    php_mongo_set_type(buf, BSON_BOOL);
+    php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
+    php_mongo_serialize_bool(buf, Z_BVAL_PP(data));
     break;
   case IS_STRING: {
-    set_type(buf, BSON_STRING);
-    serialize_string(buf, name, name_len);
+    php_mongo_set_type(buf, BSON_STRING);
+    php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);

-    serialize_int(buf, Z_STRLEN_PP(data)+1);
-    serialize_string(buf, Z_STRVAL_PP(data), Z_STRLEN_PP(data));
+    php_mongo_serialize_int(buf, Z_STRLEN_PP(data)+1);
+    php_mongo_serialize_string(buf, Z_STRVAL_PP(data), Z_STRLEN_PP(data));
     break;
   }
   case IS_ARRAY: {
@@ -179,11 +179,11 @@
     buf->pos++;

     //serialize
-    serialize_string(buf, name, name_len);
+    php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
     num = zval_to_bson(buf, Z_ARRVAL_PP(data), NO_PREP TSRMLS_CC);

     // now go back and set the type bit
-    //set_type(buf, BSON_ARRAY);
+    //php_mongo_set_type(buf, BSON_ARRAY);
     if (num == zend_hash_num_elements(Z_ARRVAL_PP(data))) {
       buf->start[type_offset] = BSON_ARRAY;
     }
@@ -200,22 +200,22 @@
     if(clazz == mongo_ce_Id) {
       mongo_id *id;

-      set_type(buf, BSON_OID);
-      serialize_string(buf, name, name_len);
+      php_mongo_set_type(buf, BSON_OID);
+      php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
       id = (mongo_id*)zend_object_store_get_object(*data TSRMLS_CC);
       if (!id->id) {
 	return ZEND_HASH_APPLY_KEEP;
       }

-      serialize_bytes(buf, id->id, OID_SIZE);
+      php_mongo_serialize_bytes(buf, id->id, OID_SIZE);
     }
     // MongoDate
     else if (clazz == mongo_ce_Date) {
       zval *zsec, *zusec;
       int64_t sec, usec, ms;

-      set_type(buf, BSON_DATE);
-      serialize_string(buf, name, name_len);
+      php_mongo_set_type(buf, BSON_DATE);
+      php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);

       zsec = zend_read_property(mongo_ce_Date, *data, "sec", 3, 0 TSRMLS_CC);
       sec = Z_LVAL_P(zsec);
@@ -223,68 +223,68 @@
       usec = Z_LVAL_P(zusec);

       ms = (sec * 1000) + (usec / 1000);
-      serialize_long(buf, ms);
+      php_mongo_serialize_long(buf, ms);
     }
     // MongoRegex
     else if (clazz == mongo_ce_Regex) {
       zval *zid;

-      set_type(buf, BSON_REGEX);
-      serialize_string(buf, name, name_len);
+      php_mongo_set_type(buf, BSON_REGEX);
+      php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);
       zid = zend_read_property(mongo_ce_Regex, *data, "regex", 5, 0 TSRMLS_CC);
-      serialize_string(buf, Z_STRVAL_P(zid), Z_STRLEN_P(zid));
+      php_mongo_serialize_string(buf, Z_STRVAL_P(zid), Z_STRLEN_P(zid));
       zid = zend_read_property(mongo_ce_Regex, *data, "flags", 5, 0 TSRMLS_CC);
-      serialize_string(buf, Z_STRVAL_P(zid), Z_STRLEN_P(zid));
+      php_mongo_serialize_string(buf, Z_STRVAL_P(zid), Z_STRLEN_P(zid));
     }
     // MongoCode
     else if (clazz == mongo_ce_Code) {
       uint start;
       zval *zid;

-      set_type(buf, BSON_CODE);
-      serialize_string(buf, name, name_len);
+      php_mongo_set_type(buf, BSON_CODE);
+      php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);

       // save spot for size
       start = buf->pos-buf->start;
       buf->pos += INT_32;
       zid = zend_read_property(mongo_ce_Code, *data, "code", 4, NOISY TSRMLS_CC);
       // string size
-      serialize_int(buf, Z_STRLEN_P(zid)+1);
+      php_mongo_serialize_int(buf, Z_STRLEN_P(zid)+1);
       // string
-      serialize_string(buf, Z_STRVAL_P(zid), Z_STRLEN_P(zid));
+      php_mongo_serialize_string(buf, Z_STRVAL_P(zid), Z_STRLEN_P(zid));
       // scope
       zid = zend_read_property(mongo_ce_Code, *data, "scope", 5, NOISY TSRMLS_CC);
       zval_to_bson(buf, HASH_P(zid), NO_PREP TSRMLS_CC);

       // get total size
-      serialize_size(buf->start+start, buf);
+      php_mongo_serialize_size(buf->start+start, buf);
     }
     // MongoBin
     else if (clazz == mongo_ce_BinData) {
       zval *zbin, *ztype;

-      set_type(buf, BSON_BINARY);
-      serialize_string(buf, name, name_len);
+      php_mongo_set_type(buf, BSON_BINARY);
+      php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);

       zbin = zend_read_property(mongo_ce_BinData, *data, "bin", 3, 0 TSRMLS_CC);
-      serialize_int(buf, Z_STRLEN_P(zbin));
+      php_mongo_serialize_int(buf, Z_STRLEN_P(zbin));

       ztype = zend_read_property(mongo_ce_BinData, *data, "type", 4, 0 TSRMLS_CC);
-      serialize_byte(buf, (unsigned char)Z_LVAL_P(ztype));
+      php_mongo_serialize_byte(buf, (unsigned char)Z_LVAL_P(ztype));

       if(BUF_REMAINING <= Z_STRLEN_P(zbin)) {
         resize_buf(buf, Z_STRLEN_P(zbin));
       }

-      serialize_bytes(buf, Z_STRVAL_P(zbin), Z_STRLEN_P(zbin));
+      php_mongo_serialize_bytes(buf, Z_STRVAL_P(zbin), Z_STRLEN_P(zbin));
     }
     // serialize a normal obj
     else {
       HashTable *hash = Z_OBJPROP_PP(data);

       // go through the k/v pairs and serialize them
-      set_type(buf, BSON_OBJECT);
-      serialize_string(buf, name, name_len);
+      php_mongo_set_type(buf, BSON_OBJECT);
+      php_mongo_serialize_key(buf, name, name_len, prep TSRMLS_CC);

       zval_to_bson(buf, hash, NO_PREP TSRMLS_CC);
     }
@@ -310,6 +310,117 @@
   return total;
 }

+void php_mongo_serialize_byte(buffer *buf, char b) {
+  if(BUF_REMAINING <= 1) {
+    resize_buf(buf, 1);
+  }
+  *(buf->pos) = b;
+  buf->pos += 1;
+}
+
+void php_mongo_serialize_bytes(buffer *buf, char *str, int str_len) {
+  if(BUF_REMAINING <= str_len) {
+    resize_buf(buf, str_len);
+  }
+  memcpy(buf->pos, str, str_len);
+  buf->pos += str_len;
+}
+
+void php_mongo_serialize_string(buffer *buf, char *str, int str_len) {
+  if(BUF_REMAINING <= str_len+1) {
+    resize_buf(buf, str_len+1);
+  }
+
+  memcpy(buf->pos, str, str_len);
+  // add \0 at the end of the string
+  buf->pos[str_len] = 0;
+  buf->pos += str_len + 1;
+}
+
+void php_mongo_serialize_int(buffer *buf, int num) {
+  if(BUF_REMAINING <= INT_32) {
+    resize_buf(buf, INT_32);
+  }
+  memcpy(buf->pos, &num, INT_32);
+  buf->pos += INT_32;
+}
+
+void php_mongo_serialize_long(buffer *buf, int64_t num) {
+  if(BUF_REMAINING <= INT_64) {
+    resize_buf(buf, INT_64);
+  }
+  memcpy(buf->pos, &num, INT_64);
+  buf->pos += INT_64;
+}
+
+void php_mongo_serialize_double(buffer *buf, double num) {
+  if(BUF_REMAINING <= INT_64) {
+    resize_buf(buf, INT_64);
+  }
+  memcpy(buf->pos, &num, DOUBLE_64);
+  buf->pos += DOUBLE_64;
+}
+
+/*
+ * prep == true
+ *    we are inserting, so keys can't have .s in them
+ */
+void php_mongo_serialize_key(buffer *buf, char *str, int str_len, int prep \
TSRMLS_DC) { +  if(BUF_REMAINING <= str_len+1) {
+    resize_buf(buf, str_len+1);
+  }
+
+  if (prep && (strchr(str, '.') != 0)) {
+    zend_error(E_ERROR, "invalid key name: [%s]", str);
+  }
+
+  if (MonGlo(cmd_char) && strchr(str, MonGlo(cmd_char)[0]) == str) {
+    *(buf->pos) = '$';
+    memcpy(buf->pos+1, str+1, str_len-1);
+  }
+  else {
+    memcpy(buf->pos, str, str_len);
+  }
+
+  // add \0 at the end of the string
+  buf->pos[str_len] = 0;
+  buf->pos += str_len + 1;
+}
+
+void php_mongo_serialize_ns(buffer *buf, char *str TSRMLS_DC) {
+  char *collection = strchr(str, '.')+1;
+
+  if(BUF_REMAINING <= (int)strlen(str)+1) {
+    resize_buf(buf, strlen(str)+1);
+  }
+
+  if (MonGlo(cmd_char) && strchr(collection, MonGlo(cmd_char)[0]) == collection) {
+    char *tmp = buf->pos;
+    memcpy(buf->pos, str, collection-str);
+    buf->pos += collection-str;
+    *(buf->pos) = '$';
+    memcpy(buf->pos+1, collection+1, strlen(collection)-1);
+    buf->pos[strlen(collection)] = 0;
+    buf->pos += strlen(collection) + 1;
+  }
+  else {
+    memcpy(buf->pos, str, strlen(str));
+    buf->pos[strlen(str)] = 0;
+    buf->pos += strlen(str) + 1;
+  }
+}
+
+
+/* the position is not increased, we are just filling
+ * in the first 4 bytes with the size.
+ */
+void php_mongo_serialize_size(unsigned char *start, buffer *buf) {
+  int total = buf->pos - start;
+  memcpy(start, &total, INT_32);
+
+}
+
+
 char* bson_to_zval(char *buf, HashTable *result TSRMLS_DC) {
   char type;

@@ -392,12 +503,12 @@
       break;
     }
     case BSON_LONG: {
-      ZVAL_DOUBLE(value, (double)*((int64_t *)buf));
+      ZVAL_DOUBLE(value, (double)*((int64_t*)buf));
       buf += INT_64;
       break;
     }
     case BSON_DATE: {
-      int64_t d = *((int64_t *)buf);
+      int64_t d = *((int64_t*)buf);
       buf += INT_64;

       object_init_ex(value, mongo_ce_Date);

Modified: pecl/mongo/trunk/bson.h
===================================================================
--- pecl/mongo/trunk/bson.h	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/bson.h	2009-09-29 21:16:57 UTC (rev 288966)
@@ -16,9 +16,6 @@
 #ifndef PHP_BSON_H
 #define PHP_BSON_H 1

-#ifdef PHP_WIN32
-# include "win32/php_stdint.h"
-#endif

 #define INT_32 4
 #define INT_64 8
@@ -48,79 +45,23 @@

 #define GROW_SLOWLY 1048576

-#ifndef INLINE
-# if __GNUC__ && !__GNUC_STDC_INLINE__
-#  define INLINE extern inline
-# else
-#  define INLINE inline
-# endif
-#endif
+void php_mongo_serialize_size(unsigned char*, buffer*);

-int serialize_element(char*, zval**, buffer*, int TSRMLS_DC);

-INLINE void serialize_byte(buffer *buf, char b) {
-  if(BUF_REMAINING <= 1) {
-    resize_buf(buf, 1);
-  }
-  *(buf->pos) = b;
-  buf->pos += 1;
-}
+int php_mongo_serialize_element(char*, zval**, buffer*, int TSRMLS_DC);
+void php_mongo_serialize_double(buffer*, double);
+void php_mongo_serialize_string(buffer*, char*, int);
+void php_mongo_serialize_long(buffer*, int64_t);
+void php_mongo_serialize_int(buffer*, int);
+void php_mongo_serialize_byte(buffer*, char);
+void php_mongo_serialize_bytes(buffer*, char*, int);
+void php_mongo_serialize_key(buffer*, char*, int, int TSRMLS_DC);
+void php_mongo_serialize_ns(buffer*, char* TSRMLS_DC);

-INLINE void serialize_bytes(buffer *buf, char *str, int str_len) {
-  if(BUF_REMAINING <= str_len) {
-    resize_buf(buf, str_len);
-  }
-  memcpy(buf->pos, str, str_len);
-  buf->pos += str_len;
-}
+#define php_mongo_set_type(buf, type) php_mongo_serialize_byte(buf, (char)type)
+#define php_mongo_serialize_null(buf) php_mongo_serialize_byte(buf, (char)0)
+#define php_mongo_serialize_bool(buf, b) php_mongo_serialize_byte(buf, (char)b)

-INLINE void serialize_double(buffer *buf, double num) {
-  if(BUF_REMAINING <= INT_64) {
-    resize_buf(buf, INT_64);
-  }
-  memcpy(buf->pos, &num, DOUBLE_64);
-  buf->pos += DOUBLE_64;
-}
-
-INLINE void serialize_int(buffer *buf, int num) {
-  if(BUF_REMAINING <= INT_32) {
-    resize_buf(buf, INT_32);
-  }
-  memcpy(buf->pos, &num, INT_32);
-  buf->pos += INT_32;
-}
-
-INLINE void serialize_long(buffer *buf, int64_t num) {
-  if(BUF_REMAINING <= INT_64) {
-    resize_buf(buf, INT_64);
-  }
-  memcpy(buf->pos, &num, INT_64);
-  buf->pos += INT_64;
-}
-
-/* the position is not increased, we are just filling
- * in the first 4 bytes with the size.
- */
-INLINE void serialize_size(unsigned char *start, buffer *buf) {
-  unsigned int total = buf->pos - start;
-  memcpy(start, &total, INT_32);
-}
-
-INLINE void serialize_string(buffer *buf, char *str, int str_len) {
-  if(BUF_REMAINING <= str_len+1) {
-    resize_buf(buf, str_len+1);
-  }
-
-  memcpy(buf->pos, str, str_len);
-  // add \0 at the end of the string
-  buf->pos[str_len] = 0;
-  buf->pos += str_len + 1;
-}
-
-#define set_type(buf, type) serialize_byte(buf, (char)type)
-#define serialize_null(buf) serialize_byte(buf, (char)0)
-#define serialize_bool(buf, b) serialize_byte(buf, (char)b)
-
 int resize_buf(buffer*, int);

 int zval_to_bson(buffer*, HashTable*, int TSRMLS_DC);

Modified: pecl/mongo/trunk/collection.c
===================================================================
--- pecl/mongo/trunk/collection.c	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/collection.c	2009-09-29 21:16:57 UTC (rev 288966)
@@ -32,7 +32,8 @@
   *mongo_ce_DB,
   *mongo_ce_Cursor,
   *mongo_ce_Code,
-  *mongo_ce_Exception;
+  *mongo_ce_Exception,
+  *mongo_ce_CursorException;

 extern int le_pconnection,
   le_connection;
@@ -101,7 +102,8 @@

   MAKE_STD_ZVAL(data);
   array_init(data);
-  add_assoc_string(data, "drop", Z_STRVAL_P(c->name), 1);
+  add_assoc_zval(data, "drop", c->name);
+  zval_add_ref(&c->name);

   PUSH_PARAM(data); PUSH_PARAM((void*)1);
   PUSH_EO_PARAM();
@@ -140,15 +142,15 @@

 PHP_METHOD(MongoCollection, insert) {
   zval *a;
+  zend_bool *safe = 0;
   mongo_collection *c;
   mongo_link *link;
   int response;
   mongo_msg_header header;
-  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  buffer buf;

-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &a) == FAILURE ||
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &a, &safe) == FAILURE \
||  IS_SCALAR_P(a)) {
-    efree(buf.start);
     return;
   }

@@ -157,7 +159,8 @@

   ZEND_FETCH_RESOURCE2(link, mongo_link*, &c->db->link, -1, PHP_CONNECTION_RES_NAME, \
le_connection, le_pconnection);

-  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), Z_STRLEN_P(c->ns), OP_INSERT);
+  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), OP_INSERT);

   // serialize
   if (zval_to_bson(&buf, HASH_P(a), PREP TSRMLS_CC) == 0 &&
@@ -167,13 +170,67 @@
     RETURN_FALSE;
   }

-  serialize_size(buf.start, &buf);
+  php_mongo_serialize_size(buf.start, &buf);

-  // sends
-  response = mongo_say(link, &buf TSRMLS_CC);
-  efree(buf.start);
+  if (safe) {
+    zval temp;
+    zval *cmd, *cursor_z, *cmd_ns_z;
+    char *start = buf.pos, *cmd_ns;
+    mongo_cursor *cursor;
+
+    MAKE_STD_ZVAL(cmd_ns_z);
+
+    spprintf(&cmd_ns, 0, "%s.$cmd", Z_STRVAL_P(c->db->name));
+    /* add a query */
+    CREATE_HEADER(buf, cmd_ns, OP_QUERY);
+    ZVAL_STRING(cmd_ns_z, cmd_ns, 0);
+
+    php_mongo_serialize_int(&buf, 0);
+    php_mongo_serialize_int(&buf, -1);
+
+    MAKE_STD_ZVAL(cmd);
+    array_init(cmd);
+    add_assoc_long(cmd, "getlasterror", 1);
+
+    zval_to_bson(&buf, HASH_P(cmd), NO_PREP TSRMLS_CC);
+
+    php_mongo_serialize_size(start, &buf);
+
+    zval_ptr_dtor(&cmd);
+
+    /* send everything */
+    response = mongo_say(link, &buf TSRMLS_CC);
+    efree(buf.start);
+    if (response == FAILURE) {
+      zval_ptr_dtor(&cmd_ns_z);
+      zend_throw_exception(mongo_ce_CursorException, "couldn't send query.", 0 \
TSRMLS_CC); +      return;
+    }
+
+    MAKE_STD_ZVAL(cursor_z);
+    object_init_ex(cursor_z, mongo_ce_Cursor);
+
+    PUSH_PARAM(c->db->link); PUSH_PARAM(cmd_ns_z); PUSH_PARAM((void*)2);
+    PUSH_EO_PARAM();
+    MONGO_METHOD(MongoCursor, __construct)(2, &temp, NULL, cursor_z, 0 TSRMLS_CC);
+    POP_EO_PARAM();
+    POP_PARAM(); POP_PARAM(); POP_PARAM();
+
+    /* get the response */
+    cursor = (mongo_cursor*)zend_object_store_get_object(cursor_z TSRMLS_CC);
+    php_mongo_get_reply(cursor TSRMLS_CC);
+
+    MONGO_METHOD(MongoCursor, getNext)(0, return_value, NULL, cursor_z, 0 \
TSRMLS_CC); +
+    zval_ptr_dtor(&cursor_z);
+    zval_ptr_dtor(&cmd_ns_z);
+  }
+  else {
+    response = mongo_say(link, &buf TSRMLS_CC);
+    efree(buf.start);

-  RETURN_BOOL(response >= SUCCESS);
+    RETURN_BOOL(response >= SUCCESS);
+  }
 }

 PHP_METHOD(MongoCollection, batchInsert) {
@@ -185,7 +242,7 @@
   zval **data;
   HashPosition pointer;
   mongo_msg_header header;
-  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  buffer buf;

   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &a) == FAILURE) {
     return;
@@ -196,7 +253,8 @@

   ZEND_FETCH_RESOURCE2(link, mongo_link*, &c->db->link, -1, PHP_CONNECTION_RES_NAME, \
le_connection, le_pconnection);

-  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), Z_STRLEN_P(c->ns), OP_INSERT);
+  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), OP_INSERT);

   php_array = HASH_P(a);

@@ -211,7 +269,7 @@
     start = buf.pos-buf.start;
     zval_to_bson(&buf, HASH_PP(data), PREP TSRMLS_CC);

-    serialize_size(buf.start+start, &buf);
+    php_mongo_serialize_size(buf.start+start, &buf);

     count++;
   }
@@ -222,7 +280,7 @@
     RETURN_FALSE;
   }

-  serialize_size(buf.start, &buf);
+  php_mongo_serialize_size(buf.start, &buf);

   RETVAL_BOOL(mongo_say(link, &buf TSRMLS_CC)+1);
   efree(buf.start);
@@ -320,12 +378,11 @@
   mongo_collection *c;
   mongo_link *link;
   mongo_msg_header header;
-  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  buffer buf;

   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|b", &criteria, &newobj, \
&upsert) == FAILURE ||  IS_SCALAR_P(criteria) ||
       IS_SCALAR_P(newobj)) {
-    efree(buf.start);
     return;
   }

@@ -334,11 +391,12 @@

   ZEND_FETCH_RESOURCE2(link, mongo_link*, &c->db->link, -1, PHP_CONNECTION_RES_NAME, \
le_connection, le_pconnection);

-  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), Z_STRLEN_P(c->ns), OP_UPDATE);
-  serialize_int(&buf, upsert);
+  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), OP_UPDATE);
+  php_mongo_serialize_int(&buf, upsert);
   zval_to_bson(&buf, HASH_P(criteria), NO_PREP TSRMLS_CC);
   zval_to_bson(&buf, HASH_P(newobj), NO_PREP TSRMLS_CC);
-  serialize_size(buf.start, &buf);
+  php_mongo_serialize_size(buf.start, &buf);

   RETVAL_BOOL(mongo_say(link, &buf TSRMLS_CC)+1);
   efree(buf.start);
@@ -351,11 +409,10 @@
   mongo_link *link;
   int mflags;
   mongo_msg_header header;
-  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  buffer buf;

   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zb", &criteria, &just_one) \
== FAILURE ||  (ZEND_NUM_ARGS() > 0 && IS_SCALAR_P(criteria))) {
-    efree(buf.start);
     return;
   }

@@ -372,13 +429,14 @@

   ZEND_FETCH_RESOURCE2(link, mongo_link*, &c->db->link, -1, PHP_CONNECTION_RES_NAME, \
le_connection, le_pconnection);

-  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), Z_STRLEN_P(c->ns), OP_DELETE);
+  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  CREATE_HEADER(buf, Z_STRVAL_P(c->ns), OP_DELETE);

   mflags = (just_one == 1);

-  serialize_int(&buf, mflags);
+  php_mongo_serialize_int(&buf, mflags);
   zval_to_bson(&buf, HASH_P(criteria), NO_PREP TSRMLS_CC);
-  serialize_size(buf.start, &buf);
+  php_mongo_serialize_size(buf.start, &buf);

   RETVAL_BOOL(mongo_say(link, &buf TSRMLS_CC)+1);

@@ -799,68 +857,58 @@
 /* {{{ MongoCollection::group
  */
 PHP_METHOD(MongoCollection, group) {
-  // TODO: keyf
-  zval temp;
-  zval *params, *key, *initial, *condition = 0, *groupFunction, *code, \
                *almost_return;
-  zval **retval, **result;
-  char *function_str, *reduce;
-  int reduce_len;
+  zval *key, *initial, *condition = 0, *group, *cmd, *reduce;
   mongo_collection *c = (mongo_collection*)zend_object_store_get_object(getThis() \
TSRMLS_CC);  MONGO_CHECK_INITIALIZED(c->ns, MongoCollection);

-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aas|z", &key, &initial, \
&reduce, &reduce_len, &condition) == FAILURE) { +  if \
(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aaz|z", &key, &initial, &reduce, \
&condition) == FAILURE) {  return;
   }

-  MAKE_STD_ZVAL(code);
-  spprintf(&function_str, 0, "function() { var c = db[ns].find(condition); var map = \
new Map(); var reduce_function = %s; while (c.hasNext()) { var obj = c.next(); var \
key = {}; for (var i in keys) { key[keys[i]] = obj[keys[i]]; } var aggObj = \
map.get(key); if (aggObj == null) { var newObj = Object.extend({}, key); aggObj = \
Object.extend(newObj, initial); map.put(key, aggObj); } reduce_function(obj, aggObj); \
                } return {\"result\": map.values()}; }", reduce);
-  ZVAL_STRING(code, function_str, 0);
+  if (Z_TYPE_P(reduce) == IS_STRING) {
+    zval *code;
+    MAKE_STD_ZVAL(code);
+    object_init_ex(code, mongo_ce_Code);

-  MAKE_STD_ZVAL(params);
-  array_init(params);
-  add_assoc_zval(params, "ns", c->name);
+    PUSH_PARAM(reduce); PUSH_PARAM((void*)1);
+    PUSH_EO_PARAM();
+    MONGO_METHOD(MongoCode, __construct)(1, return_value, NULL, code, \
return_value_used TSRMLS_CC); +    POP_EO_PARAM();
+    POP_PARAM(); POP_PARAM();
+
+    reduce = code;
+  }
+  else if (Z_TYPE_P(reduce) == IS_OBJECT &&
+           Z_OBJCE_P(reduce) == mongo_ce_Code) {
+    zval_add_ref(&reduce);
+  }
+
+  MAKE_STD_ZVAL(cmd);
+  array_init(cmd);
+
+  MAKE_STD_ZVAL(group);
+  array_init(group);
+  add_assoc_zval(group, "ns", c->name);
   zval_add_ref(&c->name);
-  add_assoc_zval(params, "keys", key);
+  add_assoc_zval(group, "$reduce", reduce);
+  zval_add_ref(&reduce);
+  add_assoc_zval(group, "key", key);
   zval_add_ref(&key);
-  add_assoc_zval(params, "initial", initial);
+  add_assoc_zval(group, "cond", condition);
+  zval_add_ref(&condition);
+  add_assoc_zval(group, "initial", initial);
   zval_add_ref(&initial);
-  if (condition) {
-    add_assoc_zval(params, "condition", condition);
-    zval_add_ref(&condition);
-  }
-  else  {
-    zval *empty;
-    MAKE_STD_ZVAL(empty);
-    array_init(empty);
-    add_assoc_zval(params, "condition", empty);
-  }

-  MAKE_STD_ZVAL(groupFunction);
-  object_init_ex(groupFunction, mongo_ce_Code);
+  add_assoc_zval(cmd, "group", group);

-  PUSH_PARAM(code); PUSH_PARAM(params); PUSH_PARAM((void*)2);
+  PUSH_PARAM(cmd); PUSH_PARAM((void*)1);
   PUSH_EO_PARAM();
-  MONGO_METHOD(MongoCode, __construct)(2, &temp, NULL, groupFunction, \
return_value_used TSRMLS_CC); +  MONGO_METHOD(MongoDB, command)(1, return_value, \
NULL, c->parent, return_value_used TSRMLS_CC);  POP_EO_PARAM();
-  POP_PARAM(); POP_PARAM(); POP_PARAM();
-
-  MAKE_STD_ZVAL(almost_return);
-  PUSH_PARAM(groupFunction);; PUSH_PARAM((void*)1);
-  PUSH_EO_PARAM();
-  MONGO_METHOD(MongoDB, execute)(1, almost_return, NULL, c->parent, \
                return_value_used TSRMLS_CC);
-  POP_EO_PARAM();
   POP_PARAM(); POP_PARAM();

-  zval_ptr_dtor(&code);
-  zval_ptr_dtor(&groupFunction);
-  zval_ptr_dtor(&params);
-
-  if (zend_hash_find(HASH_P(almost_return), "retval", 7, (void**)&retval) == \
                SUCCESS) {
-    if (zend_hash_find(HASH_PP(retval), "result", 7, (void**)&result) == SUCCESS) {
-      RETVAL_ZVAL(*result, 1, 0);
-    }
-  }
-  zval_ptr_dtor(&almost_return);
+  zval_ptr_dtor(&cmd);
+  zval_ptr_dtor(&reduce);
 }
 /* }}} */


Modified: pecl/mongo/trunk/config.m4
===================================================================
--- pecl/mongo/trunk/config.m4	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/config.m4	2009-09-29 21:16:57 UTC (rev 288966)
@@ -1,9 +1,6 @@
 PHP_ARG_ENABLE(mongo, whether to enable Mongo extension,
 [  --enable-mongo   Enable Mongo extension])

-PHP_ARG_ENABLE(osx, whether to compile for the gaggle of osx architectures,
-[  --enable-osx   Compile for the gaggle of osx architectures], no, no)
-
 if test "$PHP_MONGO" != "no"; then
   AC_DEFINE(HAVE_MONGO, 1, [Whether you have Mongo extension])
   PHP_NEW_EXTENSION(mongo, mongo.c mongo_types.c bson.c cursor.c collection.c db.c \
gridfs.c, $ext_shared) @@ -11,8 +8,17 @@
   PHP_ADD_EXTENSION_DEP(mongo, date, false)
   PHP_ADD_EXTENSION_DEP(mongo, spl, false)

-  if test "$PHP_OSX" != "no"; then
+  case $build_os in
+  darwin10.0.0)
+    AC_MSG_CHECKING([whether to compile for recent osx architectures])
+    CFLAGS="$CFLAGS -arch i386 -arch x86_64"
+    AC_MSG_RESULT([yes])
+    ;;
+  darwin*)
+    AC_MSG_CHECKING([whether to compile for every osx architecture ever])
     CFLAGS="$CFLAGS -arch i386 -arch x86_64 -arch ppc -arch ppc64"
-  fi
+    AC_MSG_RESULT([yes])
+    ;;
+  esac
 fi


Modified: pecl/mongo/trunk/cursor.c
===================================================================
--- pecl/mongo/trunk/cursor.c	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/cursor.c	2009-09-29 21:16:57 UTC (rev 288966)
@@ -171,10 +171,10 @@
   buf.pos = buf.start;
   buf.end = buf.start + size;

-  CREATE_RESPONSE_HEADER(buf, cursor->ns, strlen(cursor->ns), \
                cursor->header.request_id, OP_GET_MORE);
-  serialize_int(&buf, cursor->limit);
-  serialize_long(&buf, cursor->cursor_id);
-  serialize_size(buf.start, &buf);
+  CREATE_RESPONSE_HEADER(buf, cursor->ns, cursor->header.request_id, OP_GET_MORE);
+  php_mongo_serialize_int(&buf, cursor->limit);
+  php_mongo_serialize_long(&buf, cursor->cursor_id);
+  php_mongo_serialize_size(buf.start, &buf);

   // fails if we're out of elems
   if(mongo_say(cursor->link, &buf TSRMLS_CC) == FAILURE) {
@@ -186,7 +186,7 @@

   // if we have cursor->at == cursor->num && recv fails,
   // we're probably just out of results
-  RETURN_BOOL(get_reply(cursor TSRMLS_CC) == SUCCESS);
+  RETURN_BOOL(php_mongo_get_reply(cursor TSRMLS_CC) == SUCCESS);
 }
 /* }}} */

@@ -339,15 +339,25 @@
 /* {{{ MongoCursor->explain
  */
 PHP_METHOD(MongoCursor, explain) {
+  int temp_limit;
   zval *query;
   mongo_cursor *cursor = (mongo_cursor*)zend_object_store_get_object(getThis() \
TSRMLS_CC);  MONGO_CHECK_INITIALIZED(cursor->link, MongoCursor);

+  // make explain use a hard limit
+  temp_limit = cursor->limit;
+  if (cursor->limit > 0) {
+    cursor->limit *= -1;
+  }
+
   query = cursor->query;
   add_assoc_bool(query, "$explain", 1);

   MONGO_METHOD(MongoCursor, reset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
   MONGO_METHOD(MongoCursor, getNext)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+  // reset to original limit
+  cursor->limit = temp_limit;
 }
 /* }}} */

@@ -358,23 +368,24 @@
   int sent;
   mongo_msg_header header;
   mongo_cursor *cursor;
-  CREATE_BUF(buf, INITIAL_BUF_SIZE);
+  buffer buf;

   cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC);
   MONGO_CHECK_INITIALIZED(cursor->link, MongoCursor);

+  CREATE_BUF(buf, INITIAL_BUF_SIZE);
   CREATE_HEADER_WITH_OPTS(buf, cursor->ns, OP_QUERY, cursor->opts);

-  serialize_int(&buf, cursor->skip);
-  serialize_int(&buf, cursor->limit);
+  php_mongo_serialize_int(&buf, cursor->skip);
+  php_mongo_serialize_int(&buf, cursor->limit);

   zval_to_bson(&buf, HASH_P(cursor->query), NO_PREP TSRMLS_CC);
   if (cursor->fields && zend_hash_num_elements(HASH_P(cursor->fields)) > 0) {
     zval_to_bson(&buf, HASH_P(cursor->fields), NO_PREP TSRMLS_CC);
   }

-  serialize_size(buf.start, &buf);
-  // sends
+  php_mongo_serialize_size(buf.start, &buf);
+
   sent = mongo_say(cursor->link, &buf TSRMLS_CC);
   efree(buf.start);
   if (sent == FAILURE) {
@@ -382,7 +393,7 @@
     return;
   }

-  get_reply(cursor TSRMLS_CC);
+  php_mongo_get_reply(cursor TSRMLS_CC);
 }
 /* }}} */

@@ -654,10 +665,10 @@
   APPEND_HEADER(buf, 0);

   // # of cursors
-  serialize_int(&buf, 1);
+  php_mongo_serialize_int(&buf, 1);
   // cursor ids
-  serialize_long(&buf, cursor->cursor_id);
-  serialize_size(buf.start, &buf);
+  php_mongo_serialize_long(&buf, cursor->cursor_id);
+  php_mongo_serialize_size(buf.start, &buf);

   mongo_say(cursor->link, &buf TSRMLS_CC);
 }

Modified: pecl/mongo/trunk/mongo.c
===================================================================
--- pecl/mongo/trunk/mongo.c	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/mongo.c	2009-09-29 21:16:57 UTC (rev 288966)
@@ -58,7 +58,10 @@
 static int getPort(char*);
 static int get_host_and_port(char*, mongo_link* TSRMLS_DC);
 static void mongo_init_MongoExceptions(TSRMLS_D);
+static void run_err(int, zval*, zval* TSRMLS_DC);

+inline void set_disconnected(mongo_link *link);
+
 zend_object_handlers mongo_default_handlers;

 /** Classes */
@@ -147,6 +150,7 @@
 STD_PHP_INI_ENTRY("mongo.default_host", "localhost", PHP_INI_ALL, OnUpdateString, \
default_host, zend_mongo_globals, mongo_globals)  \
STD_PHP_INI_ENTRY("mongo.default_port", "27017", PHP_INI_ALL, OnUpdateLong, \
default_port, zend_mongo_globals, mongo_globals)  \
STD_PHP_INI_ENTRY("mongo.chunk_size", "262144", PHP_INI_ALL, OnUpdateLong, \
default_port, zend_mongo_globals, mongo_globals) +STD_PHP_INI_ENTRY("mongo.cmd", "$", \
PHP_INI_ALL, OnUpdateString, cmd_char, zend_mongo_globals, mongo_globals)  \
PHP_INI_END()  /* }}} */

@@ -276,6 +280,7 @@
   mongo_globals->default_port = 27017;
   mongo_globals->request_id = 3;
   mongo_globals->chunk_size = DEFAULT_CHUNK_SIZE;
+  mongo_globals->cmd_char = 0;
 }
 /* }}} */

@@ -348,6 +353,7 @@

   zend_declare_class_constant_string(mongo_ce_Mongo, "DEFAULT_HOST", \
strlen("DEFAULT_HOST"), MonGlo(default_host) TSRMLS_CC);  \
zend_declare_class_constant_long(mongo_ce_Mongo, "DEFAULT_PORT", \
strlen("DEFAULT_PORT"), MonGlo(default_port) TSRMLS_CC); +  \
zend_declare_class_constant_string(mongo_ce_Mongo, "VERSION", strlen("VERSION"), \
"1.0.0" TSRMLS_CC);

   zend_declare_property_bool(mongo_ce_Mongo, "connected", strlen("connected"), 0, \
ZEND_ACC_PUBLIC TSRMLS_CC);

@@ -867,37 +873,7 @@
 }
 /* }}} */

-static void run_err(char *cmd, zval *return_value, zval *this TSRMLS_DC) {
-  zval *data, *db, *name;
-
-  MAKE_STD_ZVAL(db);
-  MAKE_STD_ZVAL(name);
-  ZVAL_STRING(name, "admin", 1);
-
-  PUSH_PARAM(name); PUSH_PARAM((void*)1);
-  PUSH_EO_PARAM();
-  MONGO_METHOD(Mongo, selectDB)(1, db, NULL, this, 0 TSRMLS_CC);
-  POP_EO_PARAM();
-  POP_PARAM(); POP_PARAM();
-
-  MAKE_STD_ZVAL(data);
-  array_init(data);
-  add_assoc_long(data, cmd, 1);
-
-  PUSH_PARAM(data); PUSH_PARAM((void*)1);
-  PUSH_EO_PARAM();
-  MONGO_METHOD(MongoDB, command)(1, return_value, NULL, db, 0 TSRMLS_CC);
-  POP_EO_PARAM();
-  POP_PARAM(); POP_PARAM();
-
-  zval_ptr_dtor(&db);
-  zval_ptr_dtor(&name);
-  zval_ptr_dtor(&data);
-}
-
-/* {{{ Mongo->lastError()
- */
-PHP_METHOD(Mongo, lastError) {
+static void run_err(int err_type, zval *return_value, zval *this_ptr TSRMLS_DC) {
   zval *db_name, *db;
   MAKE_STD_ZVAL(db_name);
   ZVAL_STRING(db_name, "admin", 1);
@@ -910,29 +886,37 @@
   POP_PARAM(); POP_PARAM();
   zval_ptr_dtor(&db_name);

-  MONGO_METHOD(MongoDB, lastError)(0, return_value, NULL, db, 0 TSRMLS_CC);
+  switch (err_type) {
+  case LAST_ERROR:
+    MONGO_METHOD(MongoDB, lastError)(0, return_value, NULL, db, 0 TSRMLS_CC);
+    break;
+  case PREV_ERROR:
+    MONGO_METHOD(MongoDB, prevError)(0, return_value, NULL, db, 0 TSRMLS_CC);
+    break;
+  case RESET_ERROR:
+    MONGO_METHOD(MongoDB, resetError)(0, return_value, NULL, db, 0 TSRMLS_CC);
+    break;
+  case FORCE_ERROR:
+    MONGO_METHOD(MongoDB, forceError)(0, return_value, NULL, db, 0 TSRMLS_CC);
+    break;
+  }
+
   zval_ptr_dtor(&db);
 }
+
+
+/* {{{ Mongo->lastError()
+ */
+PHP_METHOD(Mongo, lastError) {
+  run_err(LAST_ERROR, return_value, getThis() TSRMLS_CC);
+}
 /* }}} */


 /* {{{ Mongo->prevError()
  */
 PHP_METHOD(Mongo, prevError) {
-  zval *db_name, *db;
-  MAKE_STD_ZVAL(db_name);
-  ZVAL_STRING(db_name, "admin", 1);
-
-  MAKE_STD_ZVAL(db);
-  PUSH_PARAM(db_name); PUSH_PARAM((void*)1);
-  PUSH_EO_PARAM();
-  MONGO_METHOD(Mongo, selectDB)(1, db, NULL, getThis(), 0 TSRMLS_CC);
-  POP_EO_PARAM();
-  POP_PARAM(); POP_PARAM();
-  zval_ptr_dtor(&db_name);
-
-  MONGO_METHOD(MongoDB, prevError)(0, return_value, NULL, db, 0 TSRMLS_CC);
-  zval_ptr_dtor(&db);
+  run_err(PREV_ERROR, return_value, getThis() TSRMLS_CC);
 }
 /* }}} */

@@ -940,40 +924,14 @@
 /* {{{ Mongo->resetError()
  */
 PHP_METHOD(Mongo, resetError) {
-  zval *db_name, *db;
-  MAKE_STD_ZVAL(db_name);
-  ZVAL_STRING(db_name, "admin", 1);
-
-  MAKE_STD_ZVAL(db);
-  PUSH_PARAM(db_name); PUSH_PARAM((void*)1);
-  PUSH_EO_PARAM();
-  MONGO_METHOD(Mongo, selectDB)(1, db, NULL, getThis(), 0 TSRMLS_CC);
-  POP_EO_PARAM();
-  POP_PARAM(); POP_PARAM();
-  zval_ptr_dtor(&db_name);
-
-  MONGO_METHOD(MongoDB, resetError)(0, return_value, NULL, db, 0 TSRMLS_CC);
-  zval_ptr_dtor(&db);
+  run_err(RESET_ERROR, return_value, getThis() TSRMLS_CC);
 }
 /* }}} */

 /* {{{ Mongo->forceError()
  */
 PHP_METHOD(Mongo, forceError) {
-  zval *db_name, *db;
-  MAKE_STD_ZVAL(db_name);
-  ZVAL_STRING(db_name, "admin", 1);
-
-  MAKE_STD_ZVAL(db);
-  PUSH_PARAM(db_name); PUSH_PARAM((void*)1);
-  PUSH_EO_PARAM();
-  MONGO_METHOD(Mongo, selectDB)(1, db, NULL, getThis(), 0 TSRMLS_CC);
-  POP_EO_PARAM();
-  POP_PARAM(); POP_PARAM();
-  zval_ptr_dtor(&db_name);
-
-  MONGO_METHOD(MongoDB, forceError)(0, return_value, NULL, db, 0 TSRMLS_CC);
-  zval_ptr_dtor(&db);
+  run_err(FORCE_ERROR, return_value, getThis() TSRMLS_CC);
 }
 /* }}} */

@@ -1070,28 +1028,40 @@
 }


-int get_reply(mongo_cursor *cursor TSRMLS_DC) {
+int php_mongo_get_reply(mongo_cursor *cursor TSRMLS_DC) {
   int sock = get_master(cursor->link TSRMLS_CC);
   int num_returned = 0;

+  if (check_connection(cursor->link TSRMLS_CC) != SUCCESS) {
+    return FAILURE;
+  }
+
   // if this fails, we might be disconnected... but we're probably
   // just out of results
-#ifdef WIN32
   if (recv(sock, (char*)&cursor->header.length, INT_32, FLAGS) == FAILURE) {
-#else
-  if (read(sock, &cursor->header.length, INT_32) == FAILURE) {
-#endif
+
+    set_disconnected(cursor->link);
+
     return FAILURE;
   }

   // make sure we're not getting crazy data
-  if (cursor->header.length > MAX_RESPONSE_LEN ||
-      cursor->header.length < REPLY_HEADER_SIZE) {
+  if (cursor->header.length == 0) {
+
+    set_disconnected(cursor->link);
+
+    zend_error(E_WARNING, "no db response\n");
+    return FAILURE;
+  }
+  else if (cursor->header.length > MAX_RESPONSE_LEN ||
+           cursor->header.length < REPLY_HEADER_SIZE) {
+
+    set_disconnected(cursor->link);
+
     zend_error(E_WARNING, "bad response length: %d, max: %d, did the db assert?\n", \
cursor->header.length, MAX_RESPONSE_LEN);  return FAILURE;
   }

-#ifdef WIN32
   if (recv(sock, (char*)&cursor->header.request_id, INT_32, FLAGS) == FAILURE ||
       recv(sock, (char*)&cursor->header.response_to, INT_32, FLAGS) == FAILURE ||
       recv(sock, (char*)&cursor->header.op, INT_32, FLAGS) == FAILURE ||
@@ -1099,15 +1069,6 @@
       recv(sock, (char*)&cursor->cursor_id, INT_64, FLAGS) == FAILURE ||
       recv(sock, (char*)&cursor->start, INT_32, FLAGS) == FAILURE ||
       recv(sock, (char*)&num_returned, INT_32, FLAGS) == FAILURE) {
-#else
-  if (read(sock, &cursor->header.request_id, INT_32) == FAILURE ||
-      read(sock, &cursor->header.response_to, INT_32) == FAILURE ||
-      read(sock, &cursor->header.op, INT_32) == FAILURE ||
-      read(sock, &cursor->flag, INT_32) == FAILURE ||
-      read(sock, &cursor->cursor_id, INT_64) == FAILURE ||
-      read(sock, &cursor->start, INT_32) == FAILURE ||
-      read(sock, &num_returned, INT_32) == FAILURE) {
-#endif
     return FAILURE;
   }

@@ -1143,21 +1104,14 @@
   int sock, sent;

   sock = get_master(link TSRMLS_CC);
-
-#ifdef WIN32
   sent = send(sock, (const char*)buf->start, buf->pos-buf->start, FLAGS);
-#else
-  sent = write(sock, buf->start, buf->pos-buf->start);
-#endif

   if (sent == FAILURE) {
+    set_disconnected(link);
+
     if (check_connection(link TSRMLS_CC) == SUCCESS) {
       sock = get_master(link TSRMLS_CC);
-#     ifdef WIN32
       sent = send(sock, (const char*)buf->start, buf->pos-buf->start, FLAGS);
-#     else
-      sent = send(sock, buf->start, buf->pos-buf->start, FLAGS);
-#     endif
     }
     else {
       return FAILURE;
@@ -1191,21 +1145,11 @@
 }

 static int check_connection(mongo_link *link TSRMLS_DC) {
-  int now;
-#ifdef WIN32
-  SYSTEMTIME systemTime;
-  GetSystemTime(&systemTime);
-  now = systemTime.wMilliseconds;
-#else
-  now = time(0);
-#endif
+  int now = time(0);

   if (!MonGlo(auto_reconnect) ||
       (!link->paired && link->server.single.connected) ||
-      (link->paired &&
-       (link->server.paired.lconnected ||
-        link->server.paired.rconnected)) ||
-      (now-link->ts) < 2) {
+      (link->paired && (link->server.paired.lconnected || \
link->server.paired.rconnected))) {  return SUCCESS;
   }

@@ -1214,7 +1158,7 @@
 #ifdef WIN32
   if (link->paired) {
     closesocket(link->server.paired.lsocket);
-	closesocket(link->server.paired.rsocket);
+    closesocket(link->server.paired.rsocket);
   }
   else {
     closesocket(link->server.single.socket);
@@ -1230,9 +1174,21 @@
   }
 #endif

+  set_disconnected(link);
+
   return mongo_do_socket_connect(link TSRMLS_CC);
 }

+inline void set_disconnected(mongo_link *link) {
+  if (link->paired) {
+    link->server.paired.lconnected = 0;
+    link->server.paired.rconnected = 0;
+  }
+  else {
+    link->server.single.connected = 0;
+  }
+}
+
 static int mongo_connect_nonb(int sock, char *host, int port) {
   struct sockaddr_in addr, addr2;
   fd_set rset, wset;

Modified: pecl/mongo/trunk/package.xml
===================================================================
--- pecl/mongo/trunk/package.xml	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/package.xml	2009-09-29 21:16:57 UTC (rev 288966)
@@ -13,20 +13,21 @@
    <email>kristina@10gen.com</email>
    <active>yes</active>
  </lead>
- <date>2009-08-20</date>
+ <date>2009-09-29</date>
  <time>12:00:00</time>
  <version>
-   <release>0.9.5</release>
-   <api>0.9.5</api>
+   <release>1.0.0</release>
+   <api>1.0.0</api>
  </version>
  <stability>
-   <release>beta</release>
-   <api>beta</api>
+   <release>stable</release>
+   <api>stable</api>
  </stability>
  <license uri="http://www.apache.org/licenses/LICENSE-2.0">Apache License</license>
  <notes>
-   Unbreak backwards compatibility
-   Arrays are saved as arrays only if they have ascending numeric indices, otherwise \
they're saved as objects +   Safe insert
+   Configurable special character
+   Error methods are on MongoDB, not Mongo
  </notes>
  <contents>
    <dir baseinstalldir="/" name="/">
@@ -63,6 +64,22 @@
  <changelog>
    <release>
      <stability>
+       <release>stable</release>
+       <api>stable</api>
+     </stability>
+     <version>
+       <release>1.0.0</release>
+       <api>1.0.0</api>
+     </version>
+     <date>2009-09-29</date>
+     <notes>
+       Safe insert
+       Configurable special character
+       Error methods are on MongoDB, not Mongo
+     </notes>
+   </release>
+   <release>
+     <stability>
        <release>beta</release>
        <api>beta</api>
      </stability>

Modified: pecl/mongo/trunk/php_mongo.h
===================================================================
--- pecl/mongo/trunk/php_mongo.h	2009-09-29 21:00:14 UTC (rev 288965)
+++ pecl/mongo/trunk/php_mongo.h	2009-09-29 21:16:57 UTC (rev 288966)
@@ -18,10 +18,6 @@
 #ifndef PHP_MONGO_H
 #define PHP_MONGO_H 1

-#ifdef PHP_WIN32
-# include "win32/php_stdint.h"
-#endif
-
 #define PHP_MONGO_VERSION "1.0"
 #define PHP_MONGO_EXTNAME "mongo"

@@ -29,6 +25,10 @@
 #define PHP_CONNECTION_RES_NAME "mongo connection"
 #define PHP_AUTH_CONNECTION_RES_NAME "mongo authenticated connection"

+#ifdef WIN32
+typedef long long int int64_t;
+#endif
+
 // db ops
 #define OP_REPLY 1
 #define OP_MSG 1000
@@ -66,6 +66,11 @@

 #define FLAGS 0

+#define LAST_ERROR 0
+#define PREV_ERROR 1
+#define RESET_ERROR 2
+#define FORCE_ERROR 3
+
 #if ZEND_MODULE_API_NO >= 20090115
 # define PUSH_PARAM(arg) zend_vm_stack_push(arg TSRMLS_CC)
 # define POP_PARAM() zend_vm_stack_pop(TSRMLS_C)
@@ -139,34 +144,34 @@
   unsigned char *end;
 } buffer;

-#define CREATE_MSG_HEADER(rid, rto, opcode)                     \
-  header.length = 0;                                            \
-  header.request_id = rid;                                      \
-  header.response_to = rto;                                     \
+#define CREATE_MSG_HEADER(rid, rto, opcode)     \
+  header.length = 0;                            \
+  header.request_id = rid;                      \
+  header.response_to = rto;                     \
   header.op = opcode;

-#define CREATE_RESPONSE_HEADER(buf, ns, ns_len, rto, opcode)            \
-  CREATE_MSG_HEADER(MonGlo(request_id)++, rto, opcode);                 \
-  APPEND_HEADER_NS(buf, ns, ns_len, 0);
+#define CREATE_RESPONSE_HEADER(buf, ns, rto, opcode)    \
+  CREATE_MSG_HEADER(MonGlo(request_id)++, rto, opcode); \
+  APPEND_HEADER_NS(buf, ns, 0);

 #define CREATE_HEADER_WITH_OPTS(buf, ns, opcode, opts)  \
   CREATE_MSG_HEADER(MonGlo(request_id)++, 0, opcode);   \
-  APPEND_HEADER_NS(buf, ns, strlen(ns), opts);
+  APPEND_HEADER_NS(buf, ns, opts);

-#define CREATE_HEADER(buf, ns, ns_len, opcode)          \
-  CREATE_RESPONSE_HEADER(buf, ns, ns_len, 0, opcode);
+#define CREATE_HEADER(buf, ns, opcode)          \
+  CREATE_RESPONSE_HEADER(buf, ns, 0, opcode);


-#define APPEND_HEADER(buf, opts) buf.pos += INT_32;       \
-  serialize_int(&buf, header.request_id);                 \
-  serialize_int(&buf, header.response_to);                \
-  serialize_int(&buf, header.op);                         \
-  serialize_int(&buf, opts);
+#define APPEND_HEADER(buf, opts) buf.pos += INT_32;     \
+  php_mongo_serialize_int(&buf, header.request_id);     \
+  php_mongo_serialize_int(&buf, header.response_to);    \
+  php_mongo_serialize_int(&buf, header.op);             \
+  php_mongo_serialize_int(&buf, opts);


-#define APPEND_HEADER_NS(buf, ns, ns_len, opts)         \
-  APPEND_HEADER(buf, opts);                             \
-  serialize_string(&buf, ns, ns_len);
+#define APPEND_HEADER_NS(buf, ns, opts)                         \
+  APPEND_HEADER(buf, opts);                                     \
+  php_mongo_serialize_ns(&buf, ns TSRMLS_CC);


 #define MONGO_CHECK_INITIALIZED(member, class_name)                     \
@@ -248,9 +253,9 @@

 #define BUF_REMAINING (buf->end-buf->pos)

-#define CREATE_BUF(buf, size) buffer buf;               \
-  buf.start = (unsigned char*)emalloc(size);            \
-  buf.pos = buf.start;                                  \
+#define CREATE_BUF(buf, size)                   \
+  buf.start = (unsigned char*)emalloc(size);    \
+  buf.pos = buf.start;                          \
   buf.end = buf.start + size;

 #define DEBUG_BUF(buf)                              \
@@ -294,7 +299,7 @@
 void mongo_do_connect_caller(INTERNAL_FUNCTION_PARAMETERS, zval *username, zval \
*password);  int mongo_say(mongo_link*, buffer* TSRMLS_DC);
 int mongo_hear(mongo_link*, void*, int TSRMLS_DC);
-int get_reply(mongo_cursor* TSRMLS_DC);
+int php_mongo_get_reply(mongo_cursor* TSRMLS_DC);

 void mongo_init_Mongo(TSRMLS_D);
 void mongo_init_MongoDB(TSRMLS_D);
@@ -322,6 +327,7 @@
 long default_port;
 int request_id;
 int chunk_size;
+char *cmd_char;
 ZEND_END_MODULE_GLOBALS(mongo)

 #ifdef ZTS



-- 
PECL CVS Mailing List 
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic