func installViews(bucket base.Bucket) error { // View for finding every Couchbase doc (used when deleting a database) // Key is docid; value is null allbits_map := `function (doc, meta) { emit(meta.id, null); }` // View for _all_docs // Key is docid; value is [revid, sequence] alldocs_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; if ((sync.flags & 1) || sync.deleted) return; var channels = sync.channels; var channelNames = []; for (ch in channels) { if (channels[ch] == null) channelNames.push(ch); } emit(meta.id, {r:sync.rev, s:sync.sequence, c:channelNames}); }` // View for importing unknown docs // Key is [existing?, docid] where 'existing?' is false for unknown docs import_map := `function (doc, meta) { if(meta.id.substring(0,6) != "_sync:") { var exists = (doc["_sync"] !== undefined); emit([exists, meta.id], null); } }` // View for compaction -- finds all revision docs // Key and value are ignored. oldrevs_map := `function (doc, meta) { var sync = doc._sync; if (meta.id.substring(0,10) == "_sync:rev:") emit("",null); }` // All-principals view // Key is name; value is true for user, false for role principals_map := `function (doc, meta) { var prefix = meta.id.substring(0,11); var isUser = (prefix == %q); if (isUser || prefix == %q) emit(meta.id.substring(%d), isUser); }` principals_map = fmt.Sprintf(principals_map, auth.UserKeyPrefix, auth.RoleKeyPrefix, len(auth.UserKeyPrefix)) // By-channels view. // Key is [channelname, sequence]; value is [docid, revid, flag?] // where flag is true for doc deletion, false for removed from channel, missing otherwise channels_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var sequence = sync.sequence; if (sequence === undefined) return; var value = {rev:sync.rev}; if (sync.flags) { value.flags = sync.flags } else if (sync.deleted) { value.flags = %d // channels.Deleted } if (%v) // EnableStarChannelLog emit(["*", sequence], value); var channels = sync.channels; if (channels) { for (var name in channels) { removed = channels[name]; if (!removed) emit([name, sequence], value); else { var flags = removed.del ? %d : %d; // channels.Removed/Deleted emit([name, removed.seq], {rev:removed.rev, flags: flags}); } } } }` channels_map = fmt.Sprintf(channels_map, channels.Deleted, EnableStarChannelLog, channels.Removed|channels.Deleted, channels.Removed) // Channel access view, used by ComputeChannelsForPrincipal() // Key is username; value is dictionary channelName->firstSequence (compatible with TimedSet) access_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var access = sync.access; if (access) { for (var name in access) { emit(name, access[name]); } } }` // Role access view, used by ComputeRolesForUser() // Key is username; value is array of role names roleAccess_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var access = sync.role_access; if (access) { for (var name in access) { emit(name, access[name]); } } }` ddoc := walrus.DesignDoc{ Views: walrus.ViewMap{ "principals": walrus.ViewDef{Map: principals_map}, "channels": walrus.ViewDef{Map: channels_map}, "access": walrus.ViewDef{Map: access_map}, "role_access": walrus.ViewDef{Map: roleAccess_map}, }, } err := bucket.PutDDoc("sync_gateway", ddoc) if err != nil { base.Warn("Error installing Couchbase design doc: %v", err) } ddoc = walrus.DesignDoc{ Views: walrus.ViewMap{ "all_bits": walrus.ViewDef{Map: allbits_map}, "all_docs": walrus.ViewDef{Map: alldocs_map, Reduce: "_count"}, "import": walrus.ViewDef{Map: import_map, Reduce: "_count"}, "old_revs": walrus.ViewDef{Map: oldrevs_map, Reduce: "_count"}, }, } err = bucket.PutDDoc("sync_housekeeping", ddoc) if err != nil { base.Warn("Error installing Couchbase design doc: %v", err) } return err }
func installViews(bucket base.Bucket) error { // View for finding every Couchbase doc (used when deleting a database) // Key is docid; value is null allbits_map := `function (doc, meta) { emit(meta.id, null); }` // View for _all_docs // Key is docid; value is revid alldocs_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; if (sync.deleted) return; emit(meta.id, sync.rev); }` // View for compaction -- finds all revision docs // Key and value are ignored. oldrevs_map := `function (doc, meta) { var sync = doc._sync; if (meta.id.substring(0,10) == "_sync:rev:") emit("",null); }` // All-principals view // Key is name; value is true for user, false for role principals_map := `function (doc, meta) { var prefix = meta.id.substring(0,11); var isUser = (prefix == %q); if (isUser || prefix == %q) emit(meta.id.substring(%d), isUser); }` principals_map = fmt.Sprintf(principals_map, auth.UserKeyPrefix, auth.RoleKeyPrefix, len(auth.UserKeyPrefix)) // By-channels view. // Key is [channelname, sequence]; value is [docid, revid, flag?] // where flag is true for doc deletion, false for removed from channel, missing otherwise channels_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var sequence = sync.sequence; if (sequence === undefined) return; var value = [meta.id, sync.rev]; if (sync.deleted) value.push(true); emit(["*", sequence], value); var channels = sync.channels; if (channels) { for (var name in channels) { removed = channels[name]; if (!removed) emit([name, sequence], value); else emit([name, removed.seq], [meta.id, removed.rev, !!removed.del, true]); } } }` // Channel access view, used by ComputeChannelsForPrincipal() // Key is username; value is dictionary channelName->firstSequence (compatible with TimedSet) access_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var sequence = sync.sequence; if (sync.deleted || sequence === undefined) return; var access = sync.access; if (access) { for (var name in access) { emit(name, access[name]); } } }` // Role access view, used by ComputeRolesForUser() // Key is username; value is array of role names roleAccess_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var sequence = sync.sequence; if (sync.deleted || sequence === undefined) return; var access = sync.role_access; if (access) { for (var name in access) { emit(name, access[name]); } } }` ddoc := walrus.DesignDoc{ Views: walrus.ViewMap{ "principals": walrus.ViewDef{Map: principals_map}, "channels": walrus.ViewDef{Map: channels_map}, "access": walrus.ViewDef{Map: access_map}, "role_access": walrus.ViewDef{Map: roleAccess_map}, }, } err := bucket.PutDDoc("sync_gateway", ddoc) if err != nil { base.Warn("Error installing Couchbase design doc: %v", err) } ddoc = walrus.DesignDoc{ Views: walrus.ViewMap{ "all_bits": walrus.ViewDef{Map: allbits_map}, "all_docs": walrus.ViewDef{Map: alldocs_map, Reduce: "_count"}, "old_revs": walrus.ViewDef{Map: oldrevs_map, Reduce: "_count"}, }, } err = bucket.PutDDoc("sync_housekeeping", ddoc) if err != nil { base.Warn("Error installing Couchbase design doc: %v", err) } return err }
func installViews(bucket base.Bucket) error { // View for finding every Couchbase doc (used when deleting a database) // Key is docid; value is null allbits_map := `function (doc, meta) { emit(meta.id, null); }` // View for _all_docs // Key is docid; value is revid alldocs_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; if (sync.deleted) return; emit(meta.id, sync.rev); }` // By-channels view. // Key is [channelname, sequence]; value is [docid, revid, flag?] // where flag is true for doc deletion, false for removed from channel, missing otherwise channels_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var sequence = sync.sequence; if (sequence === undefined) return; var value = [meta.id, sync.rev]; if (sync.deleted) value.push(true); emit(["*", sequence], value); var channels = sync.channels; if (channels) { for (var name in channels) { removed = channels[name]; if (!removed) emit([name, sequence], value); else emit([name, removed.seq], [meta.id, removed.rev, false]); } } }` // Channel access view, used by ComputeChannelsForPrincipal() // Key is username; value is dictionary channelName->firstSequence access_map := `function (doc, meta) { var sync = doc._sync; if (sync === undefined || meta.id.substring(0,6) == "_sync:") return; var sequence = sync.sequence; if (sync.deleted || sequence === undefined) return; var access = sync.access; if (access) { for (var name in access) { emit(name, access[name]); } } }` ddoc := walrus.DesignDoc{ Views: walrus.ViewMap{ "all_bits": walrus.ViewDef{Map: allbits_map}, "all_docs": walrus.ViewDef{Map: alldocs_map, Reduce: "_count"}, "channels": walrus.ViewDef{Map: channels_map}, "access": walrus.ViewDef{Map: access_map}, }, } err := bucket.PutDDoc("sync_gateway", ddoc) if err != nil { base.Warn("Error installing Couchbase design doc: %v", err) } return err }