Example #1
0
void sg_xmlcfg::load_svrents(const bpt::iptree& pt)
{
	boost::char_separator<char> sep(" \t\b");
	gpenv& env_mgr = gpenv::instance();

	try {
		BOOST_FOREACH(const bpt::iptree::value_type& v, pt.get_child("servicegalaxy.processes")) {
			if (v.first != "process")
				continue;

			const bpt::iptree& v_pt = v.second;
			sg_svrent_t item;
			memset(&item, '\0', sizeof(sg_svrent_t));

			item.sparms.rqparms.options = RESTARTABLE;
			item.bparms.flags = 0;

			string options = get_value(v_pt, "options", string(""));
			tokenizer options_tokens(options, sep);
			for (tokenizer::iterator iter = options_tokens.begin(); iter != options_tokens.end(); ++iter) {
				string str = *iter;

				if (strcasecmp(str.c_str(), "NONRESTART ") == 0)
					item.sparms.rqparms.options &= ~RESTARTABLE;
				else if (strcasecmp(str.c_str(), "REPLYQ") == 0)
					item.bparms.flags |= BF_REPLYQ;
				else if (strcasecmp(str.c_str(), "PRESERVE_FD") == 0)
					item.bparms.flags |= BF_PRESERVE_FD;
			}

			item.sparms.rqparms.grace = get_value(v_pt, "rstint", DFLT_RSTINT);
			if (item.sparms.rqparms.grace <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.rstint must be positive.")).str(SGLOCALE));

			item.sparms.rqparms.maxgen = get_value(v_pt, "maxrst", std::numeric_limits<int>::max());
			if (item.sparms.rqparms.maxgen <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.maxrst must be positive.")).str(SGLOCALE));

			string lqname = get_value(v_pt, "lqname", string(""));
			if (lqname.length() > MAX_IDENT)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.lqname is too long.")).str(SGLOCALE));
			strcpy(item.sparms.rqparms.saddr, lqname.c_str());

			string exitcmd = get_value(v_pt, "exitcmd", string(""));
			if (exitcmd.length() > MAX_LSTRING)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.exitcmd is too long.")).str(SGLOCALE));
			strcpy(item.sparms.rqparms.rcmd, exitcmd.c_str());

			string procname = v_pt.get<string>("procname");
			if (procname.empty() || procname.length() > MAX_LSTRING)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.procname is empty or too long.")).str(SGLOCALE));
			strcpy(item.sparms.rqparms.filename, procname.c_str());

			item.sparms.svrproc.svrid = v_pt.get<int>("prcid");
			if (item.sparms.svrproc.svrid <= MAX_RESERVED_PRCID)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.prcid must be no less than {1}.") % MAX_RESERVED_PRCID).str(SGLOCALE));

			parse_perm(get_value(v_pt, "rqperm", string("")), item.sparms.rqperm, "processes.process.rqperm");
			parse_perm(get_value(v_pt, "rpperm", string("")), item.sparms.rpperm, "processes.process.rpperm");

			item.sparms.sequence = get_value(v_pt, "priority", 0);
			if (item.sparms.sequence < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.priority must be zero or positive.")).str(SGLOCALE));

			item.bparms.bootmin = get_value(v_pt, "min", 1);
			if (item.bparms.bootmin < 0 || item.bparms.bootmin > 1000)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.min must be between 0 and 1000.")).str(SGLOCALE));

			item.sparms.svridmax = get_value(v_pt, "max", 1);
			if (item.sparms.svridmax < 1 || item.sparms.svridmax > 1000)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.max must be between 1 and 1000.")).str(SGLOCALE));

			if (item.bparms.bootmin > item.sparms.svridmax)
				item.sparms.svridmax = item.sparms.svrproc.svrid + item.bparms.bootmin - 1;
			else
				item.sparms.svridmax += item.sparms.svrproc.svrid - 1;

			item.sparms.max_num_msg = get_value(v_pt, "msgmnb", 0);
			if (item.sparms.max_num_msg < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.msgmnb must be zero or positive.")).str(SGLOCALE));

			item.sparms.max_msg_size = get_value(v_pt, "msgmax", 0);
			if (item.sparms.max_msg_size < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.msgmax must be zero or positive.")).str(SGLOCALE));

			item.sparms.cmprs_limit = get_value(v_pt, "cmprslimit", 0);
			if (item.sparms.cmprs_limit < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.cmprslimit must be zero or positive.")).str(SGLOCALE));

			item.sparms.remedy = get_value(v_pt, "costfix", 0);
			if (item.sparms.remedy < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.costfix must be zero or positive.")).str(SGLOCALE));

			string pgname = get_value(v_pt, "pgname", string(""));
			if (pgname.length() > MAX_IDENT)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.pgname is too long.")).str(SGLOCALE));
			strcpy(item.sparms.sgname, pgname.c_str());

			if (item.sparms.sgname[0] == '\0') {
				item.sparms.svrproc.grpid = DFLT_PGID;
			} else {
				bool found = false;
				BOOST_FOREACH(const sg_sgent_t& v, sgents) {
					if (v.sgname == pgname) {
						item.sparms.svrproc.grpid = v.grpid;
						found = true;
					}
				}
				if (!found)
					throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: Can't find process group for {1}") % pgname).str(SGLOCALE));
			}

			// TGWS需要独立的应答队列
			if (strcmp(item.sparms.rqparms.filename, "sgtgws") == 0)
				SGP->_SGP_boot_flags |= BF_REPLYQ;

			string args;
			env_mgr.expand_var(args, get_value(v_pt, "args", string("-A")));
			if (args.length() > MAX_LSTRING)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.args is too long.")).str(SGLOCALE));
			strcpy(item.bparms.clopt, args.c_str());

			string profile;
			env_mgr.expand_var(profile, get_value(v_pt, "profile", string("")));
			if (profile.length() > MAX_LSTRING)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: processes.process.profile is too long.")).str(SGLOCALE));
			strcpy(item.bparms.envfile, profile.c_str());

			BOOST_FOREACH(const sg_svrent_t& v, svrents) {
				if (v.sparms.svrproc.grpid == item.sparms.svrproc.grpid
					&& ((v.sparms.svrproc.svrid <= item.sparms.svrproc.svrid
						&& v.sparms.svridmax >= item.sparms.svrproc.svrid)
						|| (v.sparms.svrproc.svrid <= item.sparms.svridmax
						&& v.sparms.svridmax >= item.sparms.svridmax)))
					throw sg_exception(__FILE__, __LINE__, SGEPROTO, 0, (_("ERROR: duplicate process entry.")).str(SGLOCALE));
			}

			svrents.push_back(item);
		}
	} catch (bpt::ptree_bad_data& ex) {
		throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section processes failure, {1} ({2})") % ex.what() % ex.data<string>()).str(SGLOCALE));
	} catch (bpt::ptree_error& ex) {
		throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section processes failure, {1}") % ex.what()).str(SGLOCALE));
	}
}
Example #2
0
void sg_xmlcfg::load_bbparms(const bpt::iptree& pt, bool enable_hidden)
{
	gpenv& env_mgr = gpenv::instance();
	boost::char_separator<char> sep(" \t\b");
	int i;

	try {
		memset(&bbparms, '\0', sizeof(sg_bbparms_t));

		bbparms.magic = VERSION;
		bbparms.bbrelease = SGRELEASE;
		int current = time(0);

		BOOST_FOREACH(const bpt::iptree::value_type& v, pt.get_child("servicegalaxy")) {
			if (v.first != "cluster")
				continue;

			const bpt::iptree& v_pt = v.second;

			if (enable_hidden) {
				bbparms.bbversion = get_value(v_pt, "bbversion", current);
				bbparms.sgversion = get_value(v_pt, "sgversion", current);
			} else {
				bbparms.bbversion = current;
				bbparms.sgversion = current;
			}

			string clstid;
			env_mgr.expand_var(clstid, v_pt.get<string>("clstid"));
			try {
				bbparms.ipckey = boost::lexical_cast<int>(clstid);
			} catch (exception& ex) {
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.clstid invalid, {1}.") % ex.what()).str(SGLOCALE));
			}
			if (bbparms.ipckey <= 0 || bbparms.ipckey >= (1 << MCHIDSHIFT))
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.clstid is invalid, should be positive but less than {1}.") % (1 << MCHIDSHIFT)).str(SGLOCALE));

			bbparms.uid = get_value(v_pt, "uid", ::getuid());
			bbparms.gid = get_value(v_pt, "gid", ::getgid());

			parse_perm(get_value(v_pt, "perm", string("")), bbparms.perm, "cluster.perm");

			bbparms.options = SGLAN;	// default to LAN mode
			bbparms.ldbal = DFLT_LDBAL;

			string options = get_value(v_pt, "options", string(""));
			tokenizer options_tokens(options, sep);
			for (tokenizer::iterator iter = options_tokens.begin(); iter != options_tokens.end(); ++iter) {
				string str = *iter;

				if (strcasecmp(str.c_str(), "LAN") == 0)
					bbparms.options |= SGLAN;
				else if (strcasecmp(str.c_str(), "MIGALLOWED") == 0)
					bbparms.options |= SGMIGALLOWED;
				else if (strcasecmp(str.c_str(), "HA") == 0)
					bbparms.options |= SGHA;
				else if (strcasecmp(str.c_str(), "ACCSTATS") == 0)
					bbparms.options |= SGACCSTATS;
				else if (strcasecmp(str.c_str(), "CLEXITL") == 0)
					bbparms.options |= SGCLEXITL;
				else if (strcasecmp(str.c_str(), "AA") == 0)
					bbparms.options |= SGAA;
				else if (strcasecmp(str.c_str(), "RR") == 0)
					bbparms.ldbal = LDBAL_RR;
				else if (strcasecmp(str.c_str(), "RT") == 0)
					bbparms.ldbal = LDBAL_RT;
			}

			i = 0;
			string master = v_pt.get<string>("master");
			tokenizer master_tokens(master, sep);
			for (tokenizer::iterator iter = master_tokens.begin(); iter != master_tokens.end(); ++iter) {
				string str = *iter;

				if (str.length() > MAX_IDENT)
					throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.master too long for master node.")).str(SGLOCALE));

				strcpy(bbparms.master[i++], str.c_str());
				if (i > MAX_MASTERS)
					throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.master too many masters.")).str(SGLOCALE));
			}
			bbparms.current = get_value(v_pt, "curid", 0);
			if (bbparms.current < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.curid must be zero or positive.")).str(SGLOCALE));

			bbparms.maxpes = get_value(v_pt, "maxnodes", DFLT_MAXNODES);
			if (bbparms.maxpes <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxnodes must be positive.")).str(SGLOCALE));

			bbparms.maxnodes = get_value(v_pt, "maxnets", DFLT_MAXNETS);
			if (bbparms.maxnodes <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxnets must be positive.")).str(SGLOCALE));

			bbparms.maxaccsrs = get_value(v_pt, "maxclts", DFLT_MAXCLTS);
			if (bbparms.maxaccsrs <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxclts must be positive.")).str(SGLOCALE));

			bbparms.maxques = get_value(v_pt, "maxques", DFLT_MAXQUES);
			if (bbparms.maxques <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxques must be positive.")).str(SGLOCALE));

			bbparms.maxsgt = get_value(v_pt, "maxpgs", DFLT_MAXPGS);
			if (bbparms.maxsgt <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxpgs must be positive.")).str(SGLOCALE));

			bbparms.maxsvrs = get_value(v_pt, "maxprocs", DFLT_MAXPROCS);
			if (bbparms.maxsvrs <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxprocs must be positive.")).str(SGLOCALE));

			bbparms.maxsvcs = get_value(v_pt, "maxops", DFLT_MAXOPS);
			if (bbparms.maxsvcs <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.maxops must be positive.")).str(SGLOCALE));

			bbparms.quebkts = get_value(v_pt, "quebkts", DFLT_QUEBKTS);
			if (bbparms.quebkts <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.quebkts must be positive.")).str(SGLOCALE));

			bbparms.sgtbkts = get_value(v_pt, "pgbkts", DFLT_PGBKTS);
			if (bbparms.sgtbkts <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.pgbkts must be positive.")).str(SGLOCALE));

			bbparms.svrbkts = get_value(v_pt, "procbkts", DFLT_PROCBKTS);
			if (bbparms.svrbkts <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.procbkts must be positive.")).str(SGLOCALE));

			bbparms.svcbkts = get_value(v_pt, "opbkts", DFLT_OPBKTS);
			if (bbparms.svcbkts <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.opbkts must be positive.")).str(SGLOCALE));

			bbparms.scan_unit = get_value(v_pt, "polltime", DFLT_POLLTIME);
			if (bbparms.scan_unit < 6)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.polltime must be at least 6.")).str(SGLOCALE));

			bbparms.sanity_scan = get_value(v_pt, "robustint", DFLT_ROBUSTINT);
			if (bbparms.sanity_scan <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.robustint must be positive.")).str(SGLOCALE));

			bbparms.stack_size = get_value(v_pt, "stacksize", DFLT_STACKSIZE);
			if (bbparms.stack_size <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.stacksize must be positive.")).str(SGLOCALE));

			bbparms.max_num_msg = get_value(v_pt, "msgmnb", DFLT_MSGMNB);
			if (bbparms.max_num_msg <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.msgmnb must be positive.")).str(SGLOCALE));

			bbparms.max_msg_size = get_value(v_pt, "msgmax", DFLT_MSGMAX);
			if (bbparms.max_msg_size <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.msgmax must be positive.")).str(SGLOCALE));

			bbparms.cmprs_limit = get_value(v_pt, "cmprslimit", DFLT_CMPRSLIMIT);
			if (bbparms.cmprs_limit < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.cmprslimit must be zero or positive.")).str(SGLOCALE));

			bbparms.remedy = get_value(v_pt, "costfix", DFLT_COSTFIX);
			if (bbparms.remedy < 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.costfix must be zero or positive.")).str(SGLOCALE));

			bbparms.max_open_queues = get_value(v_pt, "nfiles", DFLT_NFILES);
			if (bbparms.max_open_queues <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.nfiles must be positive.")).str(SGLOCALE));

			bbparms.block_time = get_value(v_pt, "blktime", DFLT_BLKTIME);
			if (bbparms.block_time <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.blktime must be positive.")).str(SGLOCALE));

			bbparms.dbbm_wait = get_value(v_pt, "clstwait", DFLT_CLSTWAIT);
			if (bbparms.dbbm_wait <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.clstwait must be positive.")).str(SGLOCALE));

			bbparms.bbm_query = get_value(v_pt, "mngrquery", DFLT_MNGRQUERY);
			if (bbparms.bbm_query < bbparms.sanity_scan)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.mngrquery must be no less than robustint.")).str(SGLOCALE));

			bbparms.init_wait = get_value(v_pt, "initwait", DFLT_INITWAIT);
			if (bbparms.init_wait <= 0)
				throw sg_exception(__FILE__, __LINE__, SGEINVAL, 0, (_("ERROR: cluster.initwait must be positive.")).str(SGLOCALE));
		}
	} catch (bpt::ptree_bad_data& ex) {
		throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section cluster failure, {1} ({2})") % ex.what() % ex.data<string>()).str(SGLOCALE));
	} catch (bpt::ptree_error& ex) {
		throw sg_exception(__FILE__, __LINE__, SGESYSTEM, 0, (_("ERROR: Parse section cluster failure, {1}") % ex.what()).str(SGLOCALE));
	}
}
Example #3
0
bool SQL_CUSTOM::init(AbstractExt *extension, const std::string &database_id, const std::string init_str)
{
	extension_ptr = extension;
	if (extension_ptr->extDB_connectors_info.databases.count(database_id) == 0)
	{
		#ifdef DEBUG_TESTING
			extension_ptr->console->warn("extDB2: SQL_CUSTOM: No Database Connection ID: {0}", database_id);
		#endif
		extension_ptr->logger->warn("extDB2: SQL_CUSTOM: No Database Connection ID: {0}", database_id);
		return false;
	}

	database_ptr = &extension_ptr->extDB_connectors_info.databases[database_id];
	if ((database_ptr->type != std::string("MySQL")) && (database_ptr->type != std::string("SQLite")))
	{
		// DATABASE NOT SETUP YET
		#ifdef DEBUG_TESTING
			extension_ptr->console->warn("extDB2: SQL_CUSTOM: Database Type Not Supported");
		#endif
		extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Database Type Not Supported");
		return false;
	}

	// Check if SQL_CUSTOM Template Filename Given
	if (init_str.empty()) 
	{
		#ifdef DEBUG_TESTING
			extension_ptr->console->warn("extDB2: SQL_CUSTOM: Missing Init Parameter");
		#endif
		extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Missing Init Parameter");
		return false;
	}

	Poco::AutoPtr<Poco::Util::IniFileConfiguration> template_ini;
	template_ini = new Poco::Util::IniFileConfiguration();

	boost::filesystem::path sql_custom_path(extension_ptr->extDB_info.path);
	sql_custom_path /= "extDB";
	sql_custom_path /= "sql_custom";
	boost::filesystem::create_directories(sql_custom_path); // Creating Directory if missing

	bool status = true;
	if (status)
	{
		std::string db_template_file_str;
		Poco::StringTokenizer custom_ini_files(init_str, ",", Poco::StringTokenizer::TOK_TRIM);
		for (auto &custom_ini_file : custom_ini_files)
		{
			boost::filesystem::path db_template_file(sql_custom_path);
			db_template_file /= (custom_ini_file + ".ini");
			db_template_file_str = db_template_file.make_preferred().string();

			#ifdef DEBUG_TESTING
				extension_ptr->console->info("extDB2: SQL_CUSTOM: Loading Template Filename: {0}", db_template_file_str);
			#endif
			extension_ptr->logger->info("extDB2: SQL_CUSTOM: Loading Template Filename: {0}", db_template_file_str);

			if (boost::filesystem::exists(db_template_file_str))
			{
				template_ini->loadExtra(db_template_file_str);
			}
			else
			{
				status = false;
				#ifdef DEBUG_TESTING
					extension_ptr->console->warn("extDB2: SQL_CUSTOM: Template File Not Found: {0}", db_template_file_str);
				#endif
				extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Template File Not Found: {0}", db_template_file_str);
				break;
			}
		}
	}
	
	// Read Template File
	if (status)
	{		
		std::vector<std::string> custom_calls_list;
		template_ini->keys(custom_calls_list);

		if ((template_ini->getInt("Default.Version", 1)) == EXTDB_SQL_CUSTOM_REQUIRED_VERSION)
		{
			int default_number_of_inputs = template_ini->getInt("Default.Number of Inputs", 0);
			int default_number_of_custom_inputs = template_ini->getInt("Default.Number of Custom Inputs", 0);

			bool default_input_sanitize_value_check = template_ini->getBool("Default.Sanitize Input Value Check", true);
			bool default_output_sanitize_value_check = template_ini->getBool("Default.Sanitize Output Value Check", true);
			bool default_preparedStatement_cache = template_ini->getBool("Default.Prepared Statement Cache", true);
			bool default_returnInsertID = template_ini->getBool("Default.Return InsertID", false);


			bool default_strip = template_ini->getBool("Default.Strip", false);
			std::string default_strip_chars = template_ini->getString("Default.Strip Chars", "");
			std::string default_strip_custom_input_chars = template_ini->getString("Default.Strip Custom Chars", "");
			int default_strip_chars_action = 0;

			std::string strip_chars_action_str = template_ini->getString("Default.Strip Chars Action", "Strip");
			if	(boost::iequals(strip_chars_action_str, std::string("Strip")) == 1)
			{
				default_strip_chars_action = 1;
			}
			else if	(boost::iequals(strip_chars_action_str, std::string("Strip+Log")) == 1)
			{
				default_strip_chars_action = 2;
			}
			else if	(boost::iequals(strip_chars_action_str, std::string("Strip+Error")) == 1)
			{
				default_strip_chars_action = 3;
			}
			else if (boost::iequals(strip_chars_action_str, std::string("None")) == 1)
			{
				default_strip_chars_action = 0;
			}
			else
			{
				#ifdef DEBUG_TESTING
					extension_ptr->console->warn("extDB2: SQL_CUSTOM: Invalid Default Strip Chars Action: {0}", strip_chars_action_str);
				#endif
				extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Invalid Default Strip Chars Action: {0}", strip_chars_action_str);
			}

			for(std::string &call_name : custom_calls_list)
			{
				int sql_line_num = 0;
				int sql_part_num = 0;

				std::string sql_line_num_str;
				std::string sql_part_num_str;

				custom_calls[call_name].number_of_inputs = template_ini->getInt(call_name + ".Number of Inputs", default_number_of_inputs);
				custom_calls[call_name].number_of_custom_inputs = template_ini->getInt(call_name + ".Number of Custom Inputs", default_number_of_custom_inputs);
				custom_calls[call_name].preparedStatement_cache = template_ini->getBool(call_name + ".Prepared Statement Cache", default_preparedStatement_cache);
				custom_calls[call_name].returnInsertID = template_ini->getBool(call_name + ".Return InsertID", default_returnInsertID);

				if (template_ini->has(call_name + ".Strip Chars Action"))
				{
					strip_chars_action_str = template_ini->getString(call_name + ".Strip Chars Action", "");
					if	(boost::iequals(strip_chars_action_str, std::string("Strip")) == 1)
					{
						custom_calls[call_name].strip_chars_action = 1;
					}
					else if	(boost::iequals(strip_chars_action_str, std::string("Strip+Log")) == 1)
					{
						custom_calls[call_name].strip_chars_action = 2;
					}
					else if	(boost::iequals(strip_chars_action_str, std::string("Strip+Error")) == 1)
					{
						custom_calls[call_name].strip_chars_action = 3;
					}
					else if (boost::iequals(strip_chars_action_str, std::string("None")) == 1)
					{
						custom_calls[call_name].strip_chars_action = 0;
					}
					else
					{
						#ifdef DEBUG_TESTING
							extension_ptr->console->warn("extDB2: SQL_CUSTOM: Invalid Strip Chars Action: {0}", strip_chars_action_str);
						#endif
						extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Invalid Strip Chars Action: {0}", strip_chars_action_str);
						custom_calls[call_name].strip_chars_action = 1;
					}
				}
				else
				{
					custom_calls[call_name].strip_chars_action = default_strip_chars_action;
				}
				
				custom_calls[call_name].strip = template_ini->getBool(call_name + ".Strip", default_strip);
				custom_calls[call_name].strip_custom_input_chars = template_ini->getString(call_name + ".Strip Custom Chars", default_strip_custom_input_chars);
				custom_calls[call_name].strip_chars = template_ini->getString(call_name + ".Strip Chars", default_strip_chars);

				while (true)
				{
					// Prepared Statement
					++sql_line_num;
					sql_line_num_str = Poco::NumberFormatter::format(sql_line_num);

					if (!(template_ini->has(call_name + ".SQL" + sql_line_num_str + "_1")))  // No More SQL Statements
					{
						// Initialize Default Output Options

						// Get Output Options
						Poco::StringTokenizer tokens_output_options((template_ini->getString(call_name + ".OUTPUT", "")), ",", Poco::StringTokenizer::TOK_TRIM);

						for (int i = 0; i < (tokens_output_options.count()); ++i)
						{
							Value_Options outputs_options;
							outputs_options.check =  template_ini->getBool(call_name + ".Sanitize Output Value Check", default_output_sanitize_value_check);

							Poco::StringTokenizer options_tokens(tokens_output_options[i], "-", Poco::StringTokenizer::TOK_TRIM);
							for (int x = 0; x < (options_tokens.count()); ++x)
							{
								int temp_int;
								if (Poco::NumberParser::tryParse(options_tokens[x], temp_int))
								{
									outputs_options.number = temp_int;
								}
								else
								{
									if (boost::iequals(options_tokens[x], std::string("String")) == 1)
									{
										outputs_options.string = true;
									}
									else if (boost::iequals(options_tokens[x], std::string("BOOL")) == 1)
									{
										outputs_options.boolean = true;
									}
									else if (boost::iequals(options_tokens[x], std::string("BeGUID")) == 1)
									{
										outputs_options.beguid = true;
									}
									else if (boost::iequals(options_tokens[x], std::string("Check")) == 1)
									{
										outputs_options.check = true;
									}
									else if (boost::iequals(options_tokens[x], std::string("NoCheck")) == 1)
									{
										outputs_options.check = false;
									}
									else if (boost::iequals(options_tokens[x], std::string("Strip")) == 1)
									{
										outputs_options.strip = true;
									}
									else if (boost::iequals(options_tokens[x], std::string("NoStrip")) == 1)
									{
										outputs_options.strip = false;
									}
									else if (boost::iequals(options_tokens[x], std::string("Vac_BeGUID")) == 1)
									{
										outputs_options.vac_beguid = true;
									}
									else if (boost::iequals(options_tokens[x], std::string("Vac_SteamID")) == 1)
									{
										outputs_options.vac_steamID = true;
									}
									else
									{
										status = false;
										#ifdef DEBUG_TESTING
											extension_ptr->console->warn("extDB2: SQL_CUSTOM: Invalid Strip Output Option: {0}: {1}", call_name, options_tokens[x]);
										#endif
										extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Invalid Strip Output Option: {0}: {1}", call_name, options_tokens[x]);
									}
								}
							}
							custom_calls[call_name].sql_outputs_options.push_back(std::move(outputs_options));
						}
						break;
					}
					
					std::string sql_str;
					sql_part_num = 0;
					while (true)
					{
						++sql_part_num;
						sql_part_num_str = Poco::NumberFormatter::format(sql_part_num);							
						if (!(template_ini->has(call_name + ".SQL" + sql_line_num_str + "_" + sql_part_num_str)))
						{
							break;
						}
						sql_str += (template_ini->getString(call_name + ".SQL" + sql_line_num_str + "_" + sql_part_num_str)) + " " ;		
					}

					if (sql_part_num > 1) // Remove trailing Whitespace
					{
						sql_str = sql_str.substr(0, sql_str.size()-1);
					}

					custom_calls[call_name].sql_prepared_statements.push_back(std::move(sql_str));
					custom_calls[call_name].sql_inputs_options.push_back(std::vector < Value_Options >());

					// Get Input Options
					Poco::StringTokenizer tokens_input(template_ini->getString((call_name + ".SQL" + sql_line_num_str + "_INPUTS"), ""), ",");
					for (auto &token_input : tokens_input)
					{
						// Initialize Default Input Options
						Value_Options inputs_options;
						inputs_options.check =  template_ini->getBool(call_name + ".Sanitize Input Value Check", default_input_sanitize_value_check);
						
						Poco::StringTokenizer tokens_input_options(token_input, "-");
						for (auto &sub_token_input : tokens_input_options)
						{
							int temp_int;
							if (Poco::NumberParser::tryParse(sub_token_input, temp_int))
							{
								inputs_options.number = temp_int;
							}
							else
							{
								if (boost::iequals(sub_token_input, std::string("String")) == 1)
								{
									inputs_options.string = true;
								}
								else if (boost::iequals(sub_token_input, std::string("BeGUID")) == 1)
								{
									inputs_options.beguid = true;
								}
								else if (boost::iequals(sub_token_input, std::string("BOOL")) == 1)
								{
									inputs_options.boolean = true;
								}
								else if (boost::iequals(sub_token_input, std::string("Check")) == 1)
								{
									inputs_options.check = true;
								}
								else if (boost::iequals(sub_token_input, std::string("NoCheck")) == 1)
								{
									inputs_options.check = false;
								}
								else if (boost::iequals(sub_token_input, std::string("Strip")) == 1)
								{
									inputs_options.strip = true;
								}
								else if (boost::iequals(sub_token_input, std::string("NoStrip")) == 1)
								{
									inputs_options.strip = false;
								}
								else if (boost::iequals(sub_token_input, std::string("Vac_BeGUID")) == 1)
								{
									inputs_options.vac_beguid = true;
								}
								else if (boost::iequals(sub_token_input, std::string("Vac_SteamID")) == 1)
								{
									inputs_options.vac_steamID = true;
								}
								else
								{
									status = false;
									#ifdef DEBUG_TESTING
										extension_ptr->console->warn("extDB2: SQL_CUSTOM: Invalid Strip Input Option: {0}: {1}", call_name, sub_token_input);
									#endif
									extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Invalid Strip Input Option: {0}: {1}", call_name, sub_token_input);
								}
							}
						}
						custom_calls[call_name].sql_inputs_options[sql_line_num - 1].push_back(std::move(inputs_options));
					}
				}
			}
		}
		else
		{
			status = false;
			#ifdef DEBUG_TESTING
				extension_ptr->console->warn("extDB2: SQL_CUSTOM: Incompatible Version: {0} Required: {1}", (template_ini->getInt("Default.Version", 1)), EXTDB_SQL_CUSTOM_REQUIRED_VERSION);
			#endif
			extension_ptr->logger->warn("extDB2: SQL_CUSTOM: Incompatible Version: {0} Required: {1}", (template_ini->getInt("Default.Version", 1)), EXTDB_SQL_CUSTOM_REQUIRED_VERSION);
		}
	}
	return status;
}