#ifndef __HCM4A_CalcFS4A_sqMask_h_
#define __HCM4A_CalcFS4A_sqMask_h_

#include "sqLite.h"


struct MaskGroupRec :Moveable<MaskGroupRec>{
	int mg_id;
	String mg_name;
	void Clear(){
		mg_id = 0;
		mg_name = "";
	}
	void Jsonize(JsonIO& json){
		json
		("Mg_id", mg_id)
		("Mg_name", mg_name)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Mg_id: " <<  mg_id << "\n"
			<< "	Mg_name: " <<  mg_name << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	mg_id = value;
				continue;
			}
			if(i==1){
				mg_name = vhcm[i];
			}
		}
	}
	void Set(const MaskGroupRec& rec){
		Clear();
		mg_id = rec.mg_id;
		mg_name = rec.mg_name;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return mg_name == "";
	}
	MaskGroupRec(){Clear();};
	MaskGroupRec(const String& jstr){Clear();FromJsonStr(jstr);};
	MaskGroupRec(
		const int mg_id,
		const String& mg_name
	):
		mg_id(mg_id),
		mg_name(mg_name)
	{}
	MaskGroupRec(const MaskGroupRec& rec):
		mg_id(rec.mg_id),
		mg_name(rec.mg_name)
	{}
};

struct MaskGroupData :Moveable<MaskGroupData>{
	MaskGroupRec Get(Sqlite3Session& qSes, const int mg_id);
	MaskGroupRec Get(Sqlite3Session& qSes, const String& mg_name);
	Vector<MaskGroupRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<MaskGroupRec>& list);
	bool Ins(Sqlite3Session& qSes, const MaskGroupRec& rec);
	bool Upd(Sqlite3Session& qSes, const MaskGroupRec& rec);
	bool Del(Sqlite3Session& qSes, const int mg_id);
	MaskGroupData(){}
};
MaskGroupRec MaskGroupData::Get(Sqlite3Session& qSes, const int mg_id){
	MaskGroupRec maskgroupRec;
	if(!qSes.IsOpen()) return maskgroupRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MG_ID,
		MG_NAME
	).From(MASKGROUP).Where(MG_ID == mg_id);
	if(sql.Fetch()){
		maskgroupRec.mg_id = sql[MG_ID];
		maskgroupRec.mg_name = sql[MG_NAME];
	}
	return maskgroupRec;
}
MaskGroupRec MaskGroupData::Get(Sqlite3Session& qSes, const String& mg_name){
	MaskGroupRec maskgroupRec;	if(!qSes.IsOpen()) return maskgroupRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MG_ID,
		MG_NAME
	).From(MASKGROUP).Where(MG_NAME == mg_name);
	if(sql.Fetch()){
		maskgroupRec.mg_id = sql[MG_ID];
		maskgroupRec.mg_name = sql[MG_NAME];
	}
	return maskgroupRec;
}
Vector<MaskGroupRec> MaskGroupData::Get(Sqlite3Session& qSes){
	Vector<MaskGroupRec> maskgroupList;	if(!qSes.IsOpen()) return maskgroupList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MG_ID,
		MG_NAME
	).From(MASKGROUP);
	while(sql.Fetch()){
	MaskGroupRec& maskgroupRec = maskgroupList.Add();
		maskgroupRec.mg_id = sql[MG_ID];
		maskgroupRec.mg_name = sql[MG_NAME];
	}
	return maskgroupList;
}
int MaskGroupData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
			String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
				if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
				npp++;
				MaskGroupRec maskgroupRec; maskgroupRec.FromCSV(tmpS, isOldSource);
				if(!maskgroupRec.IsEmpty()) Ins(qSes, maskgroupRec);
			}
		}
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction MaskGroupData::FromCSV: " << e);
        return 0;
    }
	return npp;
}

int MaskGroupData::Fill(Sqlite3Session& qSes, Vector<MaskGroupRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MG_ID,
		MG_NAME
	).From(MASKGROUP);
	while(sql.Fetch()){
	MaskGroupRec& maskgroupRec = list.Add();
		maskgroupRec.mg_id = sql[MG_ID];
		maskgroupRec.mg_name = sql[MG_NAME];
	}
	return list.GetCount();
}
bool MaskGroupData::Ins(Sqlite3Session& qSes, const MaskGroupRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(MASKGROUP)
		(MG_ID, rec.mg_id)
		(MG_NAME, rec.mg_name)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", MASKGROUP.ToString(), e));
		return false;
	}
	return true;
}
bool MaskGroupData::Upd(Sqlite3Session& qSes, const MaskGroupRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(MASKGROUP)
		(MG_ID, rec.mg_id)
		(MG_NAME, rec.mg_name)
		.Where(MG_ID == rec.mg_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", MASKGROUP.ToString(), e));
		return false;
	}
	return true;
}
bool MaskGroupData::Del(Sqlite3Session& qSes, const int mg_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(MASKGROUP)
		.Where(MG_ID == mg_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", MASKGROUP.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct BandRec :Moveable<BandRec>{
	int bnd_id;
	String bnd_name;
	void Clear(){
		bnd_id = 0;
		bnd_name = "";
	}
	void Jsonize(JsonIO& json){
		json
		("Bnd_id", bnd_id)
		("Bnd_name", bnd_name)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Bnd_id: " <<  bnd_id << "\n"
			<< "	Bnd_name: " <<  bnd_name << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	bnd_id = value;
				continue;
			}
			if(i==1){
				bnd_name = vhcm[i];
			}
		}
	}
	void Set(const BandRec& rec){
		Clear();
		bnd_id = rec.bnd_id;
		bnd_name = rec.bnd_name;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return bnd_name == "";
	}
	BandRec(){Clear();};
	BandRec(const String& jstr){Clear();FromJsonStr(jstr);};
	BandRec(
		const int bnd_id,
		const String& bnd_name
	):
		bnd_id(bnd_id),
		bnd_name(bnd_name)
	{}
	BandRec(const BandRec& rec):
		bnd_id(rec.bnd_id),
		bnd_name(rec.bnd_name)
	{}
};

struct BandData :Moveable<BandData>{
	BandRec Get(Sqlite3Session& qSes, const int bnd_id);
	BandRec Get(Sqlite3Session& qSes, const String& bnd_name);
	Vector<BandRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<BandRec>& list);
	bool Ins(Sqlite3Session& qSes, const BandRec& rec);
	bool Upd(Sqlite3Session& qSes, const BandRec& rec);
	bool Del(Sqlite3Session& qSes, const int bnd_id);
	BandData(){}
};
BandRec BandData::Get(Sqlite3Session& qSes, const int bnd_id){
	BandRec bandRec;
	if(!qSes.IsOpen()) return bandRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BND_ID,
		BND_NAME
	).From(BAND).Where(BND_ID == bnd_id);
	if(sql.Fetch()){
		bandRec.bnd_id = sql[BND_ID];
		bandRec.bnd_name = sql[BND_NAME];
	}
	return bandRec;
}
BandRec BandData::Get(Sqlite3Session& qSes, const String& bnd_name){
	BandRec bandRec;	if(!qSes.IsOpen()) return bandRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BND_ID,
		BND_NAME
	).From(BAND).Where(BND_NAME == bnd_name);
	if(sql.Fetch()){
		bandRec.bnd_id = sql[BND_ID];
		bandRec.bnd_name = sql[BND_NAME];
	}
	return bandRec;
}
Vector<BandRec> BandData::Get(Sqlite3Session& qSes){
	Vector<BandRec> bandList;	if(!qSes.IsOpen()) return bandList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BND_ID,
		BND_NAME
	).From(BAND);
	while(sql.Fetch()){
	BandRec& bandRec = bandList.Add();
		bandRec.bnd_id = sql[BND_ID];
		bandRec.bnd_name = sql[BND_NAME];
	}
	return bandList;
}
int BandData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
			String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            npp++;
	            BandRec bandRec; bandRec.FromCSV(tmpS, isOldSource);
	            if(!bandRec.IsEmpty()) Ins(qSes, bandRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction BandData::FromCSV: " << e);
        return 0;
    }
	return npp;
}

int BandData::Fill(Sqlite3Session& qSes, Vector<BandRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BND_ID,
		BND_NAME
	).From(BAND);
	while(sql.Fetch()){
	BandRec& bandRec = list.Add();
		bandRec.bnd_id = sql[BND_ID];
		bandRec.bnd_name = sql[BND_NAME];
	}
	return list.GetCount();
}

bool BandData::Ins(Sqlite3Session& qSes, const BandRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(BAND)
		(BND_ID, rec.bnd_id)
		(BND_NAME, rec.bnd_name)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", BAND.ToString(), e));
		return false;
	}
	return true;
}
bool BandData::Upd(Sqlite3Session& qSes, const BandRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(BAND)
		(BND_ID, rec.bnd_id)
		(BND_NAME, rec.bnd_name)
		.Where(BND_ID == rec.bnd_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", BAND.ToString(), e));
		return false;
	}
	return true;
}
bool BandData::Del(Sqlite3Session& qSes, const int bnd_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(BAND)
		.Where(BND_ID == bnd_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", BAND.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct ChSpacingRec :Moveable<ChSpacingRec>{
	int csp_id;
	double csp_mhz;
	void Clear(){
		csp_id = 0;
		csp_mhz = 0.0;
	}
	void Jsonize(JsonIO& json){
		json
		("Csp_id", csp_id)
		("Csp_mhz", csp_mhz)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Csp_id: " <<  csp_id << "\n"
			<< "	Csp_mhz: " <<  csp_mhz << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	csp_id = value;
				// TODO: only for channel_spacing.txt
				if(isOldSource && csp_id == 0) csp_id = 1;
				continue;
			}
			if(i==1){
				value = StrDbl(vhcm[i]);
				if(IsNumber(value))	csp_mhz = value;
				continue;
			}
		}
	}
	void Set(const ChSpacingRec& rec){
		Clear();
		csp_id = rec.csp_id;
		csp_mhz = rec.csp_mhz;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return csp_mhz == 0.0;
	}
	ChSpacingRec(){Clear();};
	ChSpacingRec(const String& jstr){Clear();FromJsonStr(jstr);};
	ChSpacingRec(
		const int csp_id,
		const double csp_mhz
	):
		csp_id(csp_id),
		csp_mhz(csp_mhz)
	{}
	ChSpacingRec(const ChSpacingRec& rec):
		csp_id(rec.csp_id),
		csp_mhz(rec.csp_mhz)
	{}
};
struct ChSpacingData :Moveable<ChSpacingData>{
	ChSpacingRec Get(Sqlite3Session& qSes, const int csp_id);
	Vector<ChSpacingRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<ChSpacingRec>& list);
	bool Ins(Sqlite3Session& qSes, const ChSpacingRec& rec);
	bool Upd(Sqlite3Session& qSes, const ChSpacingRec& rec);
	bool Del(Sqlite3Session& qSes, const int csp_id);
	ChSpacingData(){}
};
ChSpacingRec ChSpacingData::Get(Sqlite3Session& qSes, const int csp_id){
	ChSpacingRec chspacingRec;
	if(!qSes.IsOpen()) return chspacingRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CSP_ID,
		CSP_MHZ
	).From(CHSPACING).Where(CSP_ID == csp_id);
	if(sql.Fetch()){
		chspacingRec.csp_id = sql[CSP_ID];
		chspacingRec.csp_mhz = sql[CSP_MHZ];
	}
	return chspacingRec;
}
Vector<ChSpacingRec> ChSpacingData::Get(Sqlite3Session& qSes){
	Vector<ChSpacingRec> chspacingList;	if(!qSes.IsOpen()) return chspacingList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CSP_ID,
		CSP_MHZ
	).From(CHSPACING);
	while(sql.Fetch()){
	ChSpacingRec& chspacingRec = chspacingList.Add();
		chspacingRec.csp_id = sql[CSP_ID];
		chspacingRec.csp_mhz = sql[CSP_MHZ];
	}
	return chspacingList;
}
int ChSpacingData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            npp++;
	            ChSpacingRec chspacingRec; chspacingRec.FromCSV(tmpS, isOldSource);
	            if(!chspacingRec.IsEmpty()) Ins(qSes, chspacingRec);
	        }
		}
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction ChSpacingData::FromCSV: " << e);
        return 0;
    }
	return npp;
}

int ChSpacingData::Fill(Sqlite3Session& qSes, Vector<ChSpacingRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CSP_ID,
		CSP_MHZ
	).From(CHSPACING);
	while(sql.Fetch()){
	ChSpacingRec& chspacingRec = list.Add();
		chspacingRec.csp_id = sql[CSP_ID];
		chspacingRec.csp_mhz = sql[CSP_MHZ];
	}
	return list.GetCount();
}
bool ChSpacingData::Ins(Sqlite3Session& qSes, const ChSpacingRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(CHSPACING)
		(CSP_ID, rec.csp_id)
		(CSP_MHZ, rec.csp_mhz)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", CHSPACING.ToString(), e));
		return false;
	}
	return true;
}
bool ChSpacingData::Upd(Sqlite3Session& qSes, const ChSpacingRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(CHSPACING)
		(CSP_ID, rec.csp_id)
		(CSP_MHZ, rec.csp_mhz)
		.Where(CSP_ID == rec.csp_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", CHSPACING.ToString(), e));
		return false;
	}
	return true;
}
bool ChSpacingData::Del(Sqlite3Session& qSes, const int csp_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(CHSPACING)
		.Where(CSP_ID == csp_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", CHSPACING.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct BitRateRec :Moveable<BitRateRec>{
	int btr_id;
	String btr_bitrare;
	void Clear(){
		btr_id = 0;
		btr_bitrare = "";
	}
	void Jsonize(JsonIO& json){
		json
		("Btr_id", btr_id)
		("Btr_bitrare", btr_bitrare)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Btr_id: " <<  btr_id << "\n"
			<< "	Btr_bitrare: " <<  btr_bitrare << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	btr_id = value;
				continue;
			}
			if(i==1){
				btr_bitrare = vhcm[i];
			}
		}
	}
	void Set(const BitRateRec& rec){
		Clear();
		btr_id = rec.btr_id;
		btr_bitrare = rec.btr_bitrare;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return btr_bitrare == "";
	}
	BitRateRec(){Clear();};
	BitRateRec(const String& jstr){Clear();FromJsonStr(jstr);};
	BitRateRec(
		const int btr_id,
		const String& btr_bitrare
	):
		btr_id(btr_id),
		btr_bitrare(btr_bitrare)
	{}
	BitRateRec(const BitRateRec& rec):
		btr_id(rec.btr_id),
		btr_bitrare(rec.btr_bitrare)
	{}
};
struct BitRateData :Moveable<BitRateData>{
	BitRateRec Get(Sqlite3Session& qSes, const int btr_id);
	Vector<BitRateRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<BitRateRec>& list);
	bool Ins(Sqlite3Session& qSes, const BitRateRec& rec);
	bool Upd(Sqlite3Session& qSes, const BitRateRec& rec);
	bool Del(Sqlite3Session& qSes, const int btr_id);
	BitRateData(){}
};
BitRateRec BitRateData::Get(Sqlite3Session& qSes, const int btr_id){
	BitRateRec bitrateRec;
	if(!qSes.IsOpen()) return bitrateRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BTR_ID,
		BTR_BITRARE
	).From(BITRATE).Where(BTR_ID == btr_id);
	if(sql.Fetch()){
		bitrateRec.btr_id = sql[BTR_ID];
		bitrateRec.btr_bitrare = sql[BTR_BITRARE];
	}
	return bitrateRec;
}
Vector<BitRateRec> BitRateData::Get(Sqlite3Session& qSes){
	Vector<BitRateRec> bitrateList;	if(!qSes.IsOpen()) return bitrateList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BTR_ID,
		BTR_BITRARE
	).From(BITRATE);
	while(sql.Fetch()){
	BitRateRec& bitrateRec = bitrateList.Add();
		bitrateRec.btr_id = sql[BTR_ID];
		bitrateRec.btr_bitrare = sql[BTR_BITRARE];
	}
	return bitrateList;
}
int BitRateData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            npp++;
	            BitRateRec bitrateRec; bitrateRec.FromCSV(tmpS, isOldSource);
	            if(!bitrateRec.IsEmpty()) Ins(qSes, bitrateRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction BitRateData::FromCSV: " << e);
        return 0;
    }
	return npp;
}

int BitRateData::Fill(Sqlite3Session& qSes, Vector<BitRateRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		BTR_ID,
		BTR_BITRARE
	).From(BITRATE);
	while(sql.Fetch()){
	BitRateRec& bitrateRec = list.Add();
		bitrateRec.btr_id = sql[BTR_ID];
		bitrateRec.btr_bitrare = sql[BTR_BITRARE];
	}
	return list.GetCount();
}
bool BitRateData::Ins(Sqlite3Session& qSes, const BitRateRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(BITRATE)
		(BTR_ID, rec.btr_id)
		(BTR_BITRARE, rec.btr_bitrare)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", BITRATE.ToString(), e));
		return false;
	}
	return true;
}
bool BitRateData::Upd(Sqlite3Session& qSes, const BitRateRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(BITRATE)
		(BTR_ID, rec.btr_id)
		(BTR_BITRARE, rec.btr_bitrare)
		.Where(BTR_ID == rec.btr_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", BITRATE.ToString(), e));
		return false;
	}
	return true;
}
bool BitRateData::Del(Sqlite3Session& qSes, const int btr_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(BITRATE)
		.Where(BTR_ID == btr_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", BITRATE.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct ClassRec :Moveable<ClassRec>{
	int cla_id;
	String cla_name;
	void Clear(){
		cla_id = 0;
		cla_name = "";
	}
	void Jsonize(JsonIO& json){
		json
		("Cla_id", cla_id)
		("Cla_name", cla_name)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Cla_id: " <<  cla_id << "\n"
			<< "	Cla_name: " <<  cla_name << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(isOldSource){
				if(i==1){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	cla_id = value;
					cla_id++;
					continue;
				}
				if(i==2){
					cla_name = vhcm[i];
				}
			}
			else{
				if(i==0){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	cla_id = value;
					continue;
				}
				if(i==1){
					cla_name = vhcm[i];
				}
			}
		}
	}
	void Set(const ClassRec& rec){
		Clear();
		cla_id = rec.cla_id;
		cla_name = rec.cla_name;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return cla_name == "";
	}
	ClassRec(){Clear();};
	ClassRec(const String& jstr){Clear();FromJsonStr(jstr);};
	ClassRec(
		const int cla_id,
		const String& cla_name
	):
		cla_id(cla_id),
		cla_name(cla_name)
	{}
	ClassRec(const ClassRec& rec):
		cla_id(rec.cla_id),
		cla_name(rec.cla_name)
	{}
};

struct ClassData :Moveable<ClassData>{
	ClassRec Get(Sqlite3Session& qSes, const int cla_id);
	ClassRec Get(Sqlite3Session& qSes, const String& cla_name);
	Vector<ClassRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<ClassRec>& list);
	bool Ins(Sqlite3Session& qSes, const ClassRec& rec);
	bool Upd(Sqlite3Session& qSes, const ClassRec& rec);
	bool Del(Sqlite3Session& qSes, const int cla_id);
	ClassData(){}
};
ClassRec ClassData::Get(Sqlite3Session& qSes, const int cla_id){
	ClassRec classRec;
	if(!qSes.IsOpen()) return classRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CLA_ID,
		CLA_NAME
	).From(CLASS).Where(CLA_ID == cla_id);
	if(sql.Fetch()){
		classRec.cla_id = sql[CLA_ID];
		classRec.cla_name = sql[CLA_NAME];
	}
	return classRec;
}
ClassRec ClassData::Get(Sqlite3Session& qSes, const String& cla_name){
	ClassRec classRec;	if(!qSes.IsOpen()) return classRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CLA_ID,
		CLA_NAME
	).From(CLASS).Where(CLA_NAME == cla_name);
	if(sql.Fetch()){
		classRec.cla_id = sql[CLA_ID];
		classRec.cla_name = sql[CLA_NAME];
	}
	return classRec;
}
Vector<ClassRec> ClassData::Get(Sqlite3Session& qSes){
	Vector<ClassRec> classList;	if(!qSes.IsOpen()) return classList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CLA_ID,
		CLA_NAME
	).From(CLASS);
	while(sql.Fetch()){
	ClassRec& classRec = classList.Add();
		classRec.cla_id = sql[CLA_ID];
		classRec.cla_name = sql[CLA_NAME];
	}
	return classList;
}
int ClassData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            npp++;
	            ClassRec classRec; classRec.FromCSV(tmpS, isOldSource);
	            if(!classRec.IsEmpty()) Ins(qSes, classRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction ClassData::FromCSV: " << e);
        return 0;
    }
	return npp;
}
int ClassData::Fill(Sqlite3Session& qSes, Vector<ClassRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		CLA_ID,
		CLA_NAME
	).From(CLASS);
	while(sql.Fetch()){
	ClassRec& classRec = list.Add();
		classRec.cla_id = sql[CLA_ID];
		classRec.cla_name = sql[CLA_NAME];
	}
	return list.GetCount();
}
bool ClassData::Ins(Sqlite3Session& qSes, const ClassRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(CLASS)
		(CLA_ID, rec.cla_id)
		(CLA_NAME, rec.cla_name)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", CLASS.ToString(), e));
		return false;
	}
	return true;
}
bool ClassData::Upd(Sqlite3Session& qSes, const ClassRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(CLASS)
		(CLA_ID, rec.cla_id)
		(CLA_NAME, rec.cla_name)
		.Where(CLA_ID == rec.cla_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", CLASS.ToString(), e));
		return false;
	}
	return true;
}
bool ClassData::Del(Sqlite3Session& qSes, const int cla_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(CLASS)
		.Where(CLA_ID == cla_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", CLASS.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct Mg_BndRec :Moveable<Mg_BndRec>{
	int mgb_id;
	int mg_id;
	int bnd_id;
	String bnd_name;

	void Clear(){
		mgb_id = 0;
		mg_id = 0;
		bnd_id = 0;
		bnd_name = "";
	}
	void Jsonize(JsonIO& json){
		json
		("Mgb_id", mgb_id)
		("Mg_id", mg_id)
		("Bnd_id", bnd_id)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return Format("mgb_id: %d, mg_id: %d, bnd_id: %d, bnd_name: %s\n", mgb_id, mg_id, bnd_id, bnd_name);
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(isOldSource){
				if(i==0){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	mgb_id = value;
					continue;
				}
				if(i==1){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	mg_id = value;
					continue;
				}
				if(i==2){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	bnd_id = value;
					continue;
				}
			}
			else{
				if(i==0){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	mgb_id = value;
					continue;
				}
				if(i==1){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	mg_id = value;
					continue;
				}
				if(i==2){
					value = StrInt(vhcm[i]);
					if(IsNumber(value))	bnd_id = value;
					continue;
				}
			}
		}
	}
	void Set(const Mg_BndRec& rec){
		Clear();
		mgb_id = rec.mgb_id;
		mg_id = rec.mg_id;
		bnd_id = rec.bnd_id;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return mg_id == 0 && bnd_id == 0;
	}
	Mg_BndRec(){Clear();};
	Mg_BndRec(const String& jstr){Clear();FromJsonStr(jstr);};
	Mg_BndRec(
		const int mgb_id,
		const int mg_id,
		const int bnd_id
	):
		mgb_id(mgb_id),
		mg_id(mg_id),
		bnd_id(bnd_id)
	{}
	Mg_BndRec(const Mg_BndRec& rec):
		mgb_id(rec.mgb_id),
		mg_id(rec.mg_id),
		bnd_id(rec.bnd_id)
	{}
};

struct Mg_BndData :Moveable<Mg_BndData>{
	Mg_BndRec Get(Sqlite3Session& qSes, const int mgb_id);
	Vector<Mg_BndRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<Mg_BndRec>& list);
	int Fill(Sqlite3Session& qSes, int mg_id, Vector<Mg_BndRec>& list);
	bool Ins(Sqlite3Session& qSes, const Mg_BndRec& rec);
	bool Upd(Sqlite3Session& qSes, const Mg_BndRec& rec);
	bool Del(Sqlite3Session& qSes, const int mgb_id);
	Mg_BndData(){}
};
Mg_BndRec Mg_BndData::Get(Sqlite3Session& qSes, const int mgb_id){
	Mg_BndRec mg_bndRec;
	if(!qSes.IsOpen()) return mg_bndRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MGB_ID,
		MG_ID,
		BND_ID
	).From(MG_BND).Where(MGB_ID == mgb_id);
	if(sql.Fetch()){
		mg_bndRec.mgb_id = sql[MGB_ID];
		mg_bndRec.mg_id = sql[MG_ID];
		mg_bndRec.bnd_id = sql[BND_ID];
	}
	return mg_bndRec;
}
Vector<Mg_BndRec> Mg_BndData::Get(Sqlite3Session& qSes){
	Vector<Mg_BndRec> mg_bndList;	if(!qSes.IsOpen()) return mg_bndList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MGB_ID,
		MG_ID,
		BND_ID
	).From(MG_BND);
	while(sql.Fetch()){
	Mg_BndRec& mg_bndRec = mg_bndList.Add();
		mg_bndRec.mgb_id = sql[MGB_ID];
		mg_bndRec.mg_id = sql[MG_ID];
		mg_bndRec.bnd_id = sql[BND_ID];
	}
	return mg_bndList;
}
int Mg_BndData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV); // cband.txt
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        String tmpS = String() << f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            Mg_BndRec mg_bndRec; mg_bndRec.FromCSV(tmpS, isOldSource);
	            if(!mg_bndRec.IsEmpty()) Ins(qSes, mg_bndRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction Mg_BndData::FromCSV: " << e);
        return 0;
    }
	return npp;
}
int Mg_BndData::Fill(Sqlite3Session& qSes, Vector<Mg_BndRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MGB_ID,
		MG_ID,
		BND_ID
	).From(MG_BND);
	while(sql.Fetch()){
	Mg_BndRec& mg_bndRec = list.Add();
		mg_bndRec.mgb_id = sql[MGB_ID];
		mg_bndRec.mg_id = sql[MG_ID];
		mg_bndRec.bnd_id = sql[BND_ID];
	}
	return list.GetCount();
}
int Mg_BndData::Fill(Sqlite3Session& qSes, int mg_id, Vector<Mg_BndRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	String sqlStr = "";
	sqlStr << " SELECT MG_BND.MGB_ID, MG_BND.MG_ID, MG_BND.BND_ID, BAND.BND_NAME from MG_BND ";
	sqlStr << " JOIN BAND ON BAND.BND_ID = MG_BND.BND_ID ";
	sqlStr << " WHERE MG_BND.MG_ID = (?)";
	sql.Execute(sqlStr, mg_id);

	while(sql.Fetch()){
	Mg_BndRec& mg_bndRec = list.Add();
		mg_bndRec.mgb_id = sql[MGB_ID];
		mg_bndRec.mg_id = sql[MG_ID];
		mg_bndRec.bnd_id = sql[BND_ID];
		mg_bndRec.bnd_name = sql[BND_NAME];
	}
	return list.GetCount();
}

bool Mg_BndData::Ins(Sqlite3Session& qSes, const Mg_BndRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(MG_BND)
		(MGB_ID, rec.mgb_id)
		(MG_ID, rec.mg_id)
		(BND_ID, rec.bnd_id)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", MG_BND.ToString(), e));
		return false;
	}
	return true;
}
bool Mg_BndData::Upd(Sqlite3Session& qSes, const Mg_BndRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(MG_BND)
		(MGB_ID, rec.mgb_id)
		(MG_ID, rec.mg_id)
		(BND_ID, rec.bnd_id)
		.Where(MGB_ID == rec.mgb_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", MG_BND.ToString(), e));
		return false;
	}
	return true;
}
bool Mg_BndData::Del(Sqlite3Session& qSes, const int mgb_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(MG_BND)
		.Where(MGB_ID == mgb_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", MG_BND.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct Mg_Bnd_CspRec :Moveable<Mg_Bnd_CspRec>{
	int mbc_id;
	int mgb_id;
	int csp_id;
	double csp_mhz;

	void Clear(){
		mbc_id = 0;
		mgb_id = 0;
		csp_id = 0;
		csp_mhz = 0.0;
	}
	void Jsonize(JsonIO& json){
		json
		("Mbc_id", mbc_id)
		("Mgb_id", mgb_id)
		("Csp_id", csp_id)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Mbc_id: " <<  mbc_id << "\n"
			<< "	Mgb_id: " <<  mgb_id << "\n"
			<< "	Csp_id: " <<  csp_id << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	mbc_id = value;
				continue;
			}
			if(i==1){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	mgb_id = value;
				continue;
			}
			if(i==2){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	csp_id = value;
				if(isOldSource && csp_id == 0) csp_id = 1;
				continue;
			}
		}
	}
	void Set(const Mg_Bnd_CspRec& rec){
		Clear();
		mbc_id = rec.mbc_id;
		mgb_id = rec.mgb_id;
		csp_id = rec.csp_id;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return mgb_id == 0 && csp_id == 0;
	}
	Mg_Bnd_CspRec(){Clear();};
	Mg_Bnd_CspRec(const String& jstr){Clear();FromJsonStr(jstr);};
	Mg_Bnd_CspRec(
		const int mbc_id,
		const int mgb_id,
		const int csp_id
	):
		mbc_id(mbc_id),
		mgb_id(mgb_id),
		csp_id(csp_id)
	{}
	Mg_Bnd_CspRec(const Mg_Bnd_CspRec& rec):
		mbc_id(rec.mbc_id),
		mgb_id(rec.mgb_id),
		csp_id(rec.csp_id)
	{}
};

struct Mg_Bnd_CspData :Moveable<Mg_Bnd_CspData>{
	Mg_Bnd_CspRec Get(Sqlite3Session& qSes, const int mbc_id);
	Vector<Mg_Bnd_CspRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<Mg_Bnd_CspRec>& list);
	int Fill(Sqlite3Session& qSes, int mgb_id, Vector<Mg_Bnd_CspRec>& list);
	bool Ins(Sqlite3Session& qSes, const Mg_Bnd_CspRec& rec);
	bool Upd(Sqlite3Session& qSes, const Mg_Bnd_CspRec& rec);
	bool Del(Sqlite3Session& qSes, const int mbc_id);
	Mg_Bnd_CspData(){}
};
Mg_Bnd_CspRec Mg_Bnd_CspData::Get(Sqlite3Session& qSes, const int mbc_id){
	Mg_Bnd_CspRec mg_bnd_cspRec;
	if(!qSes.IsOpen()) return mg_bnd_cspRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MBC_ID,
		MGB_ID,
		CSP_ID
	).From(MG_BND_CSP).Where(MBC_ID == mbc_id);
	if(sql.Fetch()){
		mg_bnd_cspRec.mbc_id = sql[MBC_ID];
		mg_bnd_cspRec.mgb_id = sql[MGB_ID];
		mg_bnd_cspRec.csp_id = sql[CSP_ID];
	}
	return mg_bnd_cspRec;
}
Vector<Mg_Bnd_CspRec> Mg_Bnd_CspData::Get(Sqlite3Session& qSes){
	Vector<Mg_Bnd_CspRec> mg_bnd_cspList;	if(!qSes.IsOpen()) return mg_bnd_cspList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MBC_ID,
		MGB_ID,
		CSP_ID
	).From(MG_BND_CSP);
	while(sql.Fetch()){
	Mg_Bnd_CspRec& mg_bnd_cspRec = mg_bnd_cspList.Add();
		mg_bnd_cspRec.mbc_id = sql[MBC_ID];
		mg_bnd_cspRec.mgb_id = sql[MGB_ID];
		mg_bnd_cspRec.csp_id = sql[CSP_ID];
	}
	return mg_bnd_cspList;
}
int Mg_Bnd_CspData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        // String tmpS = String() << ++npp << S_RAZDEL << f_in.GetLine();
	        String tmpS = String() << f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            Mg_Bnd_CspRec mg_bnd_cspRec; mg_bnd_cspRec.FromCSV(tmpS, isOldSource);
	            if(!mg_bnd_cspRec.IsEmpty()) Ins(qSes, mg_bnd_cspRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction Mg_Bnd_CspData::FromCSV: " << e);
        return 0;
    }
	return npp;
}
int Mg_Bnd_CspData::Fill(Sqlite3Session& qSes, Vector<Mg_Bnd_CspRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MBC_ID,
		MGB_ID,
		CSP_ID
	).From(MG_BND_CSP);
	while(sql.Fetch()){
	Mg_Bnd_CspRec& mg_bnd_cspRec = list.Add();
		mg_bnd_cspRec.mbc_id = sql[MBC_ID];
		mg_bnd_cspRec.mgb_id = sql[MGB_ID];
		mg_bnd_cspRec.csp_id = sql[CSP_ID];
	}
	return list.GetCount();
}
int Mg_Bnd_CspData::Fill(Sqlite3Session& qSes, int mgb_id, Vector<Mg_Bnd_CspRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	String sqlStr = "";
	sqlStr << " SELECT MG_BND_CSP.MBC_ID, MG_BND_CSP.MGB_ID, MG_BND_CSP.CSP_ID, CHSPACING.CSP_MHZ from MG_BND_CSP ";
	sqlStr << " JOIN CHSPACING ON CHSPACING.CSP_ID = MG_BND_CSP.CSP_ID ";
	sqlStr << " WHERE MG_BND_CSP.MGB_ID = (?) ORDER BY CHSPACING.CSP_MHZ";
	sql.Execute(sqlStr, mgb_id);

	while(sql.Fetch()){
	Mg_Bnd_CspRec& mg_bnd_cspRec = list.Add();
		mg_bnd_cspRec.mbc_id = sql[MBC_ID];
		mg_bnd_cspRec.mgb_id = sql[MGB_ID];
		mg_bnd_cspRec.csp_id = sql[CSP_ID];
		mg_bnd_cspRec.csp_mhz = sql[CSP_MHZ];
	}
	return list.GetCount();
}
bool Mg_Bnd_CspData::Ins(Sqlite3Session& qSes, const Mg_Bnd_CspRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(MG_BND_CSP)
		(MBC_ID, rec.mbc_id)
		(MGB_ID, rec.mgb_id)
		(CSP_ID, rec.csp_id)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", MG_BND_CSP.ToString(), e));
		return false;
	}
	return true;
}
bool Mg_Bnd_CspData::Upd(Sqlite3Session& qSes, const Mg_Bnd_CspRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(MG_BND_CSP)
		(MBC_ID, rec.mbc_id)
		(MGB_ID, rec.mgb_id)
		(CSP_ID, rec.csp_id)
		.Where(MBC_ID == rec.mbc_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", MG_BND_CSP.ToString(), e));
		return false;
	}
	return true;
}
bool Mg_Bnd_CspData::Del(Sqlite3Session& qSes, const int mbc_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(MG_BND_CSP)
		.Where(MBC_ID == mbc_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", MG_BND_CSP.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct MaskRec :Moveable<MaskRec>{
	int msk_id;
	int mbc_id;
	int btr_id;
	int cla_id;
	String msk_remark;
	String btr_bitrare;
	String cla_name;

	void Clear(){
		msk_id = 0;
		mbc_id = 0;
		btr_id = 0;
		cla_id = 0;
		msk_remark = "";
	}
	void Jsonize(JsonIO& json){
		json
		("Msk_id", msk_id)
		("Mbc_id", mbc_id)
		("Btr_id", btr_id)
		("Cla_id", cla_id)
		("Msk_remark", msk_remark)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Msk_id: " <<  msk_id << "\n"
			<< "	Mbc_id: " <<  mbc_id << "\n"
			<< "	Btr_id: " <<  btr_id << "\n"
			<< "	Cla_id: " <<  cla_id << "\n"
			<< "	Msk_remark: " <<  msk_remark << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	msk_id = value;
				continue;
			}
			if(i==1){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	mbc_id = value;
				continue;
			}
			if(i==2){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	btr_id = value;
				continue;
			}
			if(i==3){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	cla_id = value;
				if(isOldSource) cla_id++;
				continue;
			}
			if(i==4){
				msk_remark = vhcm[i];
			}
		}
	}
	void Set(const MaskRec& rec){
		Clear();
		msk_id = rec.msk_id;
		mbc_id = rec.mbc_id;
		btr_id = rec.btr_id;
		cla_id = rec.cla_id;
		msk_remark = rec.msk_remark;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return mbc_id == 0 && btr_id == 0 && cla_id == 0;
	}
	MaskRec(){Clear();};
	MaskRec(const String& jstr){Clear();FromJsonStr(jstr);};
	MaskRec(
		const int msk_id,
		const int mbc_id,
		const int btr_id,
		const int cla_id,
		const String& msk_remark
	):
		msk_id(msk_id),
		mbc_id(mbc_id),
		btr_id(btr_id),
		cla_id(cla_id),
		msk_remark(msk_remark)
	{}
	MaskRec(const MaskRec& rec):
		msk_id(rec.msk_id),
		mbc_id(rec.mbc_id),
		btr_id(rec.btr_id),
		cla_id(rec.cla_id),
		msk_remark(rec.msk_remark)
	{}
};

struct MaskData :Moveable<MaskData>{
	MaskRec Get(Sqlite3Session& qSes, const int msk_id);
	Vector<MaskRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<MaskRec>& list);
	int Fill(Sqlite3Session& qSes, int mbc_id, Vector<MaskRec>& list);
	bool Ins(Sqlite3Session& qSes, const MaskRec& rec);
	bool Upd(Sqlite3Session& qSes, const MaskRec& rec);
	bool Del(Sqlite3Session& qSes, const int msk_id);
	MaskData(){}
};
MaskRec MaskData::Get(Sqlite3Session& qSes, const int msk_id){
	MaskRec maskRec;
	if(!qSes.IsOpen()) return maskRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MSK_ID,
		MBC_ID,
		BTR_ID,
		CLA_ID,
		MSK_REMARK
	).From(MASK).Where(MSK_ID == msk_id);
	if(sql.Fetch()){
		maskRec.msk_id = sql[MSK_ID];
		maskRec.mbc_id = sql[MBC_ID];
		maskRec.btr_id = sql[BTR_ID];
		maskRec.cla_id = sql[CLA_ID];
		maskRec.msk_remark = sql[MSK_REMARK];
	}
	return maskRec;
}
Vector<MaskRec> MaskData::Get(Sqlite3Session& qSes){
	Vector<MaskRec> maskList;	if(!qSes.IsOpen()) return maskList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MSK_ID,
		MBC_ID,
		BTR_ID,
		CLA_ID,
		MSK_REMARK
	).From(MASK);
	while(sql.Fetch()){
	MaskRec& maskRec = maskList.Add();
		maskRec.msk_id = sql[MSK_ID];
		maskRec.mbc_id = sql[MBC_ID];
		maskRec.btr_id = sql[BTR_ID];
		maskRec.cla_id = sql[CLA_ID];
		maskRec.msk_remark = sql[MSK_REMARK];
	}
	return maskList;
}
int MaskData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            npp++;
	            MaskRec maskRec; maskRec.FromCSV(tmpS, isOldSource);
	            if(!maskRec.IsEmpty()) Ins(qSes, maskRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction MaskData::FromCSV: " << e);
        return 0;
    }
	return npp;
}
int MaskData::Fill(Sqlite3Session& qSes, Vector<MaskRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MSK_ID,
		MBC_ID,
		BTR_ID,
		CLA_ID,
		MSK_REMARK
	).From(MASK);
	while(sql.Fetch()){
	MaskRec& maskRec = list.Add();
		maskRec.msk_id = sql[MSK_ID];
		maskRec.mbc_id = sql[MBC_ID];
		maskRec.btr_id = sql[BTR_ID];
		maskRec.cla_id = sql[CLA_ID];
		maskRec.msk_remark = sql[MSK_REMARK];
	}
	return list.GetCount();
}
int MaskData::Fill(Sqlite3Session& qSes, int mbc_id, Vector<MaskRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	String sqlStr = "";
	sqlStr << " SELECT MASK.MSK_ID, MASK.MBC_ID, MASK.BTR_ID, MASK.CLA_ID, MASK.MSK_REMARK, BITRATE.BTR_BITRARE, CLASS.CLA_NAME from MASK "
		   << " JOIN BITRATE ON BITRATE.BTR_ID = MASK.BTR_ID "
		   << " JOIN CLASS ON CLASS.CLA_ID = MASK.CLA_ID "
		   << " WHERE MASK.MBC_ID = (?)" ;
	sql.Execute(sqlStr, mbc_id);

	while(sql.Fetch()){
	MaskRec& maskRec = list.Add();
		maskRec.msk_id = sql[MSK_ID];
		maskRec.mbc_id = sql[MBC_ID];
		maskRec.btr_id = sql[BTR_ID];
		maskRec.cla_id = sql[CLA_ID];
		maskRec.msk_remark = sql[MSK_REMARK];
		maskRec.btr_bitrare = sql[BTR_BITRARE];
		maskRec.cla_name = sql[CLA_NAME];
	}
	return list.GetCount();
}

bool MaskData::Ins(Sqlite3Session& qSes, const MaskRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(MASK)
		(MSK_ID, rec.msk_id)
		(MBC_ID, rec.mbc_id)
		(BTR_ID, rec.btr_id)
		(CLA_ID, rec.cla_id)
		(MSK_REMARK, rec.msk_remark)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", MASK.ToString(), e));
		return false;
	}
	return true;
}
bool MaskData::Upd(Sqlite3Session& qSes, const MaskRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(MASK)
		(MSK_ID, rec.msk_id)
		(MBC_ID, rec.mbc_id)
		(BTR_ID, rec.btr_id)
		(CLA_ID, rec.cla_id)
		(MSK_REMARK, rec.msk_remark)
		.Where(MSK_ID == rec.msk_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", MASK.ToString(), e));
		return false;
	}
	return true;
}
bool MaskData::Del(Sqlite3Session& qSes, const int msk_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(MASK)
		.Where(MSK_ID == msk_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", MASK.ToString(), e));
		return false;
	}
	return true;
}
//!---------------------------------------------------------------------------------------------

struct MpointRec :Moveable<MpointRec>{
	int mp_id;
	int msk_id;
	double mp_freq;
	double mp_atten;
	void Clear(){
		mp_id = 0;
		msk_id = 0;
		mp_freq = 0.0;
		mp_atten = 0.0;
	}
	void Jsonize(JsonIO& json){
		json
		("Mp_id", mp_id)
		("Msk_id", msk_id)
		("Mp_freq", mp_freq)
		("Mp_atten", mp_atten)
		;
	}
	String ToJsonStr()const{return StoreAsJson(*this);};
	void FromJsonStr(const String& s){LoadFromJson(*this, s);};
	String ToString()const{
		return String()
			<< "	Mp_id: " <<  mp_id << "\n"
			<< "	Msk_id: " <<  msk_id << "\n"
			<< "	Mp_freq: " <<  mp_freq << "\n"
			<< "	Mp_atten: " <<  mp_atten << "\n"
		;
	}
	void FromCSV(const String& csv, bool isOldSource){
		Clear();
		Vector<String> vhcm;
		StringStream strm = StringStream() << csv;
		auto v = GetCsvLine(strm, C_RAZDEL, CHARSET_DEFAULT);
		for(auto e : v){
			vhcm.Add(e);
		}
		Value value = Null;
		for(int i=0; i < vhcm.GetCount(); i++){
			if(i==0){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	mp_id = value;
				continue;
			}
			if(i==1){
				value = StrInt(vhcm[i]);
				if(IsNumber(value))	msk_id = value;
				continue;
			}
			if(i==2){
				value = StrDbl(vhcm[i]);
				if(IsNumber(value))	mp_freq = value;
				continue;
			}
			if(i==3){
				value = StrDbl(vhcm[i]);
				if(IsNumber(value))	mp_atten = value;
				continue;
			}
		}
	}
	void Set(const MpointRec& rec){
		Clear();
		mp_id = rec.mp_id;
		msk_id = rec.msk_id;
		mp_freq = rec.mp_freq;
		mp_atten = rec.mp_atten;
	}
	void Set(const String& jStr){
		Clear();FromJsonStr(jStr);
	}
	bool IsEmpty(){
		return msk_id == 0 && mp_freq == 0 && mp_atten == 0;
	}
	MpointRec(){Clear();};
	MpointRec(const String& jstr){Clear();FromJsonStr(jstr);};
	MpointRec(
		const int mp_id,
		const int msk_id,
		const double mp_freq,
		const double mp_atten
	):
		mp_id(mp_id),
		msk_id(msk_id),
		mp_freq(mp_freq),
		mp_atten(mp_atten)
	{}
	MpointRec(const MpointRec& rec):
		mp_id(rec.mp_id),
		msk_id(rec.msk_id),
		mp_freq(rec.mp_freq),
		mp_atten(rec.mp_atten)
	{}
};


struct MpointData :Moveable<MpointData>{
	MpointRec Get(Sqlite3Session& qSes, const int mp_id);
	Vector<MpointRec> Get(Sqlite3Session& qSes);
	int FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource);
	int Fill(Sqlite3Session& qSes, Vector<MpointRec>& list);
	int Fill(Sqlite3Session& qSes, int msk_id, Vector<MpointRec>& list);
	bool Ins(Sqlite3Session& qSes, const MpointRec& rec);
	bool Upd(Sqlite3Session& qSes, const MpointRec& rec);
	bool Del(Sqlite3Session& qSes, const int mp_id);
	MpointData(){}
};
MpointRec MpointData::Get(Sqlite3Session& qSes, const int mp_id){
	MpointRec mpointRec;
	if(!qSes.IsOpen()) return mpointRec;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MP_ID,
		MSK_ID,
		MP_FREQ,
		MP_ATTEN
	).From(MPOINT).Where(MP_ID == mp_id);
	if(sql.Fetch()){
		mpointRec.mp_id = sql[MP_ID];
		mpointRec.msk_id = sql[MSK_ID];
		mpointRec.mp_freq = sql[MP_FREQ];
		mpointRec.mp_atten = sql[MP_ATTEN];
	}
	return mpointRec;
}
Vector<MpointRec> MpointData::Get(Sqlite3Session& qSes){
	Vector<MpointRec> mpointList;	if(!qSes.IsOpen()) return mpointList;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MP_ID,
		MSK_ID,
		MP_FREQ,
		MP_ATTEN
	).From(MPOINT);
	while(sql.Fetch()){
	MpointRec& mpointRec = mpointList.Add();
		mpointRec.mp_id = sql[MP_ID];
		mpointRec.msk_id = sql[MSK_ID];
		mpointRec.mp_freq = sql[MP_FREQ];
		mpointRec.mp_atten = sql[MP_ATTEN];
	}
	return mpointList;
}
int MpointData::FromCSV(Sqlite3Session& qSes, const String& fileCSV, bool isOldSource){
	if(!FileExists(fileCSV)){
		LOG(Format("Error: File %s, not found", fileCSV));
		return 0;
	}
	FileIn f_in(fileCSV);
	int npp = 0;
    try
    {
		qSes.Begin();//--------------- Старт транзакции
		while(!f_in.IsEof()){
			Vector<String> tmpVec;
	        String tmpS = f_in.GetLine();
	        if(!TrimBoth(tmpS).IsEmpty()){
	            // skip title
	            if((tmpS.Find("ID;")!=-1 || tmpS.Find("ROWID;")!=-1)) continue;
	            npp++;
	            MpointRec mpointRec; mpointRec.FromCSV(tmpS, isOldSource);
	            if(!mpointRec.IsEmpty()) Ins(qSes, mpointRec);
	        }
	    }
		qSes.Commit();//--------------- Commit транзакции
	}
    catch(SqlExc &e)
    {
        qSes.Rollback();//--------------- Rollback транзакции
		LOG("ERROR Transaction MpointData::FromCSV: " << e);
        return 0;
    }
	return npp;
}
int MpointData::Fill(Sqlite3Session& qSes, Vector<MpointRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MP_ID,
		MSK_ID,
		MP_FREQ,
		MP_ATTEN
	).From(MPOINT);
	while(sql.Fetch()){
	MpointRec& mpointRec = list.Add();
		mpointRec.mp_id = sql[MP_ID];
		mpointRec.msk_id = sql[MSK_ID];
		mpointRec.mp_freq = sql[MP_FREQ];
		mpointRec.mp_atten = sql[MP_ATTEN];
	}
	return list.GetCount();
}
int MpointData::Fill(Sqlite3Session& qSes, int msk_id, Vector<MpointRec>& list){
	if(!qSes.IsOpen()) return 0;
	Sql sql(qSes);
	sql.ClearError();
	sql * Select(
		MP_ID,
		MSK_ID,
		MP_FREQ,
		MP_ATTEN
	).From(MPOINT).Where(MSK_ID == msk_id);
	while(sql.Fetch()){
	MpointRec& mpointRec = list.Add();
		mpointRec.mp_id = sql[MP_ID];
		mpointRec.msk_id = sql[MSK_ID];
		mpointRec.mp_freq = sql[MP_FREQ];
		mpointRec.mp_atten = sql[MP_ATTEN];
	}
	return list.GetCount();
}

bool MpointData::Ins(Sqlite3Session& qSes, const MpointRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Insert(MPOINT)
		(MP_ID, rec.mp_id)
		(MSK_ID, rec.msk_id)
		(MP_FREQ, rec.mp_freq)
		(MP_ATTEN, rec.mp_atten)
		;
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to insert into %s: %s ", MPOINT.ToString(), e));
		return false;
	}
	return true;
}
bool MpointData::Upd(Sqlite3Session& qSes, const MpointRec& rec){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Update(MPOINT)
		(MP_ID, rec.mp_id)
		(MSK_ID, rec.msk_id)
		(MP_FREQ, rec.mp_freq)
		(MP_ATTEN, rec.mp_atten)
		.Where(MP_ID == rec.mp_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to update into %s: %s ", MPOINT.ToString(), e));
		return false;
	}
	return true;
}
bool MpointData::Del(Sqlite3Session& qSes, const int mp_id){
	if(!qSes.IsOpen()) return false;
	Sql sql(qSes);
	sql.ClearError();
	try{
		sql * Delete(MPOINT)
		.Where(MP_ID == mp_id);
	}
	catch(SqlExc &e){
		LOG(Format("ERROR to delete %s: %s ", MPOINT.ToString(), e));
		return false;
	}
	return true;
}
 
#endif

