Click here to Skip to main content
Click here to Skip to main content
Articles » Database » Database » SQL Server » Downloads
 
Add your own
alternative version

Using SQL Server Metadata and Statistics to Build a Table Explorer Application

, 1 Oct 2012
Develops an analogy between database table and file directory information and argues that it could be very useful if it were possible to have a similar application to Windows Explorer for database tables. Demonstrates how to obtain the information from Sql Server system tables and dynamic management
using System;
using System.Collections.Generic;
using System.Text;

/*
	To do:
	extra chars.
	tidy up
*/

namespace Wildmatch
{
	class WildMatchWord
	{
		public String Word;
		public int Pos;
		public bool Finished { get { return (Pos < 0); } }
		
		public WildMatchWord(String theWord)
		{
			Word = theWord;
			Pos = 0;
		}

		public WildMatchWord(WildMatchWord src)
		{
			Word = src.Word;
			Pos = src.Pos;
		}

		public bool matchChar(char c)
		{
			if (Pos < 0) return false;
			return (Word[Pos] == c);
		}

		public void moveNext()
		{
			if (Pos >= 0)
			{
				++Pos;
				if (Pos >= Word.Length)
					Pos = -1;
			}
		}
		
		public void Finish()
		{
			if (Pos > 0) Pos = -1;
		}
		
	}
	
	class MatchState
	{
		public MatchState(String target)
		{
			process(target);
		}

		public MatchState(MatchState src)
		{
			m_Words = new List<WildMatchWord>();
			foreach (WildMatchWord wmw in src.Words)
			{
				m_Words.Add(new WildMatchWord(wmw));
			}

		}

		public void finishWord(String word)
		{
			foreach (WildMatchWord wmw in m_Words)
			{
				if (wmw.Word == word && !wmw.Finished)
				{
					wmw.Finish();
					break;
				}
			}
		}

		public List<WildMatchWord> Words { get { return m_Words; } }

		void process(String target)
		{
			// remove/replace noise
			String [] words = target.Split(' ');
			m_Words = new List<WildMatchWord>();
			foreach (String word in words)
			{
				if (word.Length > 0)
				{
					m_Words.Add(new WildMatchWord(word.ToUpper()));
				}
			}
		}
		
		
		List<WildMatchWord> m_Words;
	}
	
	class WildMatch
	{
		public static bool Match(String target, String part)
		{
			if (target.Length == 0)
				return (part.Length == 0); // T matches empty to empty F otherwise
			if (part.Length == 0)
				return true;               // anything matches an empty search string 
			
			String seek = part.Replace(","," ")
							  .Replace("-", " ")
							  .Replace("_", " ")
							  .Replace(".", " ")
							  .Replace(",", " ")
							  .Replace("/", " ")
							  .Replace(" ", "")
							  .ToUpper();
			MatchState state = new MatchState(target.Replace(",", " ")
											  .Replace("-", " ")
											  .Replace("_", " ")
											  .Replace(".", " ")
											  .Replace(",", " ")
											  .Replace("/", " ")
												);

			// seeds a search starting from word 0
			return new WildMatch().matchFrom(0, seek, 0, state);
		}

		// function to search from a given position in the seek string with 
		// a given match state for the words.
		public bool matchFrom(int wordIndex, String seek, int fromPos, MatchState state)
		{
			if (fromPos >= seek.Length) return true; // recursive exit point
			// get the target char
			char seekChar = seek[fromPos];
			// start at -1 to give priority to the word index parameter
			for (int idx = -1; idx < state.Words.Count; ++idx)
			{
				if (idx >= 0) wordIndex = idx; // after -1 normal sequence.
				WildMatchWord wmw  = state.Words[wordIndex];
				// if a word has been consumed or part-consumed then it can't be re-used
				if (!wmw.Finished) // can't use this one if it is consumed
				{
					// match current char in current target word with then seek string char
					if (wmw.matchChar(seekChar))
					{
						// consume the char in the target
						wmw.moveNext();
						// try to match the next seek string char with the next char in this word
						if (matchFrom(wordIndex, seek, fromPos + 1, new MatchState(state)))
							// return success back up the recursive stack
							return true;
					}
				}
				// as the recusive function failed for this word at this point
				// it can play no further part in the matching process. So flag it.
				// ... unless this is the front of the word in which case in may be used
				// in another position eg AN APPLE matching APAN
				if (fromPos > 0) 
					wmw.Finish();
				else
					// wind it back to the start
					wmw.Pos = 0;
			}
			return false;
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

DaveDbViewSharp

United Kingdom United Kingdom
No Biography provided

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 1 Oct 2012
Article Copyright 2012 by DaveDbViewSharp
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid