Обычная версия
Java форум JavaTalks
форум программистов

Поиск   Пользователи   Группы   Регистрация 
 Профиль   Личные сообщения 

 Вход 

Парсинг строк в файле
Список форумов
 ->  Другие технологии


На страницу 1, 2  След. 
Начать новую тему 
Предыдущая тема :: Следующая тема  
Автор Сообщение
ALeksandriys : 22
Новичок

СообщениеОкт 13, 2006 21:20 
Ответить с цитатой
Всем доброго..., помогите плиз, мне нужно сделать програму парсинга строк в файле, строки это запросы. Мне надо сделать анализ на тип запроса, тоесть разделить, 4-е типа, по типам запроса, потом каждый тип разделить по использованию общих таблиц, полей, условий выборки, группировки и т.д. И в конце, я должен буду получить получить четыре типа запросов с максимально большим количеством общих аргументов, Заранее спасибо.

Например

10 Select использующих таблицу T1, одно и тоже поле Р1 из таблицы T1 и т.д
и так все 4-е типа.

Дайте плиз хотя бы наводку бо я совсем пока незнаю как к этому подойти
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
Vlad : 1670
JavaTalks Team Member
Откуда: ODS-KRK-LON-HFE

СообщениеОкт 14, 2006 19:40 
Ответить с цитатой
Не понятно какие 4 типа запросов имеються ввиду.

А для парсинга удобно использовать regex (regular expressions). В Java эту функциональость реализуют классы java.util.regex.Pattern и java.util.regex.Matcher.

Для хранения информации о запросе можно реализовать примерно такой класс:
Код:

class QueryMetaData {
   public QueryMetaData(String query) {
      // Parsing SQL SELECT expression (for example, by regex) ...
   }
   public int getColumnCount() { ... }
   public String getColumnName(int index) { ... }
   public int getTableCount() { ... }
   public String getTableName(int index) { ... }
   public String getTableAlias(int index) { ... }
   public Collection<String> getTableColumns(int index) { ... }
   public boolean hasColumn(String tblName, String colName) { ... }
   public String getWhereClause() { ... }
}


Дальше собираем статистику с инстанций QueryMetaData.

Другой вариант: парсить и сразу собирать статистику, не сохраняя резутьтаты парсинга запроса.
Код:
public class QueryInfoCollector {
  public parseQuery(String query) { ... } 
  // ...
  private Map<String, Integer> tablesStat; // Entry = [tableName, occurences]
  private Map<String, Integer> colmnsStat; // Entry = [tableName.columnName, occurences]
  // ...
}


---
Пример выражения для парсинга запроса SELECT:
Код:

String input = "SELECT a.c1, a.c2 , b.c1, b.c2 FROM tableA a, tableB b WHERE a.c1 = b.c2";

String emptyRegex = "[\\s]*";
String selectRegex = emptyRegex + "SELECT[\\s]+(.+)[\\s]+FROM[\\s]+(.+)[\\s]+(WHERE[\\s]+(.+))?" + emptyRegex;
Pattern ptrn = Patterm.compile(selectRegex, Pattern.CASE_INSENSITIVE);

Matcher m = ptrn.matcher(input);
if (m.matches()) {
  String columnsClause = m.group(1); // "a.c1, a.c2 , b.c1, b.c2"
  String fromClause = m.group(2);      // "tableA a, tableB b"
  String whereClause = m.group(4);    // "a.c1 = b.c2"
  // Parse fromClause to get table names and aliases...
  // Parse columnClause to get column definitions...
  // Parse whereClause...
} else {
  System.out.println("Invalid SELECT query");
}


Последний раз редактировалось: Vlad (Окт 14, 2006 20:01), всего редактировалось 1 раз
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Vlad : 1670
JavaTalks Team Member
Откуда: ODS-KRK-LON-HFE

СообщениеОкт 14, 2006 19:55 
Ответить с цитатой
Vlad писал(а):
Не понятно какие 4 типа запросов имеються ввиду.

Наверняка SELECT, INSERT, UPDATE и DELETE.
Тогда для каждого из типов запроса нужно создать своё регулярное выражение.
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
ALeksandriys : 22
Новичок

СообщениеОкт 14, 2006 23:23 
Ответить с цитатой
Спасибо за пример! А как сделать чтобы он эту строку читал из файла?
Да 4-е типа запросов это insert, update, delete, select. Мне надо парсить их с каждым разом приближаясь к группе запросов с наибольшим количеством одинаковых аргументов,

Скиньте плиз пример группировки запросов с общими аргументами.
Для остальных типов запросов пример меняеться я так понял только ключевые слова а алгоритм такой же? А как создать для каждого запроса свое регулярное выражение? Еще раз спсибо за помощь Embarassed
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
Vlad : 1670
JavaTalks Team Member
Откуда: ODS-KRK-LON-HFE

СообщениеОкт 15, 2006 21:09 
Ответить с цитатой
ALeksandriys писал(а):
А как сделать чтобы он эту строку читал из файла?

Код:
      try {
         FileInputStream is = new FileInputStream(fileName);
         Scanner scanner = new Scanner(is);
         QueryInfoCollector collector = new QueryInfoCollector();
         while(scanner.hasNextLine()) {
            String query = scanner.getNextLine();
            collector.parseQuery(query);
         }
         
         System.out.println("Tables usage statistics:");
         //...
      } finally {
         if (scanner != null) scanner.close();
      }


ALeksandriys писал(а):
Для остальных типов запросов пример меняеться я так понял только ключевые слова а алгоритм такой же? А как создать для каждого запроса свое регулярное выражение?

Привожу пример того, как можно вытащить инфу о колонках и таблицах запроса (естественно с некоторыми ограничениями: e.g. нет поддержки JOIN и т.д.).
Код:
public class QueryInfoCollector {
   public parseQuery(String query) throws QueryParseException {
      if (query == null || query.length == 0) {
         throw new QueryParseException("Query string is null or empty");
      }
      
      // Наивно определяем с каким типом запроса имеет дело
      if (query.toUpperCase().indexOf("SELECT") > -1) {
         parseSelect(query);
      } else if (query.toUpperCase().indexOf("UPDATE") > -1) {
         parseUpdate(query);
      } else if (query.toUpperCase().indexOf("INSERT") > -1) {
         parseInsert(query);
      } else if (query.toUpperCase().indexOf("DELETE") > -1) {
         parseDelete(query);
      } else {
         throw new QueryParseException("Unknown or unsupported SQL query: " + query);
      }
   }
   
   public void parseSelect(String query) throws QueryParseException {
      Matcher m = SELECT_PATTERN.matcher(query);

      if (m.matches()) {
         String columnsClause = m.group(1); // "a.c1, a.c2 , b.c1, b.c2"
         Map<String, String> cols = parseColumnList(columnsClause);
         String fromClause = m.group(2);      // "tableA a, tableB b"
         Map<String, String> tables = parseTableList(fromClause);

         // Делаем, что надо с полученными таблицами и ячейками...

      } else {
         throw new QueryParseException("Invalid SELECT query: " + query);
      }
   }
   
   public void parseUpdate(String query) throws QueryParseException {...}

   public void parseDelete(String query) throws QueryParseException {...}

   public void parseInsert(String query) throws QueryParseException {...}

   public void reset() {
      // Очищаем статистику...
   }
   
   /** Parses tables list (tables delimited by comma) and returns the Map of pairs (<table name>, <table alias>) */
   private Map<String, String> parseTableList(String str) {
      Map<String, String> result = new HashMap<String, String>();
      StringTokenizer tokenizer = new StringTokenizer(str, ",");
      while (tokenizer.hasMoreTokens()) {
         String token = tokenizer.nextToken().trim();
         Matcher m = TABLE_PATTERN.matcher(token);
         if (m.matches()) {
            String tblName = m.group(1);
            String tblAlias = m.group(4);
            result.put(tblName, tblAlias);
         } else {
            throw new QueryParseException("Invalid table token in FROM clause: " + str);
         }
      }
      return result;
   }

   /** Parses columns list (columns delimited by comma) and returns the Map of pairs (<table name or alias>, <column name>) */
   private Map<String, String> parseColumnList(String str) {
      Map<String, String> result = new HashMap<String, String>();
      StringTokenizer tokenizer = new StringTokenizer(str, ",");
      while (tokenizer.hasMoreTokens()) {
         String token = tokenizer.nextToken().trim();
         Matcher m = COLUMN_PATTERN.matcher(token);
         if (m.matches()) {
            String table = m.group(1);
            String column = m.group(2);
            result.put(table, column);
         } else {
            throw new QueryParseException("Invalid table token in FROM clause: " + str);
         }
      }
      return result;
   }
   
   //...
   
   private static final String EMPTY_REGEX = "[\\s]*";
   private static final String SPACE_REGEX = "[\\s]+";
   private static final String WHERE_CLAUSE_REGEX = "(WHERE" + SPACE_REGEX + "(.+) )?";

   private static final String SELECT_REGEX = EMPTY_REGEX +
            "SELECT" + SPACE_REGEX + "(.+)" + SPACE_REGEX +
            "FROM" + SPACE_REGEX + "(.+)" + SPACE_REGEX +
            WHERE_CLAUSE_REGEX + SPACE_REGEX +
            "ORDER BY" + SPACE_REGEX + "(.+)" + EMPTY_REGEX;

   private static final String UPDATE_REGEX = EMPTY_REGEX +
            "UPDATE" + SPACE_REGEX + "(.+)" + SPACE_REGEX +
            "SET" + SPACE_REGEX + "(.+)" + SPACE_REGEX +
            WHERE_CLAUSE_REGEX + EMPTY_REGEX;

   private static final String INSERT_REGEX = EMPTY_REGEX +
            "INSERT" + SPACE_REGEX + "INTO" + SPACE_REGEX + "(.+)" + SPACE_REGEX + "(\\(" + SPACE_REGEX + "(.+)" + SPACE_REGEX + "\\))?"
            "VALUES" + SPACE_REGEX + "\\(" + SPACE_REGEX + "(.+)" + SPACE_REGEX + "\\)" + EMPTY_REGEX;

   private static final String DELETE_REGEX = EMPTY_REGEX +
            "DELETE" + SPACE_REGEX + "FROM" + SPACE_REGEX + "(.+)" + SPACE_REGEX +
            WHERE_CLAUSE_REGEX + EMPTY_REGEX;
   
   private static final String IDENTIFIER_REGEX = "([\\w]*)";
   private static final String COLUMN_REGEX = IDENTIFIER_REGEX + "[\\.]" + IDENTIFIER_REGEX;
   private static final String TABLE_REGEX = IDENTIFIER_REGEX + "(" + SPACE_REGEX + "(AS" + SPACE_REGEX + ")?" + IDENTIFIER_REGEX + ")?";

   
   private static final Pattern SELECT_PATTERN = Pattern.compile(SELECT_REGEX, Pattern.CASE_INSENSITIVE);
   private static final Pattern UPDATE_PATTERN = Pattern.compile(UPDATE_REGEX, Pattern.CASE_INSENSITIVE);
   private static final Pattern INSERT_PATTERN = Pattern.compile(INSERT_REGEX, Pattern.CASE_INSENSITIVE);
   private static final Pattern DELETE_PATTERN = Pattern.compile(DELETE_REGEX, Pattern.CASE_INSENSITIVE);
   private static final Pattern COLUMN_PATTERN = Pattern.compile(COLUMN_REGEX, Pattern.CASE_INSENSITIVE);
   private static final Pattern TABLE_PATTERN = Pattern.compile(TABLE_REGEX, Pattern.CASE_INSENSITIVE);


ALeksandriys писал(а):
Скиньте плиз пример группировки запросов с общими аргументами.

Это называется кластерный анализ. Думаю для начала Вам надо самому что-то почитать по этой теме, подумать как реализовать алгоритм, и уже потом, если что-то не получиться, обратиться на форум с конкретными вопросами.
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
ALeksandriys : 22
Новичок

СообщениеОкт 16, 2006 12:04 
Ответить с цитатой
Спасибо тебе большое за помощь!!!! Я разобрался с кластерным анализом, но есть вопрос, можно скинуть ссылочку на его реализацию на Ява, чтобы я мог хоть от чего нибудь отталкиваться, а то я пытался с нуля сделать у меня не выходит, я путаюсь в ветках.
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
ALeksandriys : 22
Новичок

СообщениеОкт 20, 2006 21:26 
Ответить с цитатой
Подскажите плиз! Как получить инфу из запроса про условия выборки и сортировки?
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
gesser : 3589
JavaTalks Team Member

СообщениеОкт 22, 2006 16:50 
Ответить с цитатой
ALeksandriys писал(а):
Подскажите плиз! Как получить инфу из запроса про условия выборки и сортировки?


Вы говорите про SQL?
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
ALeksandriys : 22
Новичок

СообщениеОкт 22, 2006 23:18 
Ответить с цитатой
gesser писал(а):
ALeksandriys писал(а):
Подскажите плиз! Как получить инфу из запроса про условия выборки и сортировки?


Вы говорите про SQL?


Да абсолютно точно! Я знаю как получать информацию о таблицах и колонках, а теперь мне надо как получать о информацию из раздела Where, Group by, Order by, т.е об условиях выборки, группировки и сортировки! Crying or Very sad
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
ALeksandriys : 22
Новичок

СообщениеОкт 23, 2006 17:09 
Ответить с цитатой
Как реализовать проверку соотвествия запросов пороговому значению для определения этих запросов в кадидаты на шаблон, исходя из этого алгоритма?

Есть X запросов с одинаковым содержимым поля FROM
Есть порог K (K<1).
Есть множество условий, которые встречаются в этих запросов.
Можно посчитать количество Ni условия Ui из множества условий, которые встречаются в запросах Х
Если Ni > X*K, то условие Ui попадает в шаблон.

Как реализовать переменную например "H", в которой будет храниться количество кандидатов на шаблон! По окочанию каждого прхода цикла проверки значение этой переменной, при Ni = true, должно возрасти на единицу H++. Если это значение после прохода цикла заданное количество раз, допустим получиться больше 5-ти, то сообщить что шаблон строить целесообразно, иначе нецелесообразно.
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
pavlentus : 12
Новичок

СообщениеОкт 24, 2006 18:40 
Ответить с цитатой
Думаю слету это не реально, страницы 2 кода точно
К началу Посмотреть профиль Отправить личное сообщение
Vlad : 1670
JavaTalks Team Member
Откуда: ODS-KRK-LON-HFE

СообщениеОкт 25, 2006 0:41 
Ответить с цитатой
ALeksandriys писал(а):
Есть множество условий, которые встречаются в этих запросов.

Думаю, для начала надо определить какие типы условий будут парситься и точнее какая информация из них важна, т.к. разнообразие выражения WHERE практически не имеет границ.

ALeksandriys писал(а):
Как реализовать переменную например "H", в которой будет храниться количество кандидатов на шаблон!

Код:
private int _templateCandidateCount = 0; // количество кандидатов на шаблон :)


ALeksandriys писал(а):
По окочанию каждого прхода цикла проверки...

Код:

_templateCandidateCount = 0;
for (int i=0; i < T /* "заданное количество раз" */; i++) {
  // Calculate N
  // ...
  if (N > K*x) { // "Ni = true" :)
    _templateCandidateCount++;
  }
}
if (_templateCandidateCount > 5) {
  System.out.println("шаблон строить целесообразно");
} else {
  System.out.println("шаблон строить нецелесообразно");
}

Это то, что можно реализовать по приведенному тобой алгоритму. Rolling Eyes
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
ALeksandriys : 22
Новичок

СообщениеОкт 25, 2006 12:46 
Ответить с цитатой
Влад спасибо за помощь! Подскажи плиз, как получить инфу из запроса про условия выборки, сортировки и группировки, у них алгоритм такой же как с полями и таблицами?
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
Vlad : 1670
JavaTalks Team Member
Откуда: ODS-KRK-LON-HFE

СообщениеОкт 25, 2006 13:48 
Ответить с цитатой
ALeksandriys писал(а):
Влад спасибо за помощь!

Eto ne obiazatel'no pisat' v kazhdom topike, tem bolee 4to "спасибо" v karman ne polozhysh Wink
ALeksandriys писал(а):
как получить инфу из запроса про условия выборки, сортировки и группировки, у них алгоритм такой же как с полями и таблицами?

Analogi4nyj, no
Vlad писал(а):
для начала надо определить какие типы условий будут парситься и точнее какая информация из них важна, т.к. разнообразие выражения WHERE практически не имеет границ.

..., 4toby mozhno bylo sozdat' nuzhnye reguliarnye vyrazhenija (naprimer, tolko dlia vyrazhenija tipa: "WHERE (value|col_id)=(value|col_id) ((AND|OR) (value|col_id)=(value|col_id))*"). Tiazhelo realizovat', esli imeesh proizvolnoe WHERE vyrazhenie (s vlozhennymi uslovyjami, raznymi EXISTS, BEETWEEN, IN, podzaprosami v konce koncov) - v etom slu4ae leg4e opredelitsa kakayu infu iz etoj vsej ku4i nado vytaschit' i po kakim harakteristikam (naprimer, tol'ko nazwanija polej i tablic na osnove polu4ennych is razbora SELECT i FROM dannyh).

PS. 4to eto u tebia za proekt takoj strannyj - kakaya kone4naya cel?
К началу Посмотреть профиль Отправить личное сообщение Посетить сайт автора
ALeksandriys : 22
Новичок

СообщениеОкт 25, 2006 21:44 
Ответить с цитатой
Насчет спасибо, это пока все чем я могу показать свою благодарность за помощь! Это мой дипломный проект конечная цель этой программы получить шаблон согласно критериям отбора, шаблон - это совокупность запросов схожих по своей характеристике, их схожесть опеределяеться пороговым значением (или критерием попадания в шаблон), задеться переменная статистики значение которой увеличиваеться каждый раз когда запрос попадает в кандидаты на шаблон, в конце переменная статистики сравниваеться с константой количества кандидатов на шаблон (значение ее задаеться в начале программы) и в случае если положительный ответ, делаеться заключение о целесообразности создания шаблона - вот этот кусочек сравнения всех переменных мне и осталось реализовать. Rolling Eyes
К началу Посмотреть профиль Отправить личное сообщение Отправить e-mail ICQ Number
 
Начать новую тему  Ответить на тему
Страница 1 из 2
На страницу 1, 2  След.
Список форумов
 -> Другие технологии


 
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Java and all Java-related trademarks and logos are trademarks or registered trademarks of Oracle Corporation in the United States and other countries.
Это сайт не относится к фирме Oracle Corporation и не поддерживается ею.

© 2006-2010 www.javatalks.ru: форум java программистов
Используется скрипт phpBB © 2001, 2010 phpBB Group

Хостинг от bizname.ru