public MetadataIndexViewModel SearchMetadata(string organizationName, string searchString, int offset, int limit)
        {
            SearchResultsType results = null;

            if (!string.IsNullOrWhiteSpace(organizationName))
            {
                if (!string.IsNullOrWhiteSpace(searchString))
                {
                    results = _geoNorge.SearchFreeTextWithOrganisationName(searchString, organizationName, offset, limit);
                }
                else
                {
                    results = _geoNorge.SearchWithOrganisationName(organizationName, offset, limit, true);
                }
            }
            else
            {
                results = _geoNorge.Search(searchString, offset, limit, true);
            }
            var model = ParseSearchResults(offset, limit, results);

            model.SearchOrganization = organizationName;
            model.SearchString       = searchString;

            return(model);
        }
        public string BuildSearchQueryString(int pageNumber)
        {
            var query  = $"/search?q={SearchTerm}";
            var paramz = new List <string>();

            if (SearchResultsType != SearchResultsType.All)
            {
                paramz.Add("t=" + SearchResultsType.ToString().ToLower());
            }

            if (pageNumber > 1)
            {
                paramz.Add("p=" + pageNumber);
            }

            if (QuerySortBy != QuerySortBy.DateCreated)
            {
                paramz.Add("s=" + QuerySortBy.ToString().ToLower());
            }

            if (QueryRange != QueryRange.Forever)
            {
                paramz.Add("r=" + QueryRange.ToString().ToLower());
            }

            if (paramz.Count == 0)
            {
                return(query);
            }

            query += "&" + string.Join('&', paramz);
            return(query);
        }
Example #3
0
        public List <MetadataEntry> CheckDownload()
        {
            metadataSets = GetDatasets();
            CheckDatasets();

            return(downloadProblems);
        }
        public MetadataIndexViewModel GetAllMetadata(string searchString, int offset, int limit)
        {
            SearchResultsType results = _geoNorge.Search(searchString, offset, limit, true);
            var model = ParseSearchResults(offset, limit, results);

            model.SearchString = searchString;
            return(model);
        }
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
        {
            MetadataViewModel model = Resources["MetadataModel"] as MetadataViewModel;

            if (model != null)
            {
                SearchResultsType results = (SearchResultsType)args.Result;

                model.Metadata.Clear();

                if (results.Items != null)
                {
                    foreach (var item in results.Items)
                    {
                        RecordType record = (RecordType)item;

                        string title   = null;
                        string uri     = null;
                        string uuid    = null;
                        string creator = null;

                        for (int i = 0; i < record.ItemsElementName.Length; i++)
                        {
                            var name  = record.ItemsElementName[i];
                            var value = record.Items[i].Text != null ? record.Items[i].Text[0] : null;

                            if (name == ItemsChoiceType24.title)
                            {
                                title = value;
                            }
                            else if (name == ItemsChoiceType24.URI && value != null && value.StartsWith("http"))
                            {
                                uri = value;
                            }
                            else if (name == ItemsChoiceType24.identifier)
                            {
                                uuid = value;
                            }
                            else if (name == ItemsChoiceType24.creator)
                            {
                                creator = value;
                            }
                        }
                        model.Metadata.Add(new Metadata {
                            Title = title, Uri = uri, Uuid = uuid, Creator = creator
                        });
                    }
                    lblStatus.Content = "Showing " + results.numberOfRecordsReturned + " of total " + results.numberOfRecordsMatched + " matches.";
                }
                else
                {
                    lblStatus.Content = "No match!";
                }
            }
        }
        //[Route("dataset/{parentRegister}/{registerowner}/{registername}/ny")]
        //[Route("dataset/{registername}/ny")]
        public ActionResult Create(Dataset dataset, string registername, string metadataUuid, string parentRegister, string registerowner, string searchString)
        {
            dataset.register = _registerService.GetRegister(parentRegister, registername);
            if (dataset.register != null)
            {
                if (_accessControlService.Access(dataset.register))
                {
                    dataset.systemId    = dataset.GetSystemId();
                    dataset.registerId  = dataset.register.GetSystemId();
                    dataset.DatasetType = dataset.GetDatasetType();

                    if (!string.IsNullOrEmpty(searchString))
                    {
                        SearchResultsType result = SearchMetadataFromKartkatalogen(searchString);
                        var resList = ParseSearchResult(result);
                        if (resList.Count == 0)
                        {
                            ViewBag.Message = "Søket gav ingen treff";
                        }
                        ViewBag.SearchResultList = resList;
                    }
                    else if (!string.IsNullOrEmpty(metadataUuid))
                    {
                        Dataset model = GetMetadataFromKartkatalogen(dataset, metadataUuid);
                        Viewbags(dataset);
                        return(View(model));
                    }
                    else if (!string.IsNullOrWhiteSpace(dataset.name))
                    {
                        if (!NameIsValid(dataset))
                        {
                            ModelState.AddModelError("ErrorMessage", HtmlHelperExtensions.ErrorMessageValidationDataset());
                            Viewbags(dataset);
                            return(View(dataset));
                        }
                        if (ModelState.IsValid)
                        {
                            dataset = GetMetadataFromKartkatalogen(dataset, dataset.Uuid);
                            dataset = _datasetService.UpdateDataset(dataset);
                            dataset.StatusHistories = _statusReportService.GetStatusHistoriesByDataset(dataset);
                            _registerItemService.SaveNewRegisterItem(dataset);
                            return(Redirect(dataset.GetObjectUrl()));
                        }
                    }
                }
                else
                {
                    throw new HttpException(401, "Access Denied");
                }
            }
            Viewbags(dataset);
            return(View(dataset));
        }
Example #7
0
        public void ShouldCrawlAndIndexAllMetadataFromGeonorge()
        {
            var geoNorgeMock      = new Mock <IGeoNorge>();
            var firstSearchResult = new SearchResultsType
            {
                Items = new object[] { CreateDummyMetadata(), CreateDummyMetadata() },
                numberOfRecordsMatched = "55",
                nextRecord             = "51",
            };

            var secondSearchResult = new SearchResultsType
            {
                Items = new object[] { CreateDummyMetadata(), CreateDummyMetadata(), CreateDummyMetadata(), CreateDummyMetadata(), CreateDummyMetadata() },
                numberOfRecordsMatched  = "55",
                numberOfRecordsReturned = "5",
                nextRecord = "56",
            };

            geoNorgeMock.Setup(g => g.SearchIso("", 1, 50, false)).Returns(firstSearchResult);
            geoNorgeMock.Setup(g => g.SearchIso("", 51, 50, false)).Returns(secondSearchResult);

            var indexerMock    = new Mock <Indexer>();
            var indexerMockAll = new Mock <IndexerAll>();
            var indexerAppMock = new Mock <IndexerApplication>();
            var indexerSerMock = new Mock <IndexerService>();

            var indexDocumentCreator = new Mock <IndexDocumentCreator>();
            var culture   = Culture.NorwegianCode;
            var indexDocs = new List <MetadataIndexDoc>();

            indexDocs.Add(new MetadataIndexDoc {
                Uuid = "12345-123545-1231245-1231238"
            });
            indexDocs.Add(new MetadataIndexDoc {
                Uuid = "12345-123545-1231245-1231239"
            });

            var errorMock = new Mock <IErrorService>();

            indexDocumentCreator.Setup(i => i.CreateIndexDocs(It.IsAny <object[]>(), geoNorgeMock.Object, culture)).Returns(indexDocs);

            var indexer = new SolrMetadataIndexer(geoNorgeMock.Object, indexerMock.Object, indexerAppMock.Object, indexerSerMock.Object, indexDocumentCreator.Object, errorMock.Object, indexerMockAll.Object);

            indexer.RunIndexing();

            geoNorgeMock.Verify(g => g.SearchIso("", 1, 50, false));
            geoNorgeMock.Verify(g => g.SearchIso("", 51, 50, false));

            indexerMock.Verify(i => i.Index(indexDocs[0]));
            indexerMock.Verify(i => i.Index(indexDocs[1]));
        }
        // *** HJELPEMETODER

        private List <MetadataItemViewModel> ParseSearchResult(SearchResultsType res)
        {
            List <MetadataItemViewModel> result = new List <MetadataItemViewModel>();

            if (res.numberOfRecordsMatched != "0")
            {
                for (int s = 0; s < res.Items.Length; s++)
                {
                    MetadataItemViewModel m = new MetadataItemViewModel();
                    m.Uuid  = ((DCMIRecordType)(res.Items[s])).Items[0].Text[0];
                    m.Title = ((DCMIRecordType)(res.Items[s])).Items[2].Text[0];
                    result.Add(m);
                }
            }

            return(result);
        }
        private void WorkerOnDoWork(object sender, DoWorkEventArgs args)
        {
            string[] arguments    = (string[])args.Argument;
            string   freeText     = arguments[0];
            string   organisation = arguments[1];

            SearchResultsType results = null;

            if (!string.IsNullOrWhiteSpace(organisation))
            {
                results = _geonorgeApi.SearchFreeTextWithOrganisationName(freeText, organisation);
            }
            else
            {
                results = _geonorgeApi.Search(freeText);
            }
            args.Result = results;
        }
Example #10
0
        public void ShouldSearchAndIndexTwoMetadataEntriesFromGeonorge()
        {
            var geoNorgeMock = new Mock <IGeoNorge>();
            var searchResult = new SearchResultsType
            {
                Items = new object[] { CreateDummyMetadata(), CreateDummyMetadata() },
                numberOfRecordsMatched = "2",
                nextRecord             = "51",
            };

            geoNorgeMock.Setup(g => g.SearchIso("", 1, 50, false)).Returns(searchResult);

            var indexerMock    = new Mock <Indexer>();
            var indexerMockAll = new Mock <IndexerAll>();
            var indexerAppMock = new Mock <IndexerApplication>();
            var indexerSerMock = new Mock <IndexerService>();

            var indexDocumentCreator = new Mock <IndexDocumentCreator>();
            var indexDocs            = new List <MetadataIndexDoc>();
            var culture = Culture.NorwegianCode;

            indexDocs.Add(new MetadataIndexDoc {
                Uuid = "12345-123545-1231245-1231230"
            });
            indexDocs.Add(new MetadataIndexDoc {
                Uuid = "12345-123545-1231245-1231231"
            });
            indexDocumentCreator.Setup(i => i.CreateIndexDocs(It.IsAny <object[]>(), geoNorgeMock.Object, culture)).Returns(indexDocs);

            var errorMock = new Mock <IErrorService>();

            var indexer = new SolrMetadataIndexer(geoNorgeMock.Object, indexerMock.Object, indexerAppMock.Object, indexerSerMock.Object, indexDocumentCreator.Object, errorMock.Object, indexerMockAll.Object);

            indexer.RunIndexing();

            geoNorgeMock.Verify(g => g.SearchIso("", 1, 50, false));
            //Indexer.Index(IEnumerable<MetadataIndexDoc> docs); //Not in use since need to put metadata in different indexes(cores)
            indexerMock.Verify(i => i.Index(indexDocs[0]));
            indexerMock.Verify(i => i.Index(indexDocs[1]));
        }
        public string BuildSearchQueryString(QueryRange queryRange)
        {
            var query = $"/search?q={SearchTerm}";

            if (SearchResultsType != SearchResultsType.All)
            {
                query += $"&t={SearchResultsType.ToString().ToLower()}";
            }

            if (CurrentPage > 1)
            {
                query += "&p=" + CurrentPage;
            }

            if (QuerySortBy != QuerySortBy.DateCreated)
            {
                query += "&s=" + QuerySortBy.ToString().ToLower();
            }

            query += "&r=" + queryRange.ToString().ToLower();
            return(query);
        }
Example #12
0
        public List <MetadataEntry> ParseSearchResults(SearchResultsType searchResults)
        {
            List <MetadataEntry> results = new List <MetadataEntry>();

            foreach (var item in searchResults.Items)
            {
                SummaryRecordType summary = (SummaryRecordType)item;

                var title = "unknown";
                if (summary.title != null && summary.title.Length > 0 && summary.title[0] != null && summary.title[0].Text != null && summary.title[0].Text.Length > 0)
                {
                    title = summary.title[0].Text[0];
                }

                var uuid = summary.identifier[0].Text[0];


                results.Add(new MetadataEntry {
                    Title = title, Uuid = uuid
                });
            }
            return(results);
        }
        public XmlDocument GenerateDcat()
        {
            MediaTypes        = GetMediaTypes();
            OrganizationsLink = GetOrganizationsLink();
            DistributionTypes = GetDistributionTypes();
            metadataSets      = GetDatasets();

            XmlElement root = Setup();

            GetConcepts();

            XmlElement catalog = CreateCatalog(root);

            CreateDatasets(root, catalog);

            AddConcepts(root);

            Finalize(root, catalog);

            doc.Save(System.Web.HttpContext.Current.Request.MapPath("~\\dcat\\geonorge_dcat.rdf"));

            return(doc);
        }
Example #14
0
        public static IEnumerable <SearchResult> PerformSearch(string milieu, string query, SearchResultsType types, int maxResultsPerType, bool random = false)
        {
            List <SearchResult> results = new List <SearchResult>();

            types = ParseQuery(query, types, out var clauses, out var terms);

            if (clauses.Count() == 0 && !random)
            {
                return(results);
            }

            clauses.Insert(0, "milieu = @term");
            terms.Insert(0, milieu ?? SectorMap.DEFAULT_MILIEU);

            string where = string.Join(" AND ",
                                       clauses.Select((clause, index) => "(" + clause.Replace("@term", $"@term{index}") + ")"));

            string orderBy = random ? "ORDER BY NEWID()" : "";

            // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
            // * {0} is the list of distinct fields (i.e. coordinates),
            // * {1} is the list of fields in the subquery (same as {0} but with "name" added,
            // * {2} is the table
            // * {3} is the filter (WHERE clause, not including "WHERE")
            // * {4} is the order (ORDERBY clause)
            // * {5} is the limit (TOP clause, not including "TOP")
            // Since we need the distinct values from the term {0} but don't use the name for the results construction,
            // we can ignore name in the resultset. This allows us to get the top N results from the database, sort by
            // name, and then toss out duplicates not based on name but on the other, used, columns. Here's a sample
            // subquery that works for the sector table:
            //   SELECT DISTINCT TOP 160 tt.x, tt.y
            //   FROM (SELECT TOP 160 x, y,name
            //         FROM sectors
            //         WHERE (name LIKE 'LEY%' OR name LIKE '%LEY%')
            //         ORDER BY name ASC) AS tt;
            // TODO: Include the searched-for name in the results, and show alternate names in the result set.
            string query_format = "SELECT DISTINCT TOP {5} {0} FROM (SELECT TOP {5} {1} FROM {2} WHERE {3} {4}) AS TT";

            using (var connection = DBUtil.MakeConnection())
            {
                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.x, TT.y", "x, y", "sectors", where, orderBy, maxResultsPerType);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue($"@term{i}", terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorResult(row.GetInt32(0), row.GetInt32(1)));
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.sector_x, TT.sector_y, TT.subsector_index", "sector_x, sector_y, subsector_index", "subsectors", where, orderBy, maxResultsPerType);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue($"@term{i}", terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorResult(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs, etc
                if (types.HasFlag(SearchResultsType.Worlds))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.sector_x, TT.sector_y, TT.hex_x, TT.hex_y", "sector_x, sector_y, hex_x, hex_y", "worlds", where, orderBy, maxResultsPerType);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue($"@term{i}", terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new WorldResult(row.GetInt32(0), row.GetInt32(1), (byte)row.GetInt32(2), (byte)row.GetInt32(3)));
                            }
                        }
                    }
                }

                // Labels
                if (types.HasFlag(SearchResultsType.Labels))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.x, TT.y, TT.radius, TT.name", "x, y, radius, name", "labels", where, orderBy, maxResultsPerType);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue($"@term{i}", terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new LabelResult(row.GetString(3), new Point(row.GetInt32(0), row.GetInt32(1)), row.GetInt32(2)));
                            }
                        }
                    }
                }
            }
            return(results);
        }
Example #15
0
        public static IEnumerable <ItemLocation> PerformSearch(string query, SearchResultsType types, int maxResultsPerType)
        {
            List <ItemLocation> results = new List <ItemLocation>();

            List <string> clauses;
            List <string> terms;

            types = ParseQuery(query, types, out clauses, out terms);

            if (clauses.Count() == 0)
            {
                return(results);
            }

            string where = string.Join(" AND ", clauses.ToArray());

            // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
            // TODO: Include the searched-for name in the results, and show alternate names in the result set.
            // {0} is the list of distinct fields (i.e. coordinates), {1} is the list of fields in the subquery (same as {0} but with "name" added, {2} is the table, {3} is the filter
            // Since we need the distinct values from the term {0} but don't use the name for the results construction, we can ignore name in the resultset.
            // This allows us to get the top N results from the database, sort by name, and then toss out duplicates not based on name but on the other, used, columns
            // Here's a sample subquery that works for the sector table.
            // SELECT DISTINCT TOP 160 tt.x, tt.y FROM (SELECT TOP 160 x, y,name FROM sectors WHERE (name LIKE 'LEY%' OR name LIKE '%LEY%') ORDER BY name ASC) AS tt;
            string query_format = "SELECT DISTINCT TOP " + maxResultsPerType + " {0} FROM (SELECT TOP " + maxResultsPerType + " {1} FROM {2} WHERE {3}) AS TT";

            using (var connection = DBUtil.MakeConnection())
            {
                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.x, TT.y", "x, y", "sectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorLocation(row.GetInt32(0), row.GetInt32(1)));
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.sector_x, TT.sector_y, TT.subsector_index", "sector_x, sector_y, subsector_index", "subsectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorLocation(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs, etc
                if (types.HasFlag(SearchResultsType.Worlds))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.sector_x, TT.sector_y, TT.hex_x, TT.hex_y", "sector_x, sector_y, hex_x, hex_y", "worlds", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new WorldLocation(row.GetInt32(0), row.GetInt32(1), (byte)row.GetInt32(2), (byte)row.GetInt32(3)));
                            }
                        }
                    }
                }

                // Labels
                if (types.HasFlag(SearchResultsType.Labels))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.x, TT.y, TT.radius, TT.name", "x, y, radius, name", "labels", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);
                        }

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new LabelLocation(row.GetString(3), new Point(row.GetInt32(0), row.GetInt32(1)), row.GetInt32(2)));
                            }
                        }
                    }
                }
            }
            return(results);
        }
        private static MetadataIndexViewModel ParseSearchResults(int offset, int limit, SearchResultsType results)
        {
            var model    = new MetadataIndexViewModel();
            var metadata = new Dictionary <string, MetadataItemViewModel>();

            if (results.Items != null)
            {
                foreach (var item in results.Items)
                {
                    RecordType record = (RecordType)item;

                    string title        = null;
                    string uuid         = null;
                    string publisher    = null;
                    string creator      = null;
                    string organization = null;
                    string type         = null;
                    string relation     = null;

                    for (int i = 0; i < record.ItemsElementName.Length; i++)
                    {
                        var name  = record.ItemsElementName[i];
                        var value = record.Items[i].Text != null ? record.Items[i].Text[0] : null;

                        if (name == ItemsChoiceType24.title)
                        {
                            title = value;
                        }
                        else if (name == ItemsChoiceType24.identifier)
                        {
                            uuid = value;
                        }
                        else if (name == ItemsChoiceType24.creator)
                        {
                            creator = value;
                        }
                        else if (name == ItemsChoiceType24.publisher)
                        {
                            publisher = value;
                        }
                        else if (name == ItemsChoiceType24.type)
                        {
                            type = value;
                        }
                        else if (name == ItemsChoiceType24.relation)
                        {
                            relation = value;
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(publisher))
                    {
                        organization = publisher;
                    }
                    else
                    {
                        organization = creator;
                    }

                    var metadataItem = new MetadataItemViewModel
                    {
                        Title                    = title,
                        Uuid                     = uuid,
                        Organization             = organization,
                        Type                     = type,
                        Relation                 = relation,
                        GeoNetworkViewUrl        = GeoNetworkUtil.GetViewUrl(uuid),
                        GeoNetworkXmlDownloadUrl = GeoNetworkUtil.GetXmlDownloadUrl(uuid)
                    };

                    if (uuid != null)
                    {
                        metadata.Add(uuid, metadataItem);
                    }
                }

                model.MetadataItems           = metadata.Values.ToList();
                model.Limit                   = limit;
                model.Offset                  = offset;
                model.NumberOfRecordsReturned = int.Parse(results.numberOfRecordsReturned);
                model.TotalNumberOfRecords    = int.Parse(results.numberOfRecordsMatched);
            }
            return(model);
        }
        public async Task <IActionResult> Index(string q, int p = 1, SearchResultsType t = SearchResultsType.All, string s = "", string r = "")
        {
            if (string.IsNullOrEmpty(q))
            {
                return(RedirectToAction("Index", "Home"));
            }

            // search categories
            // search gallery names/description
            // search image names/description/tags/credits
            q = q.Trim();
            ViewData["query"] = q;
            const int pageSize   = 21;
            const int maxResults = 500;

            Enum.TryParse(s, true, out QuerySortBy querySortBy);
            Enum.TryParse(r, true, out QueryRange queryRange);

            // don't allow invalid page numbers
            if (p < 1)
            {
                p = 1;
            }

            List <Category> categories = null;

            if (t == SearchResultsType.All || t == SearchResultsType.Categories)
            {
                // search for categories
                categories             = Server.Instance.Categories.Categories.Where(c => c.Name.Contains(q, StringComparison.CurrentCultureIgnoreCase)).ToList();
                ViewData["categories"] = categories;
            }

            PagedResultSet <Gallery> galleryPagedResultSet = null;
            PagedResultSet <Image>   imagePagedResultSet   = null;

            if (t != SearchResultsType.Categories)
            {
                if (t == SearchResultsType.Galleries)
                {
                    // search for just galleries
                    galleryPagedResultSet = await Server.Instance.Galleries.SearchForGalleriesAsync(q, null, SearchStatus.Active, p, pageSize, maxResults, querySortBy, queryRange);
                }
                else if (t == SearchResultsType.Images)
                {
                    // search for just images
                    imagePagedResultSet = await Server.Instance.Images.SearchForImagesAsync(q, p, pageSize, maxResults, includeInactiveGalleries : true, querySortBy, queryRange);
                }
                else
                {
                    // these two queries take 300-400 milliseconds, so run them in parallel:
                    var tasks = new List <Task>
                    {
                        Task.Run(async() =>
                        {
                            // search for galleries
                            galleryPagedResultSet = await Server.Instance.Galleries.SearchForGalleriesAsync(q, null, SearchStatus.Active, p, pageSize, maxResults, querySortBy, queryRange);
                        }),
                        Task.Run(async() =>
                        {
                            // search for images
                            imagePagedResultSet = await Server.Instance.Images.SearchForImagesAsync(q, p, pageSize, maxResults, includeInactiveGalleries: true, querySortBy, queryRange);
                        })
                    };

                    var stopwatch = Stopwatch.StartNew();
                    await Task.WhenAll(tasks);

                    stopwatch.Stop();
                    Log.Information($"Web:SearchController.Index(): Search took {stopwatch.ElapsedMilliseconds} ms");
                }
            }

            // merge the individual paged result sets into a multi-type one here
            var searchPagedResultSet = new SearchPagedResultSet
            {
                PageSize          = pageSize,
                CurrentPage       = p,
                SearchTerm        = q,
                MaximumResults    = maxResults,
                SearchResultsType = t,
                QuerySortBy       = querySortBy,
                QueryRange        = queryRange
            };

            if (p == 1 && categories != null)
            {
                searchPagedResultSet.CategoryResults      = categories;
                searchPagedResultSet.TotalCategoryResults = categories.Count;
            }

            if (galleryPagedResultSet != null)
            {
                searchPagedResultSet.GalleryResults      = galleryPagedResultSet.Results;
                searchPagedResultSet.TotalGalleryResults = galleryPagedResultSet.TotalResults;
            }

            if (imagePagedResultSet != null)
            {
                searchPagedResultSet.ImageResults      = imagePagedResultSet.Results;
                searchPagedResultSet.TotalImageResults = imagePagedResultSet.TotalResults;
            }

            ViewData.Model = searchPagedResultSet;

            ViewData["galleriesJson"] = searchPagedResultSet.GalleryResults != null?JsonConvert.SerializeObject(searchPagedResultSet.GalleryResults.Select(g => new
            {
                g.CategoryId,
                g.Id,
                g.Name,
                g.ThumbnailFiles,
                g.ImageCount,
                g.CommentCount,
                CategoryName = Server.Instance.Categories.GetCategory(g.CategoryId).Name
            })) : null;

            ViewData["imagesJson"] = searchPagedResultSet.ImageResults != null?JsonConvert.SerializeObject(searchPagedResultSet.ImageResults.Select(i => new
            {
                i.Id,
                i.GalleryId,
                i.Name,
                i.Files,
                i.Comments.Count
            })) : null;

            return(View());
        }
Example #18
0
        public static IEnumerable <ItemLocation> PerformSearch(string query, ResourceManager resourceManager, SearchResultsType types, int numResults)
        {
            List <ItemLocation> results = new List <ItemLocation>();

            using (var connection = DBUtil.MakeConnection())
            {
                List <string> clauses = new List <string>();
                List <string> terms   = new List <string>();
                foreach (string t in query.Split((char[])null, StringSplitOptions.RemoveEmptyEntries))
                {
                    string term = t;
                    string clause;
                    if (term.StartsWith("uwp:"))
                    {
                        term   = term.Substring(term.IndexOf(':') + 1);
                        clause = "uwp LIKE @term";
                        types  = SearchResultsType.UWP;
                    }
                    else if (term.StartsWith("exact:"))
                    {
                        term   = term.Substring(term.IndexOf(':') + 1);
                        clause = "name LIKE @term";
                    }
                    else if (term.StartsWith("like:"))
                    {
                        term   = term.Substring(term.IndexOf(':') + 1);
                        clause = "SOUNDEX(name) = SOUNDEX(@term)";
                    }
                    else if (term.Contains("%") || term.Contains("_"))
                    {
                        clause = "name LIKE @term";
                    }
                    else
                    {
                        clause = "name LIKE @term + '%' OR name LIKE '% ' + @term + '%'";
                    }

                    clause = clause.Replace("@term", String.Format("@term{0}", terms.Count));
                    clauses.Add("(" + clause + ")");
                    terms.Add(term);
                }

                string where = String.Join(" AND ", clauses.ToArray());

                // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
                // TODO: Include the searched-for name in the results, and show alternate names in the result set.
                // {0} is the list of distinct fields (i.e. coordinates), {1} is the table, {2} is the filter
                string query_format = "SELECT DISTINCT TOP " + numResults + " {0},name FROM {1} WHERE {2} ORDER BY name ASC";

                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors) && numResults > 0)
                {
                    string sql = String.Format(query_format, "x, y", "sectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorLocation(row.GetInt32(0), row.GetInt32(1)));
                                numResults -= 1;
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors) && numResults > 0)
                {
                    string sql = String.Format(query_format, "sector_x, sector_y, subsector_index", "subsectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorLocation(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs
                if ((types.HasFlag(SearchResultsType.Worlds) || types.HasFlag(SearchResultsType.UWP)) && numResults > 0)
                {
                    string sql = String.Format(query_format, "sector_x, sector_y, hex_x, hex_y", "worlds", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new WorldLocation(row.GetInt32(0), row.GetInt32(1), row.GetInt32(2), row.GetInt32(3)));
                            }
                        }
                    }
                }
            }

            return(results);
        }
        public MetadataIndexViewModel GetMyMetadata(string organizationName, int offset, int limit)
        {
            SearchResultsType results = _geoNorge.SearchWithOrganisationName(organizationName, offset, limit, true);

            return(ParseSearchResults(offset, limit, results));
        }
Example #20
0
        private static SearchResultsType ParseQuery(string?query, SearchResultsType types, out List <string> clauses, out List <string> terms)
        {
            clauses = new List <string>();
            terms   = new List <string>();
            if (string.IsNullOrWhiteSpace(query))
            {
                return(types);
            }
            query = query !.Trim().ToLowerInvariant();

            Match m = SECTOR_HEX_REGEX.Match(query);

            if (m.Success)
            {
                int hex = int.Parse(m.Groups["hex"].Value);
                clauses.Add("sector_name LIKE @term + '%'");
                terms.Add(m.Groups["sector"].Value);
                clauses.Add("hex_x = @term");
                terms.Add((hex / 100).ToString());
                clauses.Add("hex_y = @term");
                terms.Add((hex % 100).ToString());
                return(SearchResultsType.Worlds);
            }

            foreach (string t in ParseTerms(query))
            {
                string term   = t;
                string?op     = null;
                bool   quoted = false;

                foreach (var o in OPS)
                {
                    if (term.StartsWith(o))
                    {
                        op   = o;
                        term = term.Substring(o.Length);
                        break;
                    }
                }

                // Infer a trailing "
                if (term.StartsWith("\"") && (!term.EndsWith("\"") || term.Length == 1))
                {
                    term += '"';
                }
                if (term.Length >= 2 && term.StartsWith("\"") && term.EndsWith("\""))
                {
                    quoted = true;
                    term   = term.Substring(1, term.Length - 2);
                }
                if (term.Length == 0)
                {
                    continue;
                }

                string clause;
                if (op == "uwp:")
                {
                    clause = "uwp LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "pbg:")
                {
                    clause = "pbg LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "zone:")
                {
                    clause = "zone LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "alleg:")
                {
                    clause = "alleg LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "remark:")
                {
                    clause = "' ' + remarks + ' ' LIKE '% ' + @term + ' %'";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "in:")
                {
                    clause = "sector_name LIKE @term + '%'";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "exact:")
                {
                    clause = "name LIKE @term";
                }
                else if (op == "like:")
                {
                    clause = "SOUNDEX(name) = SOUNDEX(@term)";
                }
                else if (quoted)
                {
                    clause = "name LIKE @term";
                }
                else if (term.Contains("%") || term.Contains("_"))
                {
                    clause = "name LIKE @term";
                }
                else if (term.Equals("sector", StringComparison.InvariantCultureIgnoreCase))
                {
                    types = SearchResultsType.Sectors;
                    continue;
                }
                else if (term.Equals("subsector", StringComparison.InvariantCultureIgnoreCase))
                {
                    types = SearchResultsType.Subsectors;
                    continue;
                }
                else if (term.Equals("world", StringComparison.InvariantCultureIgnoreCase))
                {
                    types = SearchResultsType.Worlds;
                    continue;
                }
                else
                {
                    clause = "name LIKE @term + '%' OR name LIKE '% ' + @term + '%'";
                }

                clauses.Add(clause);
                terms.Add(term);
            }
            return(types);
        }
        public static IEnumerable<ItemLocation> PerformSearch(string query, ResourceManager resourceManager, SearchResultsType types, int numResults)
        {
            List<ItemLocation> results = new List<ItemLocation>();

            using (var connection = DBUtil.MakeConnection())
            {
                List<string> clauses = new List<string>();
                List<string> terms = new List<string>();
                foreach (string t in query.Split((char[])null, StringSplitOptions.RemoveEmptyEntries))
                {
                    string term = t;
                    string clause;
                    if (term.StartsWith("uwp:"))
                    {
                        term = term.Substring(term.IndexOf(':') + 1);
                        clause = "uwp LIKE @term";
                        types = SearchResultsType.UWP;
                    }
                    else if (term.StartsWith("exact:"))
                    {
                        term = term.Substring(term.IndexOf(':') + 1);
                        clause = "name LIKE @term";
                    }
                    else if (term.StartsWith("like:"))
                    {
                        term = term.Substring(term.IndexOf(':') + 1);
                        clause = "SOUNDEX(name) = SOUNDEX(@term)";
                    }
                    else if (term.Contains("%") || term.Contains("_"))
                    {
                        clause = "name LIKE @term";
                    }
                    else
                    {
                        clause = "name LIKE @term + '%' OR name LIKE '% ' + @term + '%'";
                    }

                    clause = clause.Replace("@term", String.Format("@term{0}", terms.Count));
                    clauses.Add("(" + clause + ")");
                    terms.Add(term);
                }

                string where = String.Join(" AND ", clauses.ToArray());

                // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
                // TODO: Include the searched-for name in the results, and show alternate names in the result set.
                // {0} is the list of distinct fields (i.e. coordinates), {1} is the table, {2} is the filter
                string query_format = "SELECT DISTINCT TOP " + numResults + " {0},name FROM {1} WHERE {2} ORDER BY name ASC";

                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors) && numResults > 0)
                {
                    string sql = String.Format(query_format, "x, y", "sectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorLocation(row.GetInt32(0), row.GetInt32(1)));
                                numResults -= 1;
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors) && numResults > 0)
                {
                    string sql = String.Format(query_format, "sector_x, sector_y, subsector_index", "subsectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorLocation(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs
                if ((types.HasFlag(SearchResultsType.Worlds) || types.HasFlag(SearchResultsType.UWP)) && numResults > 0)
                {
                    string sql = String.Format(query_format, "sector_x, sector_y, hex_x, hex_y", "worlds", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new WorldLocation(row.GetInt32(0), row.GetInt32(1), row.GetInt32(2), row.GetInt32(3)));
                            }
                        }
                    }
                }
            }

            return results;
        }
        //[Route("dataset/{parentRegister}/{registerowner}/{registername}/{municipality}/ny")]
        //[Route("dataset/{registername}/{municipality}/ny")]
        public ActionResult CreateMunicipalDataset(CreateDokMunicipalViewModel model, string searchString, bool save = false)
        {
            model.Register = _registerService.GetDokMunicipalRegister();
            if (_accessControlService.AccessEditOrCreateDOKMunicipalBySelectedMunicipality(model.MunicipalityCode))
            {
                ViewBag.SearchString = searchString;
                model.DatasetOwner   = _registerItemService.GetMunicipalityOrganizationByNr(model.MunicipalityCode);

                if (model.SelectedList != null)
                {
                    List <MetadataItemViewModel> items = new List <MetadataItemViewModel>();
                    foreach (var metaItem in model.SelectedList)
                    {
                        items.Add(metaItem);
                    }

                    foreach (var item in items)
                    {
                        if (!item.Selected)
                        {
                            model.SelectedList.Remove(item);
                        }
                    }
                }

                if (model.SearchResult != null)
                {
                    foreach (var item in model.SearchResult)
                    {
                        if (item.Selected)
                        {
                            if (model.SelectedList == null)
                            {
                                model.SelectedList = new List <MetadataItemViewModel>();
                            }
                            if (model.SelectedList.All(metaItem => metaItem.Uuid != item.Uuid))
                            {
                                model.SelectedList.Add(item);
                            }
                        }
                    }
                    model.SearchResult = null;
                }
                if (!string.IsNullOrEmpty(searchString) && !save)
                {
                    SearchResultsType result = SearchMetadataFromKartkatalogen(searchString);
                    model.SearchResult = ParseSearchResult(result);
                    return(View(model));
                }
                if (save)
                {
                    foreach (var item in model.SelectedList)
                    {
                        Dataset dataset = new Dataset();
                        dataset                = GetMetadataFromKartkatalogen(dataset, item.Uuid);
                        dataset.register       = model.Register;
                        dataset.datasetowner   = model.DatasetOwner;
                        dataset.datasetownerId = model.DatasetOwner.systemId;
                        dataset                = _datasetService.UpdateDataset(dataset);
                        _registerItemService.SaveNewRegisterItem(dataset);
                    }
                    return(Redirect(model.Register.GetObjectUrl() + "?municipality=" + model.MunicipalityCode));
                }
                return(View(model));
            }
            else
            {
                throw new HttpException(401, "Access Denied");
            }
        }
Example #23
0
        private void RunSearch(int startPosition)
        {
            Log.Info("Running search from start position: " + startPosition);
            SearchResultsType searchResult = null;
            bool runningSingle             = false;

            try
            {
                searchResult = _geoNorge.SearchIso("", startPosition, 50, false);
                Log.Info("Next record: " + searchResult.nextRecord + " " + searchResult.numberOfRecordsReturned + " " + searchResult.numberOfRecordsMatched);
                List <MetadataIndexDoc> indexDocs = _indexDocumentCreator.CreateIndexDocs(searchResult.Items, _geoNorge, Culture.NorwegianCode);
                foreach (var doc in indexDocs)
                {
                    RunIndex(doc, Culture.NorwegianCode);
                }
                indexDocs = _indexDocumentCreator.CreateIndexDocs(searchResult.Items, _geoNorge, Culture.EnglishCode);
                foreach (var doc in indexDocs)
                {
                    RunIndex(doc, Culture.EnglishCode);
                }
                runningSingle = false;
            }
            catch (Exception exception)
            {
                Log.Error("Error in ISO format from Geonetwork position: " + startPosition + " + 50. Trying to index one by one", exception);
                //Forsøke en og en?
                int count = 50;
                for (int i = 1; i <= count; i++)
                {
                    SearchResultsType searchResult2 = null;
                    try
                    {
                        Log.Info("Running single index for start position: " + startPosition);
                        searchResult2 = _geoNorge.SearchIso("", startPosition, 1, false);

                        Log.Info("Next record: " + searchResult2.nextRecord + " " + searchResult2.numberOfRecordsMatched);
                        List <MetadataIndexDoc> indexDocs = _indexDocumentCreator.CreateIndexDocs(searchResult2.Items, _geoNorge, Culture.NorwegianCode);
                        foreach (var doc in indexDocs)
                        {
                            RunIndex(doc, Culture.NorwegianCode);
                        }
                        indexDocs = _indexDocumentCreator.CreateIndexDocs(searchResult2.Items, _geoNorge, Culture.EnglishCode);
                        foreach (var doc in indexDocs)
                        {
                            RunIndex(doc, Culture.EnglishCode);
                        }
                        //_indexer.Index(indexDocs);
                        startPosition++;
                        runningSingle = true;
                    }
                    catch (Exception exception2)
                    {
                        Log.Error("Error in ISO format from Geonetwork position: " + startPosition + ".", exception2);
                        if (searchResult2 != null && searchResult2.Items != null)
                        {
                            Log.Info(searchResult2.Items[0]);
                        }

                        startPosition++;
                    }
                }
            }

            int nextRecord;
            int numberOfRecordsMatched;

            if (runningSingle)
            {
                nextRecord = startPosition;
                RunSearch(nextRecord);
            }
            else
            {
                nextRecord             = int.Parse(searchResult.nextRecord);
                numberOfRecordsMatched = int.Parse(searchResult.numberOfRecordsMatched);
                if (nextRecord < numberOfRecordsMatched)
                {
                    RunSearch(nextRecord);
                }
            }
        }
Example #24
0
        private static SearchResultsType ParseQuery(string query, SearchResultsType types, out List<string> clauses, out List<string> terms)
        {
            clauses = new List<string>();
            terms = new List<string>();
            foreach (string t in ParseTerms(query))
            {
                string term = t;
                string op = null;
                bool quoted = false;

                foreach (var o in OPS)
                {
                    if (term.StartsWith(o))
                    {
                        op = o;
                        term = term.Substring(o.Length);
                        break;
                    }
                }

                // Infer a trailing "
                if (term.StartsWith("\"") && (!term.EndsWith("\"") || term.Length == 1))
                    term += '"';
                if (term.Length >= 2 && term.StartsWith("\"") && term.EndsWith("\""))
                {
                    quoted = true;
                    term = term.Substring(1, term.Length - 2);
                }
                if (term.Length == 0)
                    continue;

                string clause;
                if (op == "uwp:")
                {
                    clause = "uwp LIKE @term";
                    types = SearchResultsType.Worlds;
                }
                else if (op == "pbg:")
                {
                    clause = "pbg LIKE @term";
                    types = SearchResultsType.Worlds;
                }
                else if (op == "zone:")
                {
                    clause = "zone LIKE @term";
                    types = SearchResultsType.Worlds;
                }
                else if (op == "alleg:")
                {
                    clause = "alleg LIKE @term";
                    types = SearchResultsType.Worlds;
                }
                else if (op == "remark:")
                {
                    clause = "' ' + remarks + ' ' LIKE '% ' + @term + ' %'";
                    types = SearchResultsType.Worlds;
                }
                else if (op == "in:")
                {
                    clause = "sector_name LIKE @term + '%'";
                    types = SearchResultsType.Worlds;
                }
                else if (op == "exact:")
                {
                    clause = "name LIKE @term";
                }
                else if (op == "like:")
                {
                    clause = "SOUNDEX(name) = SOUNDEX(@term)";
                }
                else if (quoted)
                {
                    clause = "name LIKE @term";
                }
                else if (term.Contains("%") || term.Contains("_"))
                {
                    clause = "name LIKE @term";
                }
                else
                {
                    clause = "name LIKE @term + '%' OR name LIKE '% ' + @term + '%'";
                }

                clause = clause.Replace("@term", string.Format("@term{0}", terms.Count));
                clauses.Add("(" + clause + ")");
                terms.Add(term);
            }
            return types;
        }
Example #25
0
        public static IEnumerable<ItemLocation> PerformSearch(string query, SearchResultsType types, int maxResultsPerType)
        {
            List<ItemLocation> results = new List<ItemLocation>();

            List<string> clauses;
            List<string> terms;
            types = ParseQuery(query, types, out clauses, out terms);

            if (clauses.Count() == 0)
                return results;

            string where = string.Join(" AND ", clauses.ToArray());

            // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
            // TODO: Include the searched-for name in the results, and show alternate names in the result set.
            // {0} is the list of distinct fields (i.e. coordinates), {1} is the list of fields in the subquery (same as {0} but with "name" added, {2} is the table, {3} is the filter
            // Since we need the distinct values from the term {0} but don't use the name for the results construction, we can ignore name in the resultset.
            // This allows us to get the top N results from the database, sort by name, and then toss out duplicates not based on name but on the other, used, columns
            // Here's a sample subquery that works for the sector table.
            // SELECT DISTINCT TOP 160 tt.x, tt.y FROM (SELECT TOP 160 x, y,name FROM sectors WHERE (name LIKE 'LEY%' OR name LIKE '%LEY%') ORDER BY name ASC) AS tt;
            string query_format = "SELECT DISTINCT TOP " + maxResultsPerType + " {0} FROM (SELECT TOP " + maxResultsPerType + " {1} FROM {2} WHERE {3}) AS TT";

            using (var connection = DBUtil.MakeConnection())
            {
                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.x, TT.y", "x, y", "sectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorLocation(row.GetInt32(0), row.GetInt32(1)));
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.sector_x, TT.sector_y, TT.subsector_index", "sector_x, sector_y, subsector_index", "subsectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorLocation(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs, etc
                if (types.HasFlag(SearchResultsType.Worlds))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.sector_x, TT.sector_y, TT.hex_x, TT.hex_y", "sector_x, sector_y, hex_x, hex_y", "worlds", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                                results.Add(new WorldLocation(row.GetInt32(0), row.GetInt32(1), (byte)row.GetInt32(2), (byte)row.GetInt32(3)));
                        }
                    }
                }

                // Labels
                if (types.HasFlag(SearchResultsType.Labels))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = string.Format(query_format, "TT.x, TT.y, TT.radius, TT.name", "x, y, radius, name", "labels", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(string.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new LabelLocation(row.GetString(3), new Point(row.GetInt32(0), row.GetInt32(1)), row.GetInt32(2)));
                            }
                        }
                    }
                }
            }
            return results;
        }
Example #26
0
        private static SearchResultsType ParseQuery(string query, SearchResultsType types, out List <string> clauses, out List <string> terms)
        {
            clauses = new List <string>();
            terms   = new List <string>();
            if (string.IsNullOrWhiteSpace(query))
            {
                return(types);
            }
            query = query.ToLowerInvariant();

            foreach (string t in ParseTerms(query))
            {
                string term   = t;
                string op     = null;
                bool   quoted = false;

                foreach (var o in OPS)
                {
                    if (term.StartsWith(o))
                    {
                        op   = o;
                        term = term.Substring(o.Length);
                        break;
                    }
                }

                // Infer a trailing "
                if (term.StartsWith("\"") && (!term.EndsWith("\"") || term.Length == 1))
                {
                    term += '"';
                }
                if (term.Length >= 2 && term.StartsWith("\"") && term.EndsWith("\""))
                {
                    quoted = true;
                    term   = term.Substring(1, term.Length - 2);
                }
                if (term.Length == 0)
                {
                    continue;
                }

                string clause;
                if (op == "uwp:")
                {
                    clause = "uwp LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "pbg:")
                {
                    clause = "pbg LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "zone:")
                {
                    clause = "zone LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "alleg:")
                {
                    clause = "alleg LIKE @term";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "remark:")
                {
                    clause = "' ' + remarks + ' ' LIKE '% ' + @term + ' %'";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "in:")
                {
                    clause = "sector_name LIKE @term + '%'";
                    types  = SearchResultsType.Worlds;
                }
                else if (op == "exact:")
                {
                    clause = "name LIKE @term";
                }
                else if (op == "like:")
                {
                    clause = "SOUNDEX(name) = SOUNDEX(@term)";
                }
                else if (quoted)
                {
                    clause = "name LIKE @term";
                }
                else if (term.Contains("%") || term.Contains("_"))
                {
                    clause = "name LIKE @term";
                }
                else
                {
                    clause = "name LIKE @term + '%' OR name LIKE '% ' + @term + '%'";
                }

                clauses.Add(clause);
                terms.Add(term);
            }
            return(types);
        }