docs: def get_results(self, params=None, result_id=None):
          """
          Return all the results available from the database that fulfill some
          parameter combinations.
  
          If params is None (or not specified), return all results.
  
          If params is specified, it must be a dictionary specifying the result
          values we are interested in, with multiple values specified as lists.
  
          For example, if the following params value is used::
  
              params = {
              'param1': 'value1',
              'param2': ['value2', 'value3']
              }
  
          the database will be queried for results having param1 equal to value1,
          and param2 equal to value2 or value3.
  
          Not specifying a value for all the available parameters is allowed:
          unspecified parameters are assumed to be 'free', and can take any
          value.
  
          Returns:
              A list of results matching the query. Returned results have the
              same structure as results inserted with the insert_result method.
          """
  
          # In this case, return all results
          # A cast to dict is necessary, since self.db.table() contains TinyDB's
          # Document object (which is simply a wrapper for a dictionary, thus the
          # simple cast).
          if result_id is not None:
              return [dict(i) for i in self.db.table('results').all() if
                      i['meta']['id'] == result_id]
  
          if params is None:
              return [dict(i) for i in self.db.table('results').all()]
  
          # Verify parameter format is correct
          all_params = set(['RngRun'] + self.get_params())
          param_subset = set(params.keys())
          if (not all_params.issuperset(param_subset)):
              raise ValueError(
                  '%s:\nParameters: %s\nQuery: %s' % (
                      'Specified parameter keys do not match database format',
                      all_params,
                      param_subset))
  
          # Convert values that are not lists into lists to later perform
          # iteration over values more naturally. Perform this on a new
          # dictionary not to modify the original copy.
          query_params = {}
          for key in params:
              if not isinstance(params[key], list):
                  query_params[key] = [params[key]]
              else:
                  query_params[key] = params[key]
  
          # Handle case where query params has no keys
          if not query_params.keys():
              return [dict(i) for i in self.db.table('results').all()]
  
          # Create the TinyDB query
          # In the docstring example above, this is equivalent to:
          # AND(OR(param1 == value1), OR(param2 == value2, param2 == value3))
          query = reduce(and_, [reduce(or_, [
              where('params')[key] == v for v in value]) for key, value in
                                query_params.items()])
  
          return [dict(i) for i in self.db.table('results').search(query)]