// the parameter is of type PAction to hide the real (and private) subclass from the public interface. void PWrapper::finalizeSchema(PAction *action) { if (d->m_schema != NULL) { // delete the old schema delete d->m_schema; } // retrieve and set the schema PAttemptSchema *attemptSchema = static_cast<PAttemptSchema *>(action); d->m_schema = attemptSchema->schema(); // set the root element accordingly if (d->m_rootElement != NULL) { d->m_rootElement->deleteLater(); } // the parent of the root element is the root element of the parent wrapper, // or NULL if this is the top level wrapper. PWrapperElement *parentElement = (parentWrapper() != NULL) ? parentWrapper()->rootElement() : NULL; d->m_rootElement = new PWrapperElement(this, parentElement, *(d->m_schema)); }
void DBQueryInfo::resolve(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolvedp) { *resolvedp = false; IdWrapper wid(cx, id); // We only use this for index access if (!wid.isInt()) { return; } JS::RootedObject parent(cx); if (!JS_GetPrototype(cx, obj, &parent)) uasserted(ErrorCodes::InternalError, "Couldn't get prototype"); ObjectWrapper parentWrapper(cx, parent); JS::RootedValue arrayAccess(cx); parentWrapper.getValue(InternedString::arrayAccess, &arrayAccess); if (arrayAccess.isObject() && JS_ObjectIsFunction(cx, arrayAccess.toObjectOrNull())) { JS::AutoValueArray<1> args(cx); args[0].setInt32(wid.toInt32()); JS::RootedValue vp(cx); ObjectWrapper(cx, obj).callMethod(arrayAccess, args, &vp); if (!vp.isNullOrUndefined()) { ObjectWrapper o(cx, obj); // Assumes the user won't modify the contents of what DBQuery::arrayAccess returns // otherwise we need to install a getter. o.defineProperty(id, vp, 0); } *resolvedp = true; } }
void DBInfo::getProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { // 2nd look into real values, may be cached collection object if (!vp.isUndefined()) { auto scope = getScope(cx); auto opContext = scope->getOpContext(); if (opContext && vp.isObject()) { ObjectWrapper o(cx, vp); if (o.hasOwnField(InternedString::_fullName)) { // need to check every time that the collection did not get sharded if (haveLocalShardingInfo(opContext, o.getString(InternedString::_fullName))) uasserted(ErrorCodes::BadValue, "can't use sharded collection from db.eval"); } } return; } JS::RootedObject parent(cx); if (!JS_GetPrototype(cx, obj, &parent)) uasserted(ErrorCodes::JSInterpreterFailure, "Couldn't get prototype"); ObjectWrapper parentWrapper(cx, parent); if (parentWrapper.hasOwnField(id)) { parentWrapper.getValue(id, vp); return; } IdWrapper idw(cx, id); // if starts with '_' we dont return collection, one must use getCollection() if (idw.isString()) { JSStringWrapper jsstr; auto sname = idw.toStringData(&jsstr); if (sname.size() == 0 || sname[0] == '_') { return; } } // no hit, create new collection JS::RootedValue getCollection(cx); parentWrapper.getValue(InternedString::getCollection, &getCollection); if (!(getCollection.isObject() && JS_ObjectIsFunction(cx, getCollection.toObjectOrNull()))) { uasserted(ErrorCodes::BadValue, "getCollection is not a function"); } JS::AutoValueArray<1> args(cx); idw.toValue(args[0]); JS::RootedValue coll(cx); ObjectWrapper(cx, obj).callMethod(getCollection, args, &coll); uassert(16861, "getCollection returned something other than a collection", getScope(cx)->getProto<DBCollectionInfo>().instanceOf(coll)); // cache collection for reuse, don't enumerate ObjectWrapper(cx, obj).defineProperty(id, coll, 0); vp.set(coll); }