Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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)
}
Ejemplo n.º 4
0
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
}