nodes: 0, module; 1, function_definition; 2, function_name:search; 3, parameters; 4, block; 5, identifier:self; 6, identifier:rtype; 7, dictionary_splat_pattern; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, if_statement; 18, expression_statement; 19, if_statement; 20, expression_statement; 21, expression_statement; 22, expression_statement; 23, expression_statement; 24, expression_statement; 25, expression_statement; 26, if_statement; 27, expression_statement; 28, if_statement; 29, return_statement; 30, identifier:kwargs; 31, comment:""" Search for the model by assorted criteria
  
          Quite a bit needs to happen for a search processing!
  
          The breakdown is we need to apply the query parameters
          where applicable. These include pagination, sorting,
          & filtering.
  
          Additionally, models can declare there own static
          filters or static query that should be applied. For
          static filters a model can opt-in with a `search_filters`
          property & for a static query to append a `search_query`
          property must be present.
          """; 32, assignment; 33, assignment; 34, assignment; 35, assignment; 36, assignment; 37, assignment; 38, assignment; 39, augmented_assignment; 40, identifier:filters; 41, block; 42, assignment; 43, boolean_operator; 44, block; 45, elif_clause; 46, augmented_assignment; 47, augmented_assignment; 48, augmented_assignment; 49, call; 50, assignment; 51, assignment; 52, identifier:models; 53, block; 54, assignment; 55, boolean_operator; 56, block; 57, identifier:models; 58, identifier:model; 59, call; 60, identifier:param; 61, dictionary; 62, identifier:pages; 63, call; 64, identifier:sorts; 65, call; 66, identifier:query; 67, comment:"""
                  SELECT {cols}, count(*) OVER() as _count
                  FROM {table}
                  """; 68, identifier:query; 69, call; 70, identifier:filters; 71, call; 72, identifier:filters; 73, boolean_operator; 74, expression_statement; 75, expression_statement; 76, identifier:model_query; 77, boolean_operator; 78, identifier:filters; 79, identifier:model_query; 80, expression_statement; 81, identifier:model_query; 82, block; 83, identifier:query; 84, identifier:model_query; 85, identifier:query; 86, identifier:sorts; 87, identifier:query; 88, identifier:pages; 89, attribute; 90, argument_list; 91, identifier:result; 92, call; 93, identifier:models; 94, list_comprehension; 95, expression_statement; 96, identifier:pages; 97, call; 98, identifier:pages; 99, identifier:result; 100, expression_statement; 101, identifier:rtype_to_model; 102, argument_list; 103, attribute; 104, argument_list; 105, attribute; 106, argument_list; 107, attribute; 108, argument_list; 109, attribute; 110, argument_list; 111, call; 112, list; 113, assignment; 114, augmented_assignment; 115, call; 116, string; 117, assignment; 118, expression_statement; 119, attribute; 120, identifier:send; 121, attribute; 122, keyword_argument; 123, attribute; 124, argument_list; 125, call; 126, for_in_clause; 127, call; 128, attribute; 129, argument_list; 130, assignment; 131, identifier:rtype; 132, identifier:self; 133, identifier:pages_query; 134, call; 135, identifier:self; 136, identifier:sorts_query; 137, call; 138, identifier:query; 139, identifier:format; 140, keyword_argument; 141, keyword_argument; 142, identifier:kwargs; 143, identifier:get; 144, string; 145, list; 146, identifier:getattr; 147, argument_list; 148, pattern_list; 149, call; 150, identifier:query; 151, identifier:where; 152, identifier:getattr; 153, argument_list; 154, identifier:model_query; 155, binary_operator:' AND ' + model_query; 156, assignment; 157, identifier:signals; 158, identifier:pre_search; 159, identifier:model; 160, identifier:__class__; 161, identifier:model; 162, identifier:model; 163, identifier:self; 164, identifier:query; 165, identifier:query; 166, keyword_argument; 167, identifier:model; 168, argument_list; 169, identifier:res; 170, identifier:result; 171, attribute; 172, argument_list; 173, identifier:kwargs; 174, identifier:get; 175, string; 176, attribute; 177, subscript; 178, attribute; 179, argument_list; 180, attribute; 181, argument_list; 182, identifier:cols; 183, call; 184, identifier:table; 185, identifier:rtype; 186, string_content:filters; 187, identifier:model; 188, string; 189, list; 190, identifier:where; 191, identifier:param; 192, attribute; 193, argument_list; 194, identifier:model; 195, string; 196, string; 197, string; 198, identifier:model_query; 199, identifier:model_query; 200, binary_operator:' WHERE ' + model_query; 201, identifier:param; 202, identifier:param; 203, identifier:res; 204, attribute; 205, identifier:send; 206, attribute; 207, keyword_argument; 208, string_content:pages; 209, identifier:pages; 210, identifier:total; 211, subscript; 212, string; 213, identifier:kwargs; 214, identifier:get; 215, string; 216, identifier:kwargs; 217, identifier:get; 218, string; 219, list; 220, attribute; 221, argument_list; 222, string_content:search_filters; 223, identifier:self; 224, identifier:filters_query; 225, identifier:filters; 226, string_content:search_query; 227, string_content:AND; 228, string; 229, identifier:model_query; 230, identifier:signals; 231, identifier:post_search; 232, identifier:model; 233, identifier:__class__; 234, identifier:models; 235, identifier:result; 236, identifier:result; 237, integer:0; 238, string_content:_count; 239, string_content:pages; 240, string_content:sorts; 241, call; 242, identifier:self; 243, identifier:field_cols; 244, identifier:model; 245, string_content:WHERE; 246, identifier:Sortable; 247, argument_list; 248, attribute; 249, attribute; 250, identifier:SORT; 251, identifier:goldman; 252, identifier:config
code: def search(self, rtype, **kwargs):
          """ Search for the model by assorted criteria
  
          Quite a bit needs to happen for a search processing!
  
          The breakdown is we need to apply the query parameters
          where applicable. These include pagination, sorting,
          & filtering.
  
          Additionally, models can declare there own static
          filters or static query that should be applied. For
          static filters a model can opt-in with a `search_filters`
          property & for a static query to append a `search_query`
          property must be present.
          """
  
          model = rtype_to_model(rtype)
          param = {}
          pages = self.pages_query(kwargs.get('pages'))
          sorts = self.sorts_query(kwargs.get(
              'sorts', [Sortable(goldman.config.SORT)]
          ))
  
          query = """
                  SELECT {cols}, count(*) OVER() as _count
                  FROM {table}
                  """
          query = query.format(
              cols=self.field_cols(model),
              table=rtype,
          )
  
          filters = kwargs.get('filters', [])
          filters += getattr(model, 'search_filters', []) or []
  
          if filters:
              where, param = self.filters_query(filters)
              query += where
  
          model_query = getattr(model, 'search_query', '') or ''
          if filters and model_query:
              model_query = ' AND ' + model_query
          elif model_query:
              model_query = ' WHERE ' + model_query
  
          query += model_query
          query += sorts
          query += pages
  
          signals.pre_search.send(model.__class__, model=model)
  
          result = self.query(query, param=param)
          models = [model(res) for res in result]
  
          if models:
              signals.post_search.send(model.__class__, models=result)
  
          pages = kwargs.get('pages')
          if pages and result:
              pages.total = result[0]['_count']
  
          return models