using System; using System.Data; using System.Data.OleDb; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace ThinkGeo.MapSuite.MapSuiteGeocoderExtension { internal class DbfManager { private string dbfPahtFileName; public DbfManager(string dbfPahtFileName) { this.dbfPahtFileName = dbfPahtFileName; } public DataTable ExecuteQuery(string sqlStatement) { DataTable dataTable = new DataTable(); dataTable.Locale = CultureInfo.InvariantCulture; OleDbCommand oleDbCommand = null; OleDbDataAdapter adapter = null; try { sqlStatement = ReplaceTableName(sqlStatement); oleDbCommand = GetOleDbCommand(sqlStatement); adapter = new OleDbDataAdapter(oleDbCommand); adapter.Fill(dataTable); } finally { if (oleDbCommand != null) { oleDbCommand.Dispose(); } if (adapter != null) { adapter.Dispose(); } } return dataTable; } private OleDbCommand GetOleDbCommand(string sqlStatement) { OleDbConnection connection; if (Environment.Is64BitProcess) { connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path.GetDirectoryName(dbfPahtFileName) + "\\;Extended Properties=dBASE IV;User ID=Admin;Password="); } else { connection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path.GetDirectoryName(dbfPahtFileName) + "\\;Extended Properties=dBASE IV;User ID=Admin;Password="); } if (connection.State != ConnectionState.Open) { connection.Open(); } return new OleDbCommand(sqlStatement, connection); } private string ReplaceTableName(string sqlStatement) { sqlStatement += " "; string shortName = GetShortFileName(dbfPahtFileName); string sourceFileNameWithoutExtension = Path.GetFileNameWithoutExtension(dbfPahtFileName).ToUpperInvariant(); string shortNameWithoutExtension = Path.GetFileNameWithoutExtension(shortName); int position = sqlStatement.IndexOf(sourceFileNameWithoutExtension, StringComparison.OrdinalIgnoreCase); string tableName = sqlStatement.Substring(position, sourceFileNameWithoutExtension.Length); string substringIncludeTableName = sqlStatement.Substring(0, position + tableName.Length); sqlStatement = sqlStatement.Replace(substringIncludeTableName, substringIncludeTableName.Replace(tableName, shortNameWithoutExtension)); if (!sqlStatement.Contains(" [" + shortNameWithoutExtension + "] ")) { sqlStatement = sqlStatement.Replace(" " + shortNameWithoutExtension + " ", " [" + shortNameWithoutExtension + "] "); } return sqlStatement; } private static string GetShortFileName(string pathFileName) { StringBuilder sb = new StringBuilder(1024); UnsafeNativeMethods.GetShortPathName(pathFileName, sb, sb.Capacity); string shortPath = sb.ToString(); //TODO: whether throw exception if short path is empty return shortPath; } } internal static class UnsafeNativeMethods { //TODo check this method works fine in chinese string. [DllImport("kernel32", EntryPoint = "GetShortPathNameA", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)] internal static extern int GetShortPathName(string lpszLongPath, StringBuilder lpszShortPath, int cchBuffer); } }