Show
Ignore:
Timestamp:
02/03/2010 06:45:12 PM (7 months ago)
Author:
matt
Message:

Work on NUMERIC, DATETIME, and BOOLEAN field types.
Changes instances of test_index to testindex.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • projects/whoosh/trunk/src/whoosh/fields.py

    r407 r415  
    1919""" 
    2020 
    21 import datetime 
    22 import re 
     21import datetime, re, struct 
    2322 
    2423from whoosh.analysis import IDAnalyzer, RegexAnalyzer, KeywordAnalyzer 
     
    3231class UnknownFieldError(Exception): 
    3332    pass 
    34  
    3533 
    3634 
     
    6866     
    6967    format = vector = scorable = stored = unique = None 
     68    parse_query = None 
    7069    indexed = True 
    7170    __inittypes__ = dict(format=Format, vector=Format, 
     
    108107        if not self.format: 
    109108            raise Exception("%s field cannot index without a format" % self.__class__) 
    110          
    111109        if not isinstance(value, unicode): 
    112110            raise ValueError("%r is not unicode" % value) 
    113          
    114111        return self.format.word_values(value, mode="index", **kwargs) 
     112     
     113    def process_text(self, qstring, mode='', **kwargs): 
     114        if not self.format: 
     115            raise Exception("%s field has no format" % self) 
     116        return (t.text for t in self.format.analyze(qstring, mode=mode, **kwargs)) 
    115117     
    116118 
     
    123125    __inittypes__ = dict(stored=bool, unique=bool, field_boost=float) 
    124126     
    125     def __init__(self, stored = False, unique = False, field_boost = 1.0): 
     127    def __init__(self, stored=False, unique=False, field_boost=1.0): 
    126128        """ 
    127129        :param stored: Whether the value of this field is stored with the document. 
    128130        """ 
    129         self.format = Existence(analyzer = IDAnalyzer(), field_boost = field_boost) 
     131        self.format = Existence(analyzer=IDAnalyzer(), field_boost= field_boost) 
    130132        self.stored = stored 
    131133        self.unique = unique 
     
    139141    __inittypes__ = dict(stored=bool, unique=bool, expression=bool, field_boost=float) 
    140142     
    141     def __init__(self, stored = False, unique = False, expression = None, field_boost = 1.0): 
     143    def __init__(self, stored=False, unique=False, expression=None, field_boost=1.0): 
    142144        """ 
    143145        :param stored: Whether the value of this field is stored with the document. 
     
    155157 
    156158 
     159class NUMERIC(FieldType): 
     160    def __init__(self, type=int, stored=False, unique=False, field_boost=1.0): 
     161        self.type = type 
     162        self.stored = stored 
     163        self.unique = unique 
     164        self.format = Existence(analyzer=IDAnalyzer(), field_boost= field_boost) 
     165     
     166    def index(self, num): 
     167        method = getattr(self, self.type.__name__ + "_to_text") 
     168        return [(method(num), 1, '')] 
     169     
     170    def to_text(self, x): 
     171        ntype = self.type 
     172        method = getattr(self, ntype.__name__ + "_to_text") 
     173        return method(ntype(x)) 
     174     
     175    def process_text(self, text, **kwargs): 
     176        return (self.to_text(text), ) 
     177     
     178    def parse_query(self, fieldname, qstring, boost=1.0): 
     179        from whoosh import query 
     180        return query.Term(fieldname, self.to_text(qstring), boost=boost) 
     181     
     182    @staticmethod 
     183    def int_to_text(x): 
     184        x += (1<<(4<<2))-1 # 4 means 32-bits 
     185        return u"%08x" % x 
     186     
     187    @staticmethod 
     188    def text_to_int(text): 
     189        x = int(text, 16) 
     190        x -= (1<<(4<<2))-1 
     191        return x 
     192     
     193    @staticmethod 
     194    def long_to_text(x): 
     195        x += (1<<(8<<2))-1 
     196        return u"%016x" % x 
     197     
     198    @staticmethod 
     199    def text_to_long(text): 
     200        x = long(text, 16) 
     201        x -= (1<<(8<<2))-1 
     202        return x 
     203     
     204    @staticmethod 
     205    def float_to_text(x): 
     206        x = struct.unpack("<q", struct.pack("<d", x))[0] 
     207        x += (1<<(8<<2))-1 
     208        return u"%016x" % x 
     209     
     210    @staticmethod 
     211    def text_to_float(text): 
     212        x = long(text, 16) 
     213        x -= (1<<(8<<2))-1 
     214        x = struct.unpack("<d", struct.pack("<q", x))[0] 
     215        return x 
     216     
     217 
    157218class DATETIME(FieldType): 
    158219    __inittypes__ = dict(stored=bool, unique=bool) 
    159220     
    160     def __init__(self, stored = True, unique = False): 
     221    def __init__(self, stored=False, unique=False): 
    161222        """ 
    162223        :param stored: Whether the value of this field is stored with the document. 
     
    172233            raise ValueError("Value of DATETIME field must be a datetime object: %r" % dt) 
    173234         
    174         text = dt.isoformat() 
     235        text = dt.isoformat() # 2010-02-02T17:06:19.109000 
    175236        text = text.replace(" ", "").replace(":", "").replace("-", "").replace(".", "") 
    176237        return [(text, 1, '')] 
     238     
     239    def process_text(self, text, **kwargs): 
     240        text = text.replace(" ", "").replace(":", "").replace("-", "").replace(".", "") 
     241        return (text, ) 
     242     
     243    def parse_query(self, fieldname, qstring, boost=1.0): 
     244        text = self.process_text(qstring) 
     245        from whoosh import query 
     246        return query.Prefix(fieldname, text, boost=boost) 
     247     
     248 
     249class BOOLEAN(FieldType): 
     250    strings = (u"t", u"f") 
     251    trues = frozenset((u"t", u"true", u"yes", u"1")) 
     252    falses = frozenset((u"f", u"false", u"no", u"0")) 
     253     
     254    __inittypes__ = dict(stored=bool) 
     255     
     256    def __init__(self, stored=False): 
     257        self.stored = stored 
     258        self.format = Existence() 
     259     
     260    def index(self, bit): 
     261        if not isinstance(bit, bool): 
     262            raise ValueError("Value of BOOL field must be a bool object: %r" % bit) 
     263        return [(self.strings[int(bit)], 1, '')] 
     264     
     265    def parse_query(self, fieldname, qstring, boost=1.0): 
     266        from whoosh import query 
     267        text = None 
     268        if qstring in self.falses: 
     269            text = self.strings[0] 
     270        elif qstring in self.trues: 
     271            text = self.strings[1] 
     272         
     273        if text is None: 
     274            return query.NullQuery 
     275        return query.Term(fieldname, text, boost=boost) 
    177276     
    178277