Exemplo n.º 1
0
        /// <summary>
        /// Creates a new OlsonParser to parse the provided
        /// Olson/TZ Database directory into Rules
        /// and TimeZones. The directory provided must be a valid TZ Database.
        /// </summary>
        /// <param name="timeZoneDataTable">The TimeZone DataTable containign the schema to retrieve new rows from.</param>
        /// <param name="ruleDataTable">The Rule DataTable containign the schema to retrieve new rows from.</param>
        /// <param name="leapDataTable">The Leap DataTable containign the schema to retrieve new rows from.</param>
        /// <param name="directoryPath">The valid directory to parse Rules and TimeZones from.</param>
        /// <exception cref="System.Security.SecurityException">The caller does not have the required permission. </exception>
        /// <exception cref="System.ArgumentException">directoryPath contains invalid characters such as ", <, >, or |. </exception>
        /// <exception cref="System.IO.PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length.
        /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters.
        /// The specified path, file name, or both are too long.</exception>
        public OlsonParser(System.Data.DataTable timeZoneDataTable,
                           System.Data.DataTable ruleDataTable,
                           System.Data.DataTable leapDataTable,
                           OlsonDirectoryInfo files)
        {
            Directory = files;

            _olsonFiles = files.ValidOlsonFiles;
            _isoFile    = files.IsoFile;
            _zoneFile   = files.ZoneFile;

            ParsedEntries = 0;

            TimeZones     = timeZoneDataTable;
            _timeZoneRows = TimeZones.Rows;

            Rules     = ruleDataTable;
            _ruleRows = Rules.Rows;

            Leaps     = leapDataTable;
            _leapRows = Leaps.Rows;

            _links = new List <string[]>();
            TimeZoneLookupTable = new ConcurrentDictionary <string, System.Data.DataRow>(System.Environment.ProcessorCount, 450);

            _curYear = System.DateTime.Now.Year;

            // Pre-compiled regex for faster matching. Fields are separated from one another by any number of white space characters.
            _regex = new Regex(@"\s+", RegexOptions.Compiled);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Instantiates and begins parsing the geonames and olson databases.
        /// </summary>
        public void BeginParsing()
        {
            RaiseParsingStarted();

            ProgressText = "Verifying directories";

            _olsonDirectoryInfo = new OlsonDirectoryInfo(Settings.Default.OlsonPath);
            bool isValidOlsonDir = _olsonDirectoryInfo.IsValid;

            _geonamesDirectoryInfo = new GeonamesDirectoryInfo(Settings.Default.GeonamesPath);
            bool isValidGeonamesDir = _geonamesDirectoryInfo.IsValid;

            if (!isValidOlsonDir && !isValidGeonamesDir)
            {
                // No need to lock, because only 1 thread accessing this. (UI Thread never accesses [Only creates it in app.xaml.cs])
                App.ExceptionLogger.LogMedium(new InvalidDirectoryException("You must provide a valid Geonames directory, Olson directory, or both."));
                RaiseParsingFinished(new ParsingFinishedEventArgs(ParsingResult.Failure));
                return;
            }

            ProgressText = "Validating connection string";

            using (SqlConnection conTest = new SqlConnection(ConnectionString))
            {
                try
                {
                    conTest.Open();
                }
                catch (System.Exception e)
                {
                    App.ExceptionLogger.LogMedium(e);
                    RaiseParsingFinished(new ParsingFinishedEventArgs(ParsingResult.Failure));
                    return;
                }
            }

            _dbTools = new WorlTimeDatabaseTools(_conStrBuilder);

            TaskFactory f = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None);

            Task stage1 = f.StartNew(() => PopulateFiles(isValidGeonamesDir, isValidOlsonDir));

            Task stage3 = null;
            Task stage4 = null;
            Task stage5 = null;

            if (isValidOlsonDir)
            {
                _olsonParser = new OlsonParser(_dbTools.GetTimeZoneDataTable(), _dbTools.GetRuleDataTable(), _dbTools.GetLeapDataTable(), _olsonDirectoryInfo);

                _olsonParser.FileParsing += OnParserFileParsing;

                _olsonParser.FileParsed += (s, e) => ProgressValue++;

                _timeZoneLookUpTable = _olsonParser.TimeZoneLookupTable;

                ProgressText = "Creating Olson database tables";
                _dbTools.CreateOlsonDatabaseTables();

                Task stage2 = f.StartNew(
                    () =>
                {
                    ProgressText = "Parsing Olson database files";
                    _olsonParser.ReadTZDirectory();
                });
                Task.WaitAll(stage2);

                stage3 = f.StartNew(
                    () =>
                {
                    ProgressText = "Uploading TimeZones";
                    BulkCopy(_olsonParser.TimeZones, false);
                    ProgressText = "TimeZones successfully uploaded";
                });
                stage4 = f.StartNew(
                    () =>
                {
                    ProgressText = "Uploading Rules";
                    BulkCopy(_olsonParser.Rules, false);
                    ProgressText = "Rules successfully uploaded";
                });
                stage5 = f.StartNew(
                    () =>
                {
                    ProgressText = "Uploading Leaps";
                    BulkCopy(_olsonParser.Leaps, false);
                    ProgressText = "Leaps succesfully uploaded";
                });
            }

            Task stage6 = null;

            if (isValidGeonamesDir)
            {
                DataTable cityTable = _dbTools.GetCityDataTable();

                _geonamesParser = new GeonamesParser(_dbTools.GetFeatureCodeDataTable(), _geonamesDirectoryInfo);

                stage6 = f.StartNew(
                    () =>
                {
                    ProgressMaximum++;
                    ProgressText           = "Parsing geonames featurecodes file";
                    DataTable featureCodes = _geonamesParser.ReadFeatureCodesFile();
                    ProgressText           = "Uploading geonames featurecodes file";
                    BulkCopy(featureCodes);
                });

                _geonamesParser.EntryParsed +=
                    (s, e) =>
                {
                    object[] cityValues = e.DatabaseEntry;
                    DataRow  timeZone;

                    string timeZoneName = (string)cityValues[19];
                    if (_timeZoneLookUpTable.TryGetValue(timeZoneName, out timeZone))
                    {
                        cityValues[18] = timeZone[0];
                        lock (_cityTableLock)
                        {
                            cityTable.Rows.Add(cityValues);
                        }
                    }
                    else
                    {
                        App.ExceptionLogger.LogLow(new System.Exception("Could not get the ID for the City: "
                                                                        + (string)cityValues[1] + " with TimeZoneName " + timeZoneName));
                    }
                };

                _geonamesParser.FileParsing += OnParserFileParsing;

                System.Action <FileParseEventArgs> BatchParsed =
                    (e) =>
                {
                    string name = e.ParsedFile.Name;
                    ProgressText = "Uploading File " + name;
                    lock (_cityTableLock)
                    {
                        BulkCopy(cityTable);
                        cityTable.Rows.Clear();
                    }
                    ProgressText = name + " successfully uploaded";
                };

                _geonamesParser.FileParsed += (s, e) => BatchParsed(e);

                ProgressText = "Creating Geonames database table";
                _dbTools.CreateGeonamesDatabaseTables();

                ProgressText = "Parsing Geonames city files";
                _geonamesParser.ReadCityFiles();
            }

            Task.WaitAll(stage1);

            if (isValidOlsonDir)
            {
                Task.WaitAll(stage3, stage4, stage5);
            }

            if (isValidGeonamesDir)
            {
                Task.WaitAll(stage6);
            }

            RaiseParsingFinished(new ParsingFinishedEventArgs(ParsingResult.Success));
        }