Example #1
0
/**

 	PREPARSE_execute

    @brief

    @param status
    @param ptrAtt
    @param stmt_length
    @param stmt
    @param stmt_eaten
    @param dialect

 **/
bool PREPARSE_execute(CheckStatusWrapper* status, Why::YAttachment** ptrAtt,
					  USHORT stmt_length, const SCHAR* stmt, bool* stmt_eaten, USHORT dialect)
{
	// no use creating separate pool for a couple of strings
	ContextPoolHolder context(getDefaultMemoryPool());

	try
	{
		if (!stmt)
		{
			Arg::Gds(isc_command_end_err).raise();
		}

		Tokens tks;
		tks.quotes(quotes);
		tks.parse(stmt_length, stmt);
		unsigned pos = 0;

		if (getToken(pos, tks) != pp_symbols[PP_CREATE].symbol)
		{
			return false;
		}

		NoCaseString token(getToken(pos, tks));
		if (token != pp_symbols[PP_DATABASE].symbol && token != pp_symbols[PP_SCHEMA].symbol)
		{
			return false;
		}

		PathName file_name(getToken(pos, tks, STRING).ToPathName());
		*stmt_eaten = false;
		ClumpletWriter dpb(ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1);

		dpb.insertByte(isc_dpb_overwrite, 0);
		dpb.insertInt(isc_dpb_sql_dialect, dialect);

		SLONG page_size = 0;
		bool matched;
		do {
			try
			{
				token = getToken(pos, tks);
			}
			catch (const Exception&)
			{
				*stmt_eaten = true;
				break;
			}

			matched = false;
			for (int i = 3; pp_symbols[i].symbol[0] && !matched; i++)
			{
				if (token == pp_symbols[i].symbol)
				{
					// CVC: What's strange, this routine doesn't check token.length()
					// but it proceeds blindly, trying to exhaust the token itself.

					switch (pp_symbols[i].code)
					{
					case PP_PAGE_SIZE:
					case PP_PAGESIZE:
						token = getToken(pos, tks);
						if (token == "=")
							token = getToken(pos, tks, NUMERIC);

						page_size = atol(token.c_str());
						dpb.insertInt(isc_dpb_page_size, page_size);
						matched = true;
						break;

					case PP_USER:
						token = getToken(pos, tks);

						dpb.insertString(isc_dpb_user_name, token.ToString());
						matched = true;
						break;

					case PP_PASSWORD:
						token = getToken(pos, tks, STRING);

						dpb.insertString(isc_dpb_password, token.ToString());
						matched = true;
						break;

					case PP_ROLE:
						token = getToken(pos, tks);

						dpb.insertString(isc_dpb_sql_role_name, token.ToString());
						matched = true;
						break;

					case PP_SET:
						token = getToken(pos, tks);
						if (token != pp_symbols[PP_NAMES].symbol)
							generate_error(token, UNEXPECTED_TOKEN);
						token = getToken(pos, tks, STRING);

						dpb.insertString(isc_dpb_lc_ctype, token.ToString());
						matched = true;
						break;

					case PP_LENGTH:
						token = getToken(pos, tks);
						if (token == "=")
							token = getToken(pos, tks, NUMERIC);

						// Skip a token for value
						matched = true;
						break;

					case PP_PAGE:
					case PP_PAGES:
						matched = true;
						break;
					} // switch
				} // if
			} // for
		} while (matched);

		RefPtr<Why::Dispatcher> dispatcher(new Why::Dispatcher);
		*ptrAtt = dispatcher->createDatabase(status, file_name.c_str(),
			dpb.getBufferLength(), dpb.getBuffer());
	}
	catch (const Exception& ex)
	{
		ex.stuffException(status);
		return true;
	}

	return true;
}