// Copy. // // @param dest string // @param args... bool // @return map[string]interface{}, error // @panics func (this *Document) Copy(dest string, args ...bool) (map[string]interface{}, error) { id := this.GetId() if id == "" { panic("_id field could not be empty!") } if dest == "" { panic("Destination could not be empty!") } query, headers := util.Map(), util.Map() headers["Destination"] = dest if args != nil { if args[0] == true { query["batch"] = "ok" } if args[1] == true { headers["X-Couch-Full-Commit"] = "true" } } data, err := this.Database.Client.Copy(this.Database.Name+"/"+util.UrlEncode(id), query, headers). GetBodyData(nil) if err != nil { return nil, err } return map[string]interface{}{ "ok": util.DigBool("ok", data), "id": util.DigString("id", data), "rev": util.DigString("rev", data), }, nil }
// Copy to. // // @param dest string // @param destRev string // @param args... bool // @return map[string]interface{}, error // @panics func (this *Document) CopyTo(dest, destRev string, args ...bool) (map[string]interface{}, error) { id, rev := this.GetId(), this.GetRev() if id == "" || rev == "" { panic("Both _id & _rev fields could not be empty!") } if dest == "" || destRev == "" { panic("Destination & destination revision could not be empty!") } query, headers := util.Map(), util.Map() headers["If-Match"] = rev headers["Destination"] = util.StringFormat("%s?rev=%s", dest, destRev) if args != nil { if args[0] == true { query["batch"] = "ok" } if args[1] == true { headers["X-Couch-Full-Commit"] = "true" } } data, err := this.Database.Client.Copy(this.Database.Name+"/"+util.UrlEncode(id), query, headers). GetBodyData(nil) if err != nil { return nil, err } return map[string]interface{}{ "ok": util.DigBool("ok", data), "id": util.DigString("id", data), "rev": util.DigString("rev", data), }, nil }
// Remove. // // @param args... bool // @return map[string]interface{}, error // @panics func (this *Document) Remove(args ...bool) (map[string]interface{}, error) { id, rev := this.GetId(), this.GetRev() if id == "" || rev == "" { panic("Both _id & _rev fields could not be empty!") } query, headers := util.Map(), util.Map() headers["If-Match"] = rev if args != nil { if args[0] == true { query["batch"] = "ok" } if args[1] == true { headers["X-Couch-Full-Commit"] = "true" } } data, err := this.Database.Client.Delete(this.Database.Name+"/"+util.UrlEncode(id), query, headers). GetBodyData(nil) if err != nil { return nil, err } return map[string]interface{}{ "ok": util.DigBool("ok", data), "id": util.DigString("id", data), "rev": util.DigString("rev", data), }, nil }
// Create database. // // @param target string // @param targetCreate bool // @return bool func (this *Database) Replicate( target string, targetCreate bool) (map[string]interface{}, error) { // prepare body body := util.ParamList( "source", this.Name, "target", target, "create_target", targetCreate, ) data, err := this.Client.Post("/_replicate", nil, body, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() for key, value := range data.(map[string]interface{}) { // grap, set & pass history field if key == "history" { ret[key] = util.MapList(value) for i, history := range value.([]interface{}) { ret[key].([]map[string]interface{})[i] = util.Map() for kkey, vvalue := range history.(map[string]interface{}) { ret[key].([]map[string]interface{})[i][kkey] = vvalue } } continue } ret[key] = value } return ret, nil }
// Get UUID. // // @param body map[string]interface{} // @return map[string]interface{}, error // @panics func (this *Server) Replicate(body map[string]interface{}) (map[string]interface{}, error) { body = util.Param(body) if body["source"] == nil || body["target"] == nil { panic("Both source & target required!") } data, err := this.Client.Post("/_replicate", nil, body, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() for key, value := range data.(map[string]interface{}) { // grap, set & pass history field if key == "history" { ret["history"] = util.MapList(value) for i, history := range value.([]interface{}) { ret["history"].([]map[string]interface{})[i] = util.Map() for kkey, vvalue := range history.(map[string]interface{}) { ret["history"].([]map[string]interface{})[i][kkey] = vvalue } } continue } ret[key] = value } return ret, nil }
// Update documents. // // @param document []map[string]interface{} // @return []map[string]interface{}, error // @panics func (this *Database) UpdateDocumentAll( documents []interface{}) ([]map[string]interface{}, error) { docs := util.MapList(documents) for i, doc := range documents { if docs[i] == nil { docs[i] = util.Map() } for key, value := range doc.(map[string]interface{}) { docs[i][key] = value } // these are required params if docs[i]["_id"] == nil || docs[i]["_rev"] == nil { panic("Both _id & _rev fields are required!") } } body := util.ParamList("docs", docs) data, err := this.Client.Post(this.Name+"/_bulk_docs", nil, body, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.MapList(data) for i, doc := range data.([]interface{}) { if ret[i] == nil { ret[i] = util.Map() } for key, value := range doc.(map[string]interface{}) { ret[i][key] = value } } return ret, nil }
// Ping. // // @param statusCodes... uint16 // @return bool // @panics func (this *DocumentAttachment) Ping(statusCodes ...uint16) bool { if this.Document == nil { panic("Attachment document is not defined!") } docId := this.Document.GetId() docRev := this.Document.GetRev() if docId == "" { panic("Attachment document _id is required!") } if this.FileName == "" { panic("Attachment file name is required!") } query, headers := util.Map(), util.Map() if docRev != "" { query["rev"] = docRev } if this.Digest != "" { headers["If-None-Match"] = util.Quote(this.Digest) } database := this.Document.GetDatabase() response := database.Client.Head(util.StringFormat("%s/%s/%s", database.Name, docId, util.UrlEncode(this.FileName)), query, headers) // try to match given status codes for _, statusCode := range statusCodes { if response.GetStatusCode() == statusCode { return true } } return false }
// Save. // // @param args... bool // @return map[string]interface{}, error func (this *Document) Save(args ...bool) (map[string]interface{}, error) { query, headers, body := util.Map(), util.Map(), this.GetData() if args != nil { if args[0] == true { query["batch"] = "ok" } if args[1] == true { headers["X-Couch-Full-Commit"] = "true" } } if this.Rev != "" { headers["If-Match"] = this.Rev } if this.Attachments != nil { body["_attachments"] = util.Map() for name, attachment := range this.Attachments { body["_attachments"].(map[string]interface{})[name] = attachment.ToArray(true) } } // make a reusable lambda _func := func(data interface{}, err error) (map[string]interface{}, error) { if err != nil { return nil, err } id, rev := util.DigString("id", data), util.DigString("rev", data) // set id & rev for next save() instant calls if id != "" && this.Id == nil { this.SetId(id) } if rev != "" { this.SetRev(rev) } return map[string]interface{}{ "ok": util.DigBool("ok", data), "id": id, "rev": rev, }, nil } if this.Id == nil { return _func( // insert action this.Database.Client.Post(this.Database.Name, query, body, headers). GetBodyData(nil)) } else { return _func( // update action this.Database.Client.Put(this.Database.Name+"/"+this.GetId(), query, body, headers). GetBodyData(nil)) } }
// Get document. // // @param key string // @return map[string]interface{}, error func (this *Database) GetDocument(key string) (map[string]interface{}, error) { // prepare query query := util.ParamList( "include_docs", true, "key", util.Quote(key), ) data, err := this.Client.Get(this.Name+"/_all_docs", query, nil). GetBodyData(&DatabaseDocumentList{}) if err != nil { return nil, err } ret := util.Map() for _, doc := range data.(*DatabaseDocumentList).Rows { ret["id"] = doc.Id ret["key"] = doc.Key ret["value"] = map[string]string{"rev": doc.Value["rev"].(string)} ret["doc"] = map[string]interface{}{} // fill doc field for key, value := range doc.Doc { ret["doc"].(map[string]interface{})[key] = value } } return ret, nil }
// Get changes. // // @param query map[string]interface{} // @return []map[string]interface{}, error func (this *Database) GetChanges( query map[string]interface{}, docIds []string) (map[string]interface{}, error) { query = util.Param(query) if docIds != nil { query["filter"] = "_doc_ids" } body := util.ParamList("doc_ids", docIds) data, err := this.Client.Post(this.Name+"/_changes", query, body, nil). GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() ret["last_seq"] = util.Dig("last_seq", data) ret["results"] = util.MapList(0) // set empty as default if results := data.(map[string]interface{})["results"].([]interface{}); results != nil { ret["results"] = util.MapList(results) // @overwrite for i, result := range results { ret["results"].([]map[string]interface{})[i] = map[string]interface{}{ "id": util.Dig("id", result), "seq": util.Dig("seq", result), "deleted": util.Dig("deleted", result), "changes": util.Dig("changes", result), } } } return ret, nil }
// Constructor. // // @param type_ uint8 // @param httpVersion string // @return couch.http.Stream func NewStream(type_ uint8, httpVersion string) *Stream { return &Stream{ Type: type_, HttpVersion: httpVersion, Headers: util.Map(), } }
// Get missing revisions. // // @param object map[string]interface{} // @return map[string]interface{}, error func (this *Database) GetMissingRevisions( object map[string]interface{}) (map[string]interface{}, error) { data, err := this.Client.Post(this.Name+"/_missing_revs", nil, object, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() ret["missing_revs"] = util.Map() // fill missing revs for id, revs := range data.(map[string]interface{})["missing_revs"].(map[string]interface{}) { ret["missing_revs"].(map[string]interface{})[id] = revs } return ret, nil }
// Purge // // @param object map[string]interface{} // @return map[string]interface{}, error func (this *Database) Purge(object map[string]interface{}) (map[string]interface{}, error) { data, err := this.Client.Post(this.Name+"/_purge", nil, object, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() ret["purge_seq"] = util.DigInt("purge_seq", data) ret["purged"] = util.Map() // fill purged revs for id, revs := range data.(map[string]interface{})["purged"].(map[string]interface{}) { ret["purged"].(map[string]interface{})[id] = revs } return ret, nil }
// View temp. // // @param _map string // @param _red interface{} // @return map[string]interface{}, error func (this *Database) ViewTemp(_map string, _red interface{}) (map[string]interface{}, error) { body := util.ParamList( "map", _map, "reduce", util.IsEmptySet(_red, nil), // prevent "missing function" error ) // short? type ddl DatabaseDocumentList data, err := this.Client.Post(this.Name+"/_temp_view", nil, body, nil).GetBodyData(&ddl{}) if err != nil { return nil, err } ret := util.Map() ret["offset"] = data.(*ddl).Offset ret["total_rows"] = data.(*ddl).TotalRows rows := data.(*ddl).Rows ret["rows"] = util.MapList(len(rows)) // append docs for i, row := range rows { ret["rows"].([]map[string]interface{})[i] = map[string]interface{}{ "id": row.Id, "key": row.Key, "value": row.Value, } } return ret, nil }
// Find attachments // // @param attEncInfo bool // @param attsSince []string // return []map[string]interface{}, error func (this *Document) FindAttachments( attEncInfo bool, attsSince []string) ([]map[string]interface{}, error) { query := util.Map() query["attachments"] = true query["att_encoding_info"] = attEncInfo if attsSince != nil { attsSinceArray := util.MapSliceString(attsSince) for _, attsSinceValue := range attsSince { attsSinceArray = append(attsSinceArray, util.QuoteEncode(attsSinceValue)) } } data, err := this.Find(query) if err != nil { return nil, err } ret := util.MapList(nil) if data["_attachments"] != nil { for _, attc := range data["_attachments"].(map[string]interface{}) { ret = append(ret, attc.(map[string]interface{})) } } return ret, nil }
// Find. // // @return map[string]interface{} // @panics func (this *DocumentAttachment) Find() map[string]interface{} { if this.Document == nil { panic("Attachment document is not defined!") } docId := this.Document.GetId() docRev := this.Document.GetRev() if docId == "" { panic("Attachment document _id is required!") } if this.FileName == "" { panic("Attachment file name is required!") } query, headers := util.Map(), util.Map() if docRev != "" { query["rev"] = docRev } if this.Digest != "" { headers["If-None-Match"] = util.Quote(this.Digest) } headers["Accept"] = "*/*" headers["Content-Type"] = nil // nil=remove database := this.Document.GetDatabase() response := database.Client.Get(util.StringFormat("%s/%s/%s", database.Name, docId, util.UrlEncode(this.FileName)), query, headers) statusCode := response.GetStatusCode() ret := util.Map() // try to match excepted status code if statusCode == 200 || statusCode == 304 { ret["content"] = response.GetBody() ret["content_type"] = response.GetHeader("Content-Type") ret["content_length"] = util.UInt(response.GetHeader("Content-Length")) // set digest md5 := response.GetHeader("Content-MD5") if md5 == nil { md5 = response.GetHeader("ETag") } ret["digest"] = "md5-" + util.Trim(md5.(string), "\"") } return ret }
// Constructor. // // @param couch *couch.http.Couch // @return *couch.Client func NewClient(couch *Couch) *Client { this := &Client{ Scheme: Scheme, Host: Host, Port: Port, Username: Username, Password: Password, } Config := util.Map() Config["Couch.NAME"] = NAME Config["Couch.VERSION"] = VERSION Config["Couch.DEBUG"] = DEBUG // set default // copy Couch configs config := couch.GetConfig() if config != nil { for key, value := range config { Config[key] = value } } // add scheme if provided if scheme := config["Scheme"]; scheme != nil { this.Scheme = scheme.(string) } // add host if provided if host := config["Host"]; host != nil { this.Host = host.(string) } // add port if provided if port := config["Port"]; port != nil { this.Port = port.(uint16) } // add username if provided if username := config["Username"]; username != nil { this.Username = username.(string) } // add password if provided if password := config["Password"]; password != nil { this.Password = password.(string) } Config["Scheme"] = this.Scheme Config["Host"] = this.Host Config["Port"] = this.Port Config["Username"] = this.Username Config["Password"] = this.Password // add debug if provided if debug := couch.Config["debug"]; debug != nil { Config["Couch.DEBUG"] = debug } this.Config = Config return this }
// Constructor. // // @param data map[string]interface{} // @return *couch.query.Query func New(data map[string]interface{}) *Query { if data == nil { data = util.Map() } return &Query{ Data: data, DataString: "", } }
// Remove. // // @return map[string]interface{}, error // @panics func (this *DocumentAttachment) Remove(args ...bool) (map[string]interface{}, error) { if this.Document == nil { panic("Attachment document is not defined!") } docId := this.Document.GetId() docRev := this.Document.GetRev() if docId == "" { panic("Attachment document _id is required!") } if docRev == "" { panic("Attachment document _rev is required!") } if this.FileName == "" { panic("Attachment file name is required!") } query, headers := util.Map(), util.Map() if args != nil { if args[0] { query["batch"] = "ok" } if args[1] { headers["X-Couch-Full-Commit"] = "true" } } headers["If-Match"] = docRev data, err := this.Document.Database.Client.Delete(util.StringFormat( "%s/%s/%s", this.Document.Database.Name, docId, util.UrlEncode(this.FileName), ), nil, headers, ).GetBodyData(nil) if err != nil { return nil, err } return map[string]interface{}{ "ok": util.DigBool("ok", data), "id": util.DigString("id", data), "rev": util.DigString("rev", data), }, nil }
// Constructor. // // @param database *couch.Database // @param data... interface{} // @return *couch.Document func NewDocument(database *Database, data ...interface{}) *Document { this := &Document{ Data: util.Map(), Database: database, } if data != nil { this.SetData(util.ParamList(data...)) } return this }
// Check is not modified. // // @return bool // @panics func (this *Document) IsNotModified() bool { id, rev := this.GetId(), this.GetRev() if id == "" || rev == "" { panic("_id & _rev fields are could not be empty!") } headers := util.Map() headers["If-None-Match"] = util.Quote(rev) return (304 == this.Database.Client. Head(this.Database.Name+"/"+util.UrlEncode(id), nil, headers).GetStatusCode()) }
// Get database info. // // @return map[string]interface{}, error func (this *Database) Info() (map[string]interface{}, error) { data, err := this.Client.Get(this.Name, nil, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() for key, value := range data.(map[string]interface{}) { ret[key] = value } return ret, nil }
// Find revisions. // // @return map[string]interface{}, error func (this *Document) FindRevisions() (map[string]interface{}, error) { data, err := this.Find(util.ParamList("revs", true)) if err != nil { return nil, err } ret := util.Map() if data["_revisions"] != nil { ret["start"] = util.DigInt("_revisions.start", data) ret["ids"] = util.DigSliceString("_revisions.ids", data) } return ret, nil }
// Ping. // // @param statusCode uint16 // @return bool // @panics func (this *Document) Ping(statusCode uint16) bool { id := this.GetId() if id == "" { panic("_id field is could not be empty!") } headers := util.Map() if this.Rev != "" { headers["If-None-Match"] = util.Quote(this.Rev) } return (statusCode == this.Database.Client. Head(this.Database.Name+"/"+util.UrlEncode(id), nil, headers).GetStatusCode()) }
// Create documents. // // @param document []map[string]interface{} // @return []map[string]interface{}, error func (this *Database) CreateDocumentAll( documents []interface{}) ([]map[string]interface{}, error) { docs := util.MapList(documents) for i, doc := range documents { if docs[i] == nil { docs[i] = util.Map() } // filter documents for key, value := range doc.(map[string]interface{}) { // this is create method, no update allowed if key == "_rev" || key == "_deleted" { continue } docs[i][key] = value } } body := util.ParamList("docs", docs) data, err := this.Client.Post(this.Name+"/_bulk_docs", nil, body, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.MapList(data) for i, doc := range data.([]interface{}) { if ret[i] == nil { ret[i] = util.Map() } for key, value := range doc.(map[string]interface{}) { ret[i][key] = value } } return ret, nil }
// Get config. // // @return map[string]map[string]interface{}, error func (this *Server) GetConfig() (map[string]map[string]interface{}, error) { data, err := this.Client.Get("/_config", nil, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.MapMapString() for key, value := range data.(map[string]interface{}) { ret[key] = util.Map() for kkey, vvalue := range value.(map[string]interface{}) { ret[key][kkey] = vvalue } } return ret, nil }
// Get missing revisions diff. // // @param object map[string]interface{} // @return map[string]interface{}, error func (this *Database) GetMissingRevisionsDiff( object map[string]interface{}) (map[string]interface{}, error) { data, err := this.Client.Post(this.Name+"/_revs_diff", nil, object, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() for id, _ := range data.(map[string]interface{}) { ret[id] = map[string]interface{}{ "missing": util.Dig(id+".missing", data), } } return ret, nil }
// Get active tasks. // // @return []map[string]interface{}, error func (this *Server) GetActiveTasks() ([]map[string]interface{}, error) { data, err := this.Client.Get("/_active_tasks", nil, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.MapList(data) for i, data := range data.([]interface{}) { ret[i] = util.Map() for key, value := range data.(map[string]interface{}) { ret[i][key] = value } } return ret, nil }
// Get documents. // // @param query map[string]interface{} // @param keys []string // @return map[string]interface{}, error func (this *Database) GetDocumentAll( query map[string]interface{}, keys []string) (map[string]interface{}, error) { query = util.Param(query) if query["include_docs"] == nil { query["include_docs"] = true } // short? type ddl DatabaseDocumentList // make a reusable lambda _func := func(data interface{}, err error) (map[string]interface{}, error) { if err != nil { return nil, err } ret := util.Map() ret["offset"] = data.(*ddl).Offset ret["total_rows"] = data.(*ddl).TotalRows rows := data.(*ddl).Rows ret["rows"] = util.MapList(len(rows)) // append docs for i, row := range rows { ret["rows"].([]map[string]interface{})[i] = map[string]interface{}{ "id": row.Id, "key": row.Key, "value": map[string]string{"rev": row.Value["rev"].(string)}, "doc": row.Doc, } } return ret, nil } if keys == nil { return _func( // get all this.Client.Get(this.Name+"/_all_docs", query, nil).GetBodyData(&ddl{})) } else { body := util.ParamList("keys", keys) return _func( // get all only matched keys this.Client.Post(this.Name+"/_all_docs", query, body, nil).GetBodyData(&ddl{})) } }
// Info. // // @return map[string]interface{}, error func (this *Server) Info() (map[string]interface{}, error) { data, err := this.Client.Get("/", nil, nil).GetBodyData(nil) if err != nil { return nil, err } ret := util.Map() for key, value := range data.(map[string]interface{}) { switch value := value.(type) { case map[string]interface{}: ret[key] = util.MapString() for kkey, vvalue := range value { ret[key].(map[string]string)[kkey] = vvalue.(string) } default: ret[key] = value } } return ret, nil }