func (c *C) KillCursors(cursors ...Cursor) error { requestID := c.database.mongo.nextID() responseTo := int32(0) buf := new(bytes.Buffer) buffer.WriteToBuf(buf, int32(0), requestID, responseTo, int32(OP_KILL_CURSORS), int32(len(cursors))) for _, cursor := range cursors { buffer.WriteToBuf(buf, cursor.ID()) } input := buf.Bytes() respSize := make([]byte, 4) binary.LittleEndian.PutUint32(respSize, uint32(len(input))) input[0] = respSize[0] input[1] = respSize[1] input[2] = respSize[2] input[3] = respSize[3] err := c.database.mongo.conn.send(input) if err != nil { return err } for _, cursor := range cursors { c.cursors[cursor.ID()] = nil } return nil }
func (c *C) GetMore(cursor Cursor) (Cursor, error) { requestID := c.database.mongo.nextID() responseTo := int32(0) fullCollectionBytes := []byte(cursor.Namespace()) fullCollectionBytes = append(fullCollectionBytes, byte('\x00')) numberToReturn := cursor.BatchSize() buf := new(bytes.Buffer) buffer.WriteToBuf(buf, int32(0), requestID, responseTo, int32(OP_GET_MORE), int32(0), fullCollectionBytes, numberToReturn, cursor.ID()) input := buf.Bytes() respSize := make([]byte, 4) binary.LittleEndian.PutUint32(respSize, uint32(len(input))) input[0] = respSize[0] input[1] = respSize[1] input[2] = respSize[2] input[3] = respSize[3] res, err := c.database.mongo.conn.sendWithResponse(input) if err != nil { return nil, err } cObj, ok := cursor.(*cursorObj) if !ok { var ok2 bool cObj, ok2 = c.cursors[cursor.ID()] if !ok2 { cObj = &cursorObj{ collection: c, cursorID: cursor.ID(), requestID: requestID, namespace: cursor.Namespace(), limit: cursor.Limit(), batchSize: cursor.BatchSize(), err: cursor.Error(), } c.cursors[cursor.ID()] = cObj } } receiveFindResponse(res, cObj) if err != nil { return nil, err } return cObj, nil }
func (d *DB) run(socket *Connection, command interface{}, result interface{}) error { commandBytes, err := bson.Marshal(command) if err != nil { return err } namespace := d.name + ".$cmd" requestID := d.mongo.nextID() limit := int32(-1) skip := int32(0) responseTo := int32(0) // flags flags := int32(0) fullCollectionBytes := []byte(namespace) fullCollectionBytes = append(fullCollectionBytes, byte('\x00')) buf := new(bytes.Buffer) buffer.WriteToBuf(buf, int32(0), requestID, responseTo, int32(OP_QUERY), flags, fullCollectionBytes, skip, limit, commandBytes) input := buf.Bytes() respSize := make([]byte, 4) binary.LittleEndian.PutUint32(respSize, uint32(len(input))) input[0] = respSize[0] input[1] = respSize[1] input[2] = respSize[2] input[3] = respSize[3] err = socket.send(input) if err != nil { return err } res, err := socket.receive() if err != nil { return err } resultBytes := res.Document[0] return bson.Unmarshal(resultBytes, result) }
func (c *C) Find(query interface{}, options *FindOpts) (Cursor, error) { namespace := c.database.GetName() + "." + c.name requestID := c.database.mongo.nextID() limit := int32(0) skip := int32(0) batchSize := int32(20) if options != nil { limit = options.Limit skip = options.Skip if options.BatchSize > 1 { batchSize = options.BatchSize } } if limit > 1 && batchSize > limit { batchSize = limit } responseTo := int32(0) // flags flags := int32(0) if options != nil { flags = convert.WriteBit32LE(flags, 1, options.Tailable) flags = convert.WriteBit32LE(flags, 4, options.NoCursorTimeout) flags = convert.WriteBit32LE(flags, 5, options.AwaitData) flags = convert.WriteBit32LE(flags, 7, options.Partial) } queryBytes, err := bson.Marshal(query) if err != nil { return nil, err } fullCollectionBytes := []byte(namespace) fullCollectionBytes = append(fullCollectionBytes, byte('\x00')) buf := new(bytes.Buffer) buffer.WriteToBuf(buf, int32(0), requestID, responseTo, int32(OP_QUERY), flags, fullCollectionBytes, skip, batchSize, queryBytes) if options != nil { if options.Projection != nil { projectionBytes, err := bson.Marshal(options.Projection) if err != nil { return nil, err } buffer.WriteToBuf(buf, projectionBytes) } } input := buf.Bytes() respSize := make([]byte, 4) binary.LittleEndian.PutUint32(respSize, uint32(len(input))) input[0] = respSize[0] input[1] = respSize[1] input[2] = respSize[2] input[3] = respSize[3] res, err := c.database.mongo.conn.sendWithResponse(input) if err != nil { return nil, err } cursor := cursorObj{ collection: c, requestID: requestID, limit: limit, batchSize: batchSize, flags: flags, } receiveFindResponse(res, &cursor) if err != nil { return nil, err } c.cursors[cursor.cursorID] = &cursor return &cursor, nil }