Skip to content

Instantly share code, notes, and snippets.

@andreyp
Created September 13, 2012 15:11
Show Gist options
  • Save andreyp/3714974 to your computer and use it in GitHub Desktop.
Save andreyp/3714974 to your computer and use it in GitHub Desktop.
from struct import pack, unpack, calcsize
import cStringIO
def sphinx_unpack(fmt, fp):
return unpack(fmt, fp.read(calcsize(fmt)))
def parse_query_result(data, query_count):
data = cStringIO.StringIO(data)
result = []
for i in xrange(0, query_count):
res = {'error': None,
'warning': None,
'fields': [],
'attrs': [],
'matches': [],
'total': 0,
'total_found': 0,
'time': None,
'words': [], }
result.append(res)
status = sphinx_unpack('>L', data)[0]
if status != SEARCHD_OK:
length = sphinx_unpack('>L', data)[0]
message = data.read(length)
if status == SEARCHD_WARNING:
res['warning'] = message
else:
res['error'] = message
continue
fields_count = sphinx_unpack('>L', data)[0]
while fields_count and data:
fields_count -= 1
length = sphinx_unpack('>L', data)[0]
field = data.read(length)
res['fields'].append(field)
attrs_count = sphinx_unpack('>L', data)[0]
while attrs_count and data:
attrs_count -= 1
length = sphinx_unpack('>L', data)[0]
attr, data = data.read(length)
attr_type = sphinx_unpack('>L', data)[0]
res['attrs'].append([attr, attr_type])
count = sphinx_unpack('>L', data)[0]
id64 = sphinx_unpack('>L', data)[0]
while count and data:
count -= 1
if id64:
doc, weight = sphinx_unpack('>QL', data)
else:
doc, weight = sphinx_unpack('>2L', data)
match = {'id': doc, 'weight': weight, 'attrs': {}}
for i, attr in enumerate(res['attrs']):
if attr[1] == SPH_ATTR_FLOAT:
match['attrs'][attr[0]] = sphinx_unpack('>f', data)[0]
elif attr[1] == SPH_ATTR_BIGINT:
match['attrs'][attr[0]] = sphinx_unpack('>q', data)[0]
elif attr[1] == SPH_ATTR_STRING:
slen = sphinx_unpack('>L', data)[0]
match['attrs'][attr[0]] = data.read(slen) if slen else ''
elif attr[1] == (SPH_ATTR_MULTI | SPH_ATTR_INTEGER):
values_count = sphinx_unpack('>L', data)[0]
vals = []
for n in xrange(0, values_count):
vals.append(sphinx_unpack('>L', data)[0])
match['attrs'][attr[0]] = vals
else:
match['attrs'][attr[0]] = sphinx_unpack('>L', data)[0]
res['matches'].append(match)
(res['total'], res['total_found'],
res['time'], words) = sphinx_unpack('>4L', data)
while words:
words -= 1
length = sphinx_unpack('>L', data)[0]
word = data.read(length)
docs, hits = sphinx_unpack('>2L', data)
res['words'].append(dict(word=word, docs=docs, hits=hits))
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment