コード例 #1
0
ファイル: qm_nodejs_streamaggr.cpp プロジェクト: Zala/qminer
PJsonVal TNodeJsStreamAggr::SaveJson(const int& Limit) const {
	if (!SaveJsonFun.IsEmpty()) {
		v8::Isolate* Isolate = v8::Isolate::GetCurrent();
		v8::HandleScope HandleScope(Isolate);

		v8::Local<v8::Function> Callback = v8::Local<v8::Function>::New(Isolate, SaveJsonFun);
		v8::Local<v8::Object> GlobalContext = Isolate->GetCurrentContext()->Global();
		const unsigned Argc = 1;
		v8::Local<v8::Value> ArgV[Argc] = { v8::Number::New(Isolate, Limit) };
		v8::TryCatch TryCatch;
		v8::Local<v8::Value> ReturnVal = Callback->Call(GlobalContext, Argc, ArgV);
		if (TryCatch.HasCaught()) {
			TryCatch.ReThrow();	
			return TJsonVal::NewObj();
		}
		QmAssertR(ReturnVal->IsObject(), "Stream aggr JS callback: saveJson didn't return an object.");
		PJsonVal Res = TNodeJsUtil::GetObjJson(ReturnVal->ToObject());

		QmAssertR(Res->IsDef(), "Stream aggr JS callback: saveJson didn't return a valid JSON.");
		return Res;
	}
	else {
		return TJsonVal::NewObj();
	}
}
コード例 #2
0
ファイル: nodeutil.cpp プロジェクト: amrsobhy/qminer
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");
    }
}
コード例 #3
0
ファイル: qm_nodejs_streamaggr.cpp プロジェクト: Zala/qminer
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;
		}
	}
}