Пример #1
0
/*----------------------------------------------------------------------------------------------
	Initialize the database.
----------------------------------------------------------------------------------------------*/
void InitializeDB(const wchar * pszwServer, const wchar * pszwDB, const char * pszInitScript)
{
	SqlDb sdb;
	SqlStatement sstmt;
	HRESULT hr;
	char * pszCmd;
	char * psz;
	char * pchEnd;
	int chLeading;
	int chTrailing;
	Vector<char> vchScript;
	FILE * pfile;
	RETCODE rc;
	struct stat statInit;

	// osql -U sa -E -n -b -d %1 <%SQLSCRIPT%

	if (stat(pszInitScript, &statInit))
	{
		fprintf(stderr, "Cannot open Initialization SQL file \"%s\"!\n", pszInitScript);
		ThrowHr(WarnHr(E_FAIL));
	}
	vchScript.Resize(statInit.st_size + 1);
	pfile = fopen(pszInitScript, "rb");
	if (!pfile)
	{
		fprintf(stderr, "Cannot open Initialization SQL file \"%s\"!\n", pszInitScript);
		ThrowHr(WarnHr(E_FAIL));
	}
	fread(vchScript.Begin(), 1, statInit.st_size, pfile);
	fclose(pfile);
	pchEnd = vchScript.Begin() + statInit.st_size;
	*pchEnd = '\0';

	hr = sdb.Open(pszwServer, pszwDB);
	CheckHr(hr);
	sstmt.Init(sdb);

	// This is needed to allow double quotes in dynamic SQL, which is used by some of the
	// stored procedures that FieldWorks defines.
	pszCmd = "SET QUOTED_IDENTIFIER OFF";
	rc = SQLExecDirectA(sstmt.Hstmt(), reinterpret_cast<SQLCHAR *>(pszCmd), SQL_NTS);
	VerifySqlRc(rc, sstmt.Hstmt(), pszCmd);
	sstmt.Clear();

	// Find next "go" keyword, if any.
	// Note that we have to skip over any comments or quoted strings while searching.
	// Also we need to convert non-embedded double quotes to single quotes.
	bool fSingleQuoted;
	bool fDoubleQuoted;
	char * pszOpen;
	bool fInLineComment;
	bool fInsideComment;
	int ch;
	int ch2;
	for (pszCmd = vchScript.Begin(); pszCmd < pchEnd; pszCmd = psz)
	{
		// Skip leading whitespace.
		pszCmd += strspn(pszCmd, " \t\r\n\f\v");
		if (pszCmd == pchEnd)
			break;
		fSingleQuoted = false;
		fDoubleQuoted = false;
		pszOpen = NULL;
		fInLineComment = false;
		fInsideComment = false;
		for (psz = pszCmd; psz < pchEnd; ++psz)
		{
			ch = *psz;
			ch2 = *(psz + 1);
			if (fInLineComment)
			{
				if (ch == '\n')
					fInLineComment = false;
				continue;
			}
			if (fInsideComment)
			{
				if (ch == '*' && ch2 == '/')
				{
					fInsideComment = false;
					++psz;
				}
				continue;
			}
			if (!fSingleQuoted && !fDoubleQuoted)
			{
				if (ch == '-' && ch2 == '-')
				{
					fInLineComment = true;
					++psz;
					continue;
				}
				else if (ch == '/' && ch2 == '*')
				{
					fInsideComment = true;
					++psz;
					continue;
				}
			}
			if (ch == '\'')
			{
				if (fSingleQuoted)
				{
					fSingleQuoted = false;
				}
				else if (fDoubleQuoted)
				{
					// Retain outer double quotes if embedded single quote.
					pszOpen = NULL;
				}
				else
				{
					fSingleQuoted = true;
				}
			}
			else if (ch == '"')
			{
				if (fSingleQuoted)
				{
					// Do nothing. (?)
				}
				else if (fDoubleQuoted)
				{
					if (pszOpen)
					{
						// Convert double quotes to single quotes if not embedded.
						*pszOpen = '\'';
						*psz = '\'';
						pszOpen = NULL;
					}
					fDoubleQuoted = false;
				}
				else
				{
					fDoubleQuoted = true;
					pszOpen = psz;
				}
			}
			else if ((ch == 'g' || ch == 'G') && (ch2 == 'o' || ch2 == 'O') &&
				!fSingleQuoted && !fDoubleQuoted)
			{
				chLeading = (psz > pszCmd) ? *(psz - 1) : ' ';
				chTrailing = (psz + 2 < pchEnd) ? *(psz + 2) : ' ';
				if (isascii(chLeading) && isspace(chLeading) &&
					isascii(chTrailing) && isspace(chTrailing))
				{
					*psz = '\0';
					psz += 2;
					break;
				}
			}
		}

		sstmt.Init(sdb);
		rc = SQLExecDirectA(sstmt.Hstmt(), reinterpret_cast<SQLCHAR *>(pszCmd), strlen(pszCmd));
		VerifySqlRc(rc, sstmt.Hstmt(), pszCmd);
		sstmt.Clear();
	}
	sdb.Close();
}
Пример #2
0
/*----------------------------------------------------------------------------------------------
	Create the database.  Return 0 if successful, or a nonzero value if an error occurs.
----------------------------------------------------------------------------------------------*/
int CreateDB(const char * pszServer, const char * pszDB, const char * pszOutputDir,
	const char * pszInitScript,	bool fForceCreate)
{
	HRESULT hr;

	static const wchar szwMaster[] = L"master";
	StrUniBuf stubServer(pszServer);
	StrUniBuf stubDatabase(pszDB);

	if (stubServer.Overflow() || stubDatabase.Overflow())
	{
		fprintf(stderr, "Out of memory filling static buffers??\n");
		return __LINE__;
	}
	try
	{
		SqlDb sdb;
		SqlStatement sstmt;
		StrAnsiBufBig stabCmd;
		hr = sdb.Open(stubServer.Chars(), stubDatabase.Chars());
		if (SUCCEEDED(hr))
		{
			sdb.Close();
			if (fForceCreate)
			{
				// osql /U sa /E /n /b /Q "DROP DATABASE %1"
				hr = sdb.Open(stubServer.Chars(), szwMaster);
				if (FAILED(hr))
					ThrowHr(WarnHr(hr));
				sstmt.Init(sdb);
				stabCmd.Format("DROP DATABASE %s", pszDB);
				RETCODE rc;
				rc = SQLExecDirectA(sstmt.Hstmt(),
					reinterpret_cast<SQLCHAR *>(const_cast<char *>(stabCmd.Chars())), SQL_NTS);
				VerifySqlRc(rc, sstmt.Hstmt(), stabCmd.Chars());
				sstmt.Clear();
				sdb.Close();
			}
			else
			{
				fprintf(stderr, "The database \"%s\" already exists on the server \"%s\".\n",
					pszDB, pszServer);
				fprintf(stderr,
					"Use the -f command line flag to force recreating this database.\n");
				return 1;
			}
		}
		// osql -U sa -E -n -b -Q "CREATE DATABASE %1 ON
		// (NAME=%1,FILENAME='%OUTPUT_DIR%\%1.mdf',FILEGROWTH=5MB) LOG ON
		// (NAME='%1_Log', FILENAME='%OUTPUT_DIR%\%1_log.ldf',FILEGROWTH=5MB)"
		hr = sdb.Open(stubServer.Chars(), szwMaster);
		CheckHr(hr);
		sstmt.Init(sdb);
		if (pszOutputDir)
			stabCmd.Format("CREATE DATABASE %s ON (NAME='%s',FILENAME='%s\\%s.mdf') \
LOG ON (NAME='%s_Log',FILENAME='%s\\%s_log.ldf')",
			pszDB, pszDB, pszOutputDir, pszDB, pszDB, pszOutputDir, pszDB);
		else
			stabCmd.Format("CREATE DATABASE %s ", pszDB);

		RETCODE rc;
		rc = SQLExecDirectA(sstmt.Hstmt(),
			reinterpret_cast<SQLCHAR *>(const_cast<char *>(stabCmd.Chars())), SQL_NTS);
		VerifySqlRc(rc, sstmt.Hstmt(), stabCmd.Chars());
		sstmt.Clear();
		sdb.Close();
		if (pszInitScript)
		{
			InitializeDB(stubServer.Chars(), stubDatabase.Chars(), pszInitScript);
		}
	}
	catch (Throwable & thr)
	{
		fprintf(stderr, "Error %s caught creating database \"%s\" on server \"%s\"!\n",
			AsciiHresult(thr.Error()), pszDB, pszServer);
		return __LINE__;
	}
	catch (...)
	{
		fprintf(stderr, "Error caught creating database \"%s\" on server \"%s\"!\n",
			pszDB, pszServer);
		return __LINE__;
	}
	return 0;
}