Created
September 13, 2012 15:11
-
-
Save andreyp/3714974 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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