/* Defining a query using lambda function to search specific key 
 */
 public void key_value_search(DBEngine<int, DBElement<int, string>> db, IQuery<int, DBElement<int, string>> i_query, QueryEngine<int, DBElement<int, string>> qe )
 {
     "Query for value with specified key (key = 2):".title();
     WriteLine();
     int key_to_search = 2;
     Func<int, string, bool> keyValueSearch = (int key, string search) => //lambda function
     {
         if (!db.Keys().Contains(key))
             return false;
         else
         {
             if (key == int.Parse(search))
             {
                 DBElement<int, string> ele = new DBElement<int, string>();
                 db.getValue(key, out ele);
                 return true;
             }
             else { return false; }
         }
     };
     // pass query to query engine and call simpleQuery to make query on DBEngine
     qe.simpleQuery(keyValueSearch, key_to_search.ToString(), out i_query);
     WriteLine();
     foreach (var key in i_query.Keys())
     {
         DBElement<int, string> temp = new DBElement<int, string>();
         i_query.getValue(key, out temp);
         WriteLine("key : {0}", key);
         temp.showElement();
         WriteLine();
     }
 }
    /* Defining a query using lambda function to search specific key 
    */
    public bool key_value_search(DBEngine<string, DBElement<string, List<string>>> db, out IQuery<string, DBElement<string, List<string>>> i_query, QueryEngine<string, DBElement<string, List<string>>> qe, string key_to_search = "12345")
    {
      "Query for value with specified key (key = element2):".title();
      WriteLine();

      Func<string, string, bool> keyValueSearch = (string key, string search) => //lambda function
      {
        if (!db.Keys().Contains(key))
          return false;
        else
        {
          if (key == (search))
          {
            DBElement<string, List<string>> ele = new DBElement<string, List<string>>();
            db.getValue(key, out ele);
            return true;
          }
          else { return false; }
        }
      };
      // pass query to query engine and call simpleQuery to make query on DBEngine

      if (qe.simpleQuery(keyValueSearch, key_to_search.ToString(), out i_query))
      {
        WriteLine();
        foreach (var key in i_query.Keys())
        {
          DBElement<string, List<string>> temp = new DBElement<string, List<string>>();
          i_query.getValue(key, out temp);
          WriteLine("key : {0}", key);
          temp.showEnumerableElement();
          WriteLine();
        }
        return true;
      }
      else
      {
        return false;
      }
    }
 /* Defining a query using lambda function to search specific elements belonging in specific  
 *  time-interval with end of time interval equal to present
 */
 public void date_time_specific(DBEngine<string, DBElement<string, List<string>>> db, out IQuery<string, DBElement<string, List<string>>> i_query, QueryEngine<string, DBElement<string, List<string>>> qe, DateTime start, DateTime end = new DateTime())
 {
   "Query for keys with specified date time interval: start=10/4/2015 end=10/5/2015".title();
   WriteLine();
   Func<string, DateTime, DateTime, bool> TimeDateQuery = (string key, DateTime query_start, DateTime query_end) => //lambda function
   {
     if (!db.Keys().Contains(key))
       return false;
     else
     {
       DBElement<string, List<string>> ele = new DBElement<string, List<string>>();
       db.getValue(key, out ele);
       int start_result = DateTime.Compare(query_start, ele.timeStamp);
       int end_result = DateTime.Compare(query_end, ele.timeStamp);
       if ((start_result <= 0) && (end_result >= 0))
       {
         return true;
       }
       else return false;
     }
   };
   // pass query to query engine and call simpleQuery to make query on DBEngine
   qe.simpleQueryDate(TimeDateQuery, out i_query, start, end);
   WriteLine();
   foreach (var key in i_query.Keys())
   {
     DBElement<string, List<string>> temp = new DBElement<string, List<string>>();
     i_query.getValue(key, out temp);
     WriteLine("key : {0}", key);
     temp.showEnumerableElement();
     WriteLine();
   }
 }
 /* Defining a query using lambda function to search specific string in metadata 
 */
 public bool metadata_string(DBEngine<string, DBElement<string, List<string>>> db, out IQuery<string, DBElement<string, List<string>>> i_query, QueryEngine<string, DBElement<string, List<string>>> qe, string metadata_str = "ele")
 {
   "Query for specified string in metadata: String = 'ele' ".title();
   WriteLine();
   Func<string, string, bool> stringMetadata = (string key, string search) => //lambda function
   {
     if (!db.Keys().Contains(key))
       return false;
     else
     {
       DBElement<string, List<string>> ele = new DBElement<string, List<string>>();
       db.getValue(key, out ele);
       if (ele.name.Contains(search) || ele.descr.Contains(search))
         return true;
       else return false;
     }
   };
   // pass query to query engine and call simpleQuery to make query on DBEngine
   if (qe.simpleQuery(stringMetadata, metadata_str, out i_query))
   {
     WriteLine();
     foreach (var key in i_query.Keys())
     {
       DBElement<string, List<string>> temp = new DBElement<string, List<string>>();
       i_query.getValue(key, out temp);
       WriteLine("key : {0}", key);
       temp.showEnumerableElement();
       WriteLine();
     }
     return true;
   } else
   {
     return false;
   }
 }
    /* Defining a query using lambda function to search specific key matching default pattern
    */
    public void default_pattern_matching(DBEngine<string, DBElement<string, List<string>>> db, out IQuery<string, DBElement<string, List<string>>> i_query, QueryEngine<string, DBElement<string, List<string>>> qe)
    {
      string pattern = "";
      "Query for keys matching with specified pattern (pattern = none  -> default case):".title();
      WriteLine();
      Func<string, string, bool> keysMatchingPattern = (string key, string search) => //lambda function
      {
        if (!db.Keys().Contains(key))
          return false;
        else
        {
          if (key.ToString().Contains(search))
          {
            DBElement<string, List<string>> ele = new DBElement<string, List<string>>();
            db.getValue(key, out ele);
            return true;
          }
          else return false;
        }
      };
      // pass query to query engine and call simpleQuery to make query on DBEngine
      qe.simpleQuery(keysMatchingPattern, pattern, out i_query);
      WriteLine();
      foreach (var key in i_query.Keys())
      {
        DBElement<string, List<string>> temp = new DBElement<string, List<string>>();
        i_query.getValue(key, out temp);
        WriteLine("key : {0}", key);
        temp.showEnumerableElement();
        WriteLine();
      }

    }
 private void display_children(IQuery<string, DBElement<string, List<string>>> i_query, DBEngine<string, DBElement<string, List<string>>> db)
 {
   foreach (var key in i_query.Keys())
   {
     DBElement<string, List<string>> temp = new DBElement<string, List<string>>();
     i_query.getValue(key, out temp);
     WriteLine("children of element with key {0} :", key);
     WriteLine();
     if (temp.children != null)
     {
       int i = 0;
       foreach (string child in temp.children)
       {
         WriteLine("Children {0}", ++i);
         DBElement<string, List<string>> temp_child = new DBElement<string, List<string>>();
         if (db.Keys().Contains(child))
         {
           db.getValue(child, out temp_child);
           WriteLine("key : {0}", child);
           temp_child.showEnumerableElement();
           WriteLine();
         }
         else
         {
           WriteLine("no value with key {0} is present in database", child);
           WriteLine();
         }
       }
     }
   }
 }
 /* Defining a query using lambda function to search children of specific element 
 */
 public void key_children_search(DBEngine<int, DBElement<int, string>> db, IQuery<int, DBElement<int, string>> i_query, QueryEngine<int, DBElement<int, string>> qe)
 {
     int specific_key = 2;
     "Query for children of specified key (key = 2):".title();
     WriteLine();
     Func<int, string, bool> childrenQuery = (int key, string search) => //lambda function
     {
         if (!db.Keys().Contains(key))
             return false;
         if (key == int.Parse(search))
         {
             DBElement<int, string> ele = new DBElement<int, string>();
             db.getValue(key, out ele);
             return true;
         }
         else return false;
     };
     // pass query to query engine and call simpleQuery to make query on DBEngine
     qe.simpleQuery(childrenQuery, specific_key.ToString(), out i_query);
     WriteLine();
     foreach (var key in i_query.Keys())
     {
         DBElement<int, string> temp = new DBElement<int, string>();
         i_query.getValue(key, out temp);
         WriteLine("children of element with key {0} :", key);
         WriteLine();
         if (temp.children != null)
         {
             int i = 0;
             foreach (int child in temp.children)
             {
                 WriteLine("Children {0}", i++);
                 DBElement<int, string> temp_child = new DBElement<int, string>();
                 if (db.Keys().Contains(child))
                 {
                     db.getValue(child, out temp_child);
                     WriteLine("key : {0}", child);
                     temp_child.showElement();
                     WriteLine();
                 }
                 else
                 {
                     WriteLine("no value with key {0} is present in database", child);
                     WriteLine();
                 }
             }
         }
     }
 }