// extend/update the object with values from Val // this and Val should be an Object and not an array or something else void TJsonVal::MergeObj(const PJsonVal& Val) { EAssert(Val->IsObj() && IsObj()); for (int N = 0; N < Val->GetObjKeys(); N++) { const TStr Key = Val->GetObjKey(N); AddToObj(Key, Val->GetObjKey(Key)); } }
void TJsonVal::AddToObj(const PJsonVal& Val) { EAssert(Val->IsObj()); int KeyId = Val->KeyValH.FFirstKeyId(); while (Val->KeyValH.FNextKeyId(KeyId)) { AddToObj(Val->KeyValH.GetKey(KeyId), Val->KeyValH[KeyId]); } }
PStemmer TStemmer::ParseJson(const PJsonVal& StemmerVal, const bool& RealWordP) { if (StemmerVal->IsBool()) { return TStemmer::New(StemmerVal->GetBool() ? stmtPorter : stmtNone, RealWordP); } else if (StemmerVal->IsObj()) { TStr StemmerType = StemmerVal->GetObjStr("type", "none"); const bool RealWordP = StemmerVal->GetObjBool("realWord", RealWordP); return TStemmer::New((StemmerType == "porter") ? stmtPorter : stmtNone, RealWordP); } throw TExcept::New("Unknown stemmer definiton " + StemmerVal->SaveStr()); }
void TFolderBackup::ParseSettings(const PJsonVal& SettingsJson) { // name of the file that holds all backups DestinationDirNm = SettingsJson->GetObjStr("destination"); // load profiles for which we wish to make backups PJsonVal ProfilesJson = SettingsJson->GetObjKey("profiles"); if (!ProfilesJson->IsObj()) { TNotify::StdNotify->OnStatus("'profiles' object is not an object"); return; } for (int N = 0; N < ProfilesJson->GetObjKeys(); N++) { const TStr ProfileName = ProfilesJson->GetObjKey(N); ProfileH.AddDat(ProfileName, TBackupProfile(ProfilesJson->GetObjKey(ProfileName), DestinationDirNm, ProfileName)); } }
v8::Local<v8::Value> TNodeJsUtil::ParseJson(v8::Isolate* Isolate, const PJsonVal& JsonVal) { v8::EscapableHandleScope HandleScope(Isolate); if (!JsonVal->IsDef()) { return v8::Undefined(Isolate); } else if (JsonVal->IsBool()) { return v8::Boolean::New(Isolate, JsonVal->GetBool()); } else if (JsonVal->IsNull()) { return v8::Null(Isolate); } else if (JsonVal->IsNum()) { return HandleScope.Escape(v8::Number::New(Isolate, JsonVal->GetNum())); } else if (JsonVal->IsStr()) { return HandleScope.Escape(v8::String::NewFromUtf8(Isolate, JsonVal->GetStr().CStr())); } else if (JsonVal->IsArr()) { const uint Len = JsonVal->GetArrVals(); v8::Local<v8::Array> ResArr = v8::Array::New(Isolate, Len); for (uint i = 0; i < Len; i++) { ResArr->Set(i, ParseJson(Isolate, JsonVal->GetArrVal(i))); } return HandleScope.Escape(ResArr); } else if (JsonVal->IsObj()) { v8::Local<v8::Object> ResObj = v8::Object::New(Isolate); const int NKeys = JsonVal->GetObjKeys(); for (int i = 0; i < NKeys; i++) { TStr Key; PJsonVal Val; JsonVal->GetObjKeyVal(i, Key, Val); ResObj->Set(v8::String::NewFromUtf8(Isolate, Key.CStr()), ParseJson(Isolate, Val)); } return HandleScope.Escape(ResObj); } else { throw TExcept::New("Invalid JSON!", "TNodeJsUtil::ParseJson"); } }
// parse from json configuration file TJsParam(const TStr& RootFNm, const PJsonVal& JsVal) { EAssertR(JsVal->IsObj(), "Unsupported type: " + TJsonVal::GetStrFromVal(JsVal)); // we must have at least the script name EAssert(JsVal->IsObjKey("file")); // get script name FNm = JsVal->GetObjStr("file"); // get namespace (get from script name if not available) Nm = JsVal->IsObjKey("name") ? JsVal->GetObjStr("name") : FNm.GetFMid(); // get initialization parameters (if available) InitVal = JsVal->IsObjKey("init") ? JsVal->GetObjKey("init") : TJsonVal::NewObj(); // get library include folders if (JsVal->IsObjKey("include")) { PJsonVal IncludesVal = JsVal->GetObjKey("include"); EAssertR(IncludesVal->IsArr(), "Expected array of strings, not: " + TJsonVal::GetStrFromVal(IncludesVal)); for (int IncludeN = 0; IncludeN < IncludesVal->GetArrVals(); IncludeN++) { PJsonVal IncludeVal = IncludesVal->GetArrVal(IncludeN); EAssertR(IncludeVal->IsStr(), "Expected string, not: " + TJsonVal::GetStrFromVal(IncludeVal)); IncludeFPathV.Add(IncludeVal->GetStr()); } } // handle default includes AddLocalLibFPath(); AddQMinerLibFPath(); // get folders with access permissions if (JsVal->IsObjKey("dirs")) { PJsonVal DirsVal = JsVal->GetObjKey("dirs"); EAssertR(DirsVal->IsArr(), "Expected array of strings, not: " + TJsonVal::GetStrFromVal(DirsVal)); for (int DirN = 0; DirN < DirsVal->GetArrVals(); DirN++) { PJsonVal DirVal = DirsVal->GetArrVal(DirN); EAssertR(DirVal->IsStr(), "Expected string, not: " + TJsonVal::GetStrFromVal(DirVal)); AccessFPathV.Add(DirVal->GetStr()); } } // add sandbox access AddSandboxAccessFPath(RootFNm); }
void TNodeJsSA::New(const v8::FunctionCallbackInfo<v8::Value>& Args) { v8::Isolate* Isolate = v8::Isolate::GetCurrent(); v8::HandleScope HandleScope(Isolate); if (Args.Length() == 0) { return; } // EAssertR(!constructor.IsEmpty(), "TNodeJsSA::New: constructor is empty. Did you call TNodeJsSA::Init(exports); in this module's init function?"); QmAssertR(Args.Length() <= 3 && Args.Length() >= 2, "stream aggregator constructor expects at least two parameters"); QmAssertR(Args[0]->IsObject() && Args[1]->IsObject(), "stream aggregator constructor expects first two arguments as objects"); // new sa(...) if (Args.IsConstructCall()) { TQm::PStreamAggr StreamAggr; TNodeJsBase* JsBase = TNodeJsUtil::UnwrapCheckWatcher<TNodeJsBase>(Args[0]->ToObject()); // get aggregate type TStr TypeNm = TNodeJsUtil::GetArgStr(Args, 1, "type", "javaScript"); if (TypeNm == "javaScript") { // we have a javascript stream aggregate TStr AggrName = TNodeJsUtil::GetArgStr(Args, 1, "name", ""); // we need a name, if not give just generate one if (AggrName.Empty()) { AggrName = TGuid::GenSafeGuid(); } // create aggregate StreamAggr = TNodeJsStreamAggr::New(JsBase->Base, AggrName, Args[1]->ToObject()); } else if (TypeNm == "ftrext") { TStr AggrName = TNodeJsUtil::GetArgStr(Args, 1, "name", ""); QmAssertR(Args[1]->ToObject()->Has(v8::String::NewFromUtf8(Isolate, "featureSpace")), "addStreamAggr: featureSpace property missing!"); // we need a name, if not give just generate one if (AggrName.Empty()) { AggrName = TGuid::GenSafeGuid(); } throw TQm::TQmExcept::New("ftrext stream aggr not implemented yet! (needs feature space implementation)"); // TODO //TQm::PFtrSpace FtrSpace = TJsFtrSpace::GetArgFtrSpace(Args[1]->ToObject()->Get(v8::String::NewFromUtf8(Isolate, "featureSpace"))); //StreamAggr = TStreamAggrs::TFtrExtAggr::New(JsBase->Base, AggrName, FtrSpace); } else if (TypeNm == "stmerger") { // create new aggregate PJsonVal ParamVal = TNodeJsUtil::GetArgJson(Args, 1); StreamAggr = TQm::TStreamAggr::New(JsBase->Base, TypeNm, ParamVal); PJsonVal FieldArrVal = ParamVal->GetObjKey("fields"); TStrV InterpNmV; QmAssertR(ParamVal->IsObjKey("fields"), "Missing argument 'fields'!"); // automatically register the aggregate for addRec callbacks for (int FieldN = 0; FieldN < FieldArrVal->GetArrVals(); FieldN++) { PJsonVal FieldVal = FieldArrVal->GetArrVal(FieldN); PJsonVal SourceVal = FieldVal->GetObjKey("source"); TStr StoreNm = ""; if (SourceVal->IsStr()) { // we have just store name StoreNm = SourceVal->GetStr(); } else if (SourceVal->IsObj()) { // get store StoreNm = SourceVal->GetObjStr("store"); } JsBase->Base->AddStreamAggr(JsBase->Base->GetStoreByStoreNm(StoreNm)->GetStoreId(), StreamAggr); } } else { // we have a GLib stream aggregate, translate parameters to PJsonVal PJsonVal ParamVal = TNodeJsUtil::GetArgJson(Args, 1); if (Args.Length() >= 3 && Args[2]->IsString()) { ParamVal->AddToObj("store", TNodeJsUtil::GetArgStr(Args, 2)); } // check if it's one stream aggregate or composition if (TQm::TStreamAggrs::TCompositional::IsCompositional(TypeNm)) { // we have a composition of aggregates, call code to assemble it TQm::TStreamAggrs::TCompositional::Register(JsBase->Base, TypeNm, ParamVal); } else { // create new aggregate StreamAggr = TQm::TStreamAggr::New(JsBase->Base, TypeNm, ParamVal); } } if (!TQm::TStreamAggrs::TCompositional::IsCompositional(TypeNm)) { if (Args.Length() > 2) { TStrV Stores(0); if (Args[2]->IsString()) { Stores.Add(TNodeJsUtil::GetArgStr(Args, 2)); } if (Args[2]->IsArray()) { PJsonVal StoresJson = TNodeJsUtil::GetArgJson(Args, 2); QmAssertR(StoresJson->IsDef(), "stream aggr constructor : Args[2] should be a string (store name) or a string array (store names)"); StoresJson->GetArrStrV(Stores); } for (int StoreN = 0; StoreN < Stores.Len(); StoreN++) { QmAssertR(JsBase->Base->IsStoreNm(Stores[StoreN]), "stream aggr constructor : Args[2] : store does not exist!"); JsBase->Base->AddStreamAggr(Stores[StoreN], StreamAggr); } } else { JsBase->Base->AddStreamAggr(StreamAggr); } // non-compositional aggregates are returned TNodeJsSA* JsSA = new TNodeJsSA(StreamAggr); v8::Local<v8::Object> Instance = Args.This(); JsSA->Wrap(Instance); Args.GetReturnValue().Set(Instance); return; } } // sa(...) -> calls new sa(...) else { if (Args.Length() == 2) { const int Argc = 2; v8::Local<v8::Value> Argv[Argc] = { Args[0], Args[1] }; v8::Local<v8::Function> cons = v8::Local<v8::Function>::New(Isolate, constructor); v8::Local<v8::Object> Instance = cons->NewInstance(Argc, Argv); Args.GetReturnValue().Set(Instance); return; } if (Args.Length() == 3) { const int Argc = 3; v8::Local<v8::Value> Argv[Argc] = { Args[0], Args[1], Args[2] }; v8::Local<v8::Function> cons = v8::Local<v8::Function>::New(Isolate, constructor); v8::Local<v8::Object> Instance = cons->NewInstance(Argc, Argv); Args.GetReturnValue().Set(Instance); return; } else { // sa()->calls new sa() v8::Local<v8::Function> cons = v8::Local<v8::Function>::New(Isolate, constructor); v8::Local<v8::Object> Instance = cons->NewInstance(); Args.GetReturnValue().Set(Instance); return; } } }
TQmParam(const TStr& FNm) { EAssertR(TFile::Exists(FNm), "Missing configuration file " + FNm); // load configuration file PJsonVal ConfigVal = TJsonVal::GetValFromSIn(TFIn::New(FNm)); EAssertR(ConfigVal->IsObj(), "Invalid setting file - not valid JSON"); // parse out common stuff RootFPath = TStr::GetNrFPath(ConfigVal->GetObjStr("directory", TDir::GetCurDir())); LockFNm = RootFPath + "./lock"; DbFPath = ConfigVal->GetObjStr("database", "./db/"); PortN = TFlt::Round(ConfigVal->GetObjNum("port")); // parse out unicode definition file TStr UnicodeFNm = ConfigVal->GetObjStr("unicode", TQm::TEnv::QMinerFPath + "./UnicodeDef.Bin"); if (!TUnicodeDef::IsDef()) { TUnicodeDef::Load(UnicodeFNm); } // parse cache if (ConfigVal->IsObjKey("cache")) { PJsonVal CacheVal = ConfigVal->GetObjKey("cache"); // parse out index and default store cache sizes IndexCacheSize = int64(CacheVal->GetObjNum("index", 1024)) * int64(TInt::Mega); DefStoreCacheSize = int64(CacheVal->GetObjNum("store", 1024)) * int64(TInt::Mega); // prase out store specific sizes, when available if (CacheVal->IsObjKey("stores")) { PJsonVal StoreCacheVals = CacheVal->GetObjKey("stores"); for (int StoreN = 0; StoreN < StoreCacheVals->GetArrVals(); StoreN++) { PJsonVal StoreCacheVal = StoreCacheVals->GetArrVal(StoreN); TStr StoreName = StoreCacheVal->GetObjStr("name"); uint64 StoreCacheSize = int64(StoreCacheVal->GetObjNum("size")) * int64(TInt::Mega); StoreNmCacheSizeH.AddDat(StoreName, StoreCacheSize); } } } else { // default sizes are set to 1GB for index and stores IndexCacheSize = int64(1024) * int64(TInt::Mega); DefStoreCacheSize = int64(1024) * int64(TInt::Mega); } // load scripts if (ConfigVal->IsObjKey("script")) { // we have configuration file, read it PJsonVal JsVals = ConfigVal->GetObjKey("script"); if (JsVals->IsArr()) { for (int JsValN = 0; JsValN < JsVals->GetArrVals(); JsValN++) { JsParamV.Add(TJsParam(RootFPath, JsVals->GetArrVal(JsValN))); } } else { JsParamV.Add(TJsParam(RootFPath, JsVals)); } } else { // no settings for scripts, assume default setting TStr SrcFPath = TStr::GetNrAbsFPath("src", RootFPath); TFFile File(SrcFPath, ".js", false); TStr SrcFNm; while (File.Next(SrcFNm)) { JsParamV.Add(TJsParam(RootFPath, SrcFNm)); } } // load serving folders //TODO: Add to qm config ability to edit this if (ConfigVal->IsObjKey("wwwroot")) { PJsonVal WwwVals = ConfigVal->GetObjKey("wwwroot"); if (WwwVals->IsArr()) { for (int WwwValN = 0; WwwValN < WwwVals->GetArrVals(); WwwValN++) { AddWwwRoot(WwwVals->GetArrVal(WwwValN)); } } else { AddWwwRoot(WwwVals); } } // check for folder with admin GUI TStr GuiFPath = TStr::GetNrAbsFPath("gui", TQm::TEnv::QMinerFPath); if (TDir::Exists(GuiFPath)) { WwwRootV.Add(TStrPr("admin", GuiFPath)); } // check for any default wwwroot TStr DefaultWwwRootFPath = TStr::GetNrAbsFPath("www", RootFPath); if (TDir::Exists(DefaultWwwRootFPath)) { WwwRootV.Add(TStrPr("www", DefaultWwwRootFPath)); } }