#include "stdafx.h" #include #include #include #include namespace mssql { BoundDatumSet::BoundDatumSet() : err(nullptr), first_error(0), _output_param_count(-1), _params(nullptr) { _bindings = make_shared(); } BoundDatumSet::BoundDatumSet(shared_ptr params) : BoundDatumSet() { _params = params; } bool BoundDatumSet::reserve(const shared_ptr& set, const size_t row_count) const { for (uint32_t i = 0; i < set->get_column_count(); ++i) { const auto binding = make_shared(_params); auto& def = set->get_meta_data(i); const size_t size = def.columnSize; size_t new_size = size; binding->reserve_column_type(def.dataType, new_size, row_count); if (size != new_size) { def.columnSize = new_size; } _bindings->push_back(binding); } return true; } Local get(const Local o, const char* v) { const auto vp = Nan::New(v).ToLocalChecked(); const auto val = Nan::Get(o, vp).ToLocalChecked(); return val; } int get_tvp_col_count(const Local& v) { const auto tvp_columns = Nan::Get(Nan::To(v).ToLocalChecked(), Nan::New("table_value_param").ToLocalChecked()).ToLocalChecked(); const auto cols = tvp_columns.As(); const auto count = cols->Length(); return count; } bool BoundDatumSet::tvp(Local& v) const { const auto tvp_columns = Nan::Get(Nan::To(v).ToLocalChecked(), Nan::New("table_value_param").ToLocalChecked()).ToLocalChecked(); if (tvp_columns->IsNull()) return false; if (!tvp_columns->IsArray()) return false; const auto cols = tvp_columns.As(); const auto count = cols->Length(); for (uint32_t i = 0; i < count; ++i) { const auto binding = make_shared(); auto p = Nan::Get(Nan::To(tvp_columns).ToLocalChecked(), i).ToLocalChecked(); const auto res = binding->bind(p); if (!res) break; _bindings->push_back(binding); } return true; } bool BoundDatumSet::bind(Local& node_params) { const auto count = node_params->Length(); auto res = true; _output_param_count = 0; if (count > 0) { for (uint32_t i = 0; i < count; ++i) { const auto binding = make_shared(); auto v = Nan::Get(node_params, i).ToLocalChecked(); res = binding->bind(v); switch (binding->param_type) { case SQL_PARAM_OUTPUT: case SQL_PARAM_INPUT_OUTPUT: _output_param_count++; break; default: break; } if (!res) { err = binding->getErr(); first_error = i; break; } _bindings->push_back(binding); if (binding->is_tvp) { const auto col_count = get_tvp_col_count(v); binding->tvp_no_cols = col_count; res = tvp(v); } } } return res; } Local BoundDatumSet::unbind() const { const nodeTypeFactory fact; const auto arr = fact.new_array(_output_param_count); auto i = 0; std::for_each(_bindings->begin(), _bindings->end(), [&](const shared_ptr & param) mutable { switch (param->param_type) { case SQL_PARAM_OUTPUT: case SQL_PARAM_INPUT_OUTPUT: { const auto v = param->unbind(); Nan::Set(arr, i++, v); } break; default: break; } }); return arr; } }