Skip to content

Commit a855728

Browse files
author
Richard Jones
committed
indexing may be turned off for FileClass "content" now
1 parent f9457e5 commit a855728

File tree

8 files changed

+132
-79
lines changed

8 files changed

+132
-79
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Feature:
88
Fixed:
99
- progress display in roundup-admin reindex
1010
- bug in menu() permission filter (sf bug 1444440)
11+
- indexing may be turned off for FileClass "content" now
12+
("content" and "type" properties are now automatically included in the
13+
FileClass schema where previously the "content" property was faked and
14+
"type" was optional)
1115

1216

1317
2006-03-03 1.1.1

roundup/backends/back_anydbm.py

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.197 2006-03-03 02:51:13 richard Exp $
18+
#$Id: back_anydbm.py,v 1.198 2006-04-27 01:39:47 richard Exp $
1919
'''This module defines a backend that saves the hyperdatabase in a
2020
database chosen by anydbm. It is guaranteed to always be available in python
2121
versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
@@ -2023,7 +2023,15 @@ class FileClass(hyperdb.FileClass, Class):
20232023
"default_mime_type" class attribute, which may be overridden by each
20242024
node if the class defines a "type" String property.
20252025
'''
2026-
default_mime_type = 'text/plain'
2026+
def __init__(self, db, classname, **properties):
2027+
'''The newly-created class automatically includes the "content"
2028+
and "type" properties.
2029+
'''
2030+
if not properties.has_key('content'):
2031+
properties['content'] = hyperdb.String(indexme='yes')
2032+
if not properties.has_key('type'):
2033+
properties['type'] = hyperdb.String()
2034+
Class.__init__(self, db, classname, **properties)
20272035

20282036
def create(self, **propvalues):
20292037
''' Snarf the "content" propvalue and store in a file
@@ -2093,47 +2101,37 @@ def set(self, itemid, **propvalues):
20932101

20942102
# do content?
20952103
if content:
2096-
# store and index
2104+
# store and possibly index
20972105
self.db.storefile(self.classname, itemid, None, content)
2098-
mime_type = None
2099-
if self.getprops().has_key('type'):
2100-
mime_type = propvalues.get('type', self.get(itemid, 'type'))
2101-
if not mime_type:
2102-
mime_type = self.default_mime_type
2103-
self.db.indexer.add_text((self.classname, itemid, 'content'),
2104-
content, mime_type)
2105-
2106+
if self.properties['content'].indexme:
2107+
mime_type = self.get(itemid, 'type', self.default_mime_type)
2108+
self.db.indexer.add_text((self.classname, itemid, 'content'),
2109+
content, mime_type)
21062110
propvalues['content'] = content
21072111

21082112
# fire reactors
21092113
self.fireReactors('set', itemid, oldvalues)
21102114
return propvalues
21112115

2112-
def getprops(self, protected=1):
2113-
'''In addition to the actual properties on the node, these methods
2114-
provide the "content" property. If the "protected" flag is true,
2115-
we include protected properties - those which may not be
2116-
modified.
2117-
2118-
Note that the content prop is indexed separately, hence no indexme.
2119-
'''
2120-
d = Class.getprops(self, protected=protected).copy()
2121-
d['content'] = hyperdb.String()
2122-
return d
2123-
21242116
def index(self, nodeid):
2125-
'''Add (or refresh) the node to search indexes.
2117+
''' Add (or refresh) the node to search indexes.
21262118
2127-
Pass on the content-type property for the content property.
2119+
Use the content-type property for the content property.
21282120
'''
2129-
Class.index(self, nodeid)
2130-
mime_type = None
2131-
if self.getprops().has_key('type'):
2132-
mime_type = self.get(nodeid, 'type', self.default_mime_type)
2133-
if not mime_type:
2134-
mime_type = self.default_mime_type
2135-
self.db.indexer.add_text((self.classname, nodeid, 'content'),
2136-
str(self.get(nodeid, 'content')), mime_type)
2121+
# find all the String properties that have indexme
2122+
for prop, propclass in self.getprops().items():
2123+
if prop == 'content' and propclass.indexme:
2124+
mime_type = self.get(nodeid, 'type', self.default_mime_type)
2125+
self.db.indexer.add_text((self.classname, nodeid, 'content'),
2126+
str(self.get(nodeid, 'content')), mime_type)
2127+
elif isinstance(propclass, hyperdb.String) and propclass.indexme:
2128+
# index them under (classname, nodeid, property)
2129+
try:
2130+
value = str(self.get(nodeid, prop))
2131+
except IndexError:
2132+
# node has been destroyed
2133+
continue
2134+
self.db.indexer.add_text((self.classname, nodeid, prop), value)
21372135

21382136
# deviation from spec - was called ItemClass
21392137
class IssueClass(Class, roundupdb.IssueClass):

roundup/backends/back_metakit.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: back_metakit.py,v 1.106 2006-02-09 23:53:10 richard Exp $
1+
# $Id: back_metakit.py,v 1.107 2006-04-27 01:39:47 richard Exp $
22
'''Metakit backend for Roundup, originally by Gordon McMillan.
33
44
Known Current Bugs:
@@ -1778,9 +1778,12 @@ class FileName(hyperdb.String):
17781778
class FileClass(hyperdb.FileClass, Class):
17791779
''' like Class but with a content property
17801780
'''
1781-
default_mime_type = 'text/plain'
17821781
def __init__(self, db, classname, **properties):
1783-
properties['content'] = FileName()
1782+
'''The newly-created class automatically includes the "content"
1783+
and "type" properties.
1784+
'''
1785+
if not properties.has_key('content'):
1786+
properties['content'] = hyperdb.String(indexme='yes')
17841787
if not properties.has_key('type'):
17851788
properties['type'] = hyperdb.String()
17861789
Class.__init__(self, db, classname, **properties)
@@ -1908,24 +1911,32 @@ def undo(fnm=nm):
19081911
f.write(content)
19091912
f.close()
19101913

1911-
mimetype = propvalues.get('type', self.default_mime_type)
1912-
self.db.indexer.add_text((self.classname, itemid, 'content'),
1913-
content, mimetype)
1914+
if self.properties['content'].indexme:
1915+
mimetype = self.get('type', self.default_mime_type)
1916+
self.db.indexer.add_text((self.classname, itemid, 'content'),
1917+
content, mimetype)
19141918

19151919
self.fireReactors('set', oldnode, propvalues)
19161920

19171921
def index(self, nodeid):
1918-
'''Add (or refresh) the node to search indexes.
1922+
''' Add (or refresh) the node to search indexes.
19191923
1920-
Pass on the content-type property for the content property.
1924+
Use the content-type property for the content property.
19211925
'''
1922-
Class.index(self, nodeid)
1923-
try:
1924-
mime_type = self.get(nodeid, 'type', self.default_mime_type)
1925-
except KeyError:
1926-
mime_type = self.default_mime_type
1927-
self.db.indexer.add_text((self.classname, nodeid, 'content'),
1928-
str(self.get(nodeid, 'content')), mime_type)
1926+
# find all the String properties that have indexme
1927+
for prop, propclass in self.getprops().items():
1928+
if prop == 'content' and propclass.indexme:
1929+
mime_type = self.get(nodeid, 'type', self.default_mime_type)
1930+
self.db.indexer.add_text((self.classname, nodeid, 'content'),
1931+
str(self.get(nodeid, 'content')), mime_type)
1932+
elif isinstance(propclass, hyperdb.String) and propclass.indexme:
1933+
# index them under (classname, nodeid, property)
1934+
try:
1935+
value = str(self.get(nodeid, prop))
1936+
except IndexError:
1937+
# node has been destroyed
1938+
continue
1939+
self.db.indexer.add_text((self.classname, nodeid, prop), value)
19291940

19301941
class IssueClass(Class, roundupdb.IssueClass):
19311942
''' The newly-created class automatically includes the "messages",

roundup/backends/rdbms_common.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: rdbms_common.py,v 1.168 2006-03-03 02:02:50 richard Exp $
18+
#$Id: rdbms_common.py,v 1.169 2006-04-27 01:39:47 richard Exp $
1919
''' Relational database (SQL) backend common code.
2020
2121
Basics:
@@ -2504,7 +2504,15 @@ class FileClass(hyperdb.FileClass, Class):
25042504
"default_mime_type" class attribute, which may be overridden by each
25052505
node if the class defines a "type" String property.
25062506
'''
2507-
default_mime_type = 'text/plain'
2507+
def __init__(self, db, classname, **properties):
2508+
'''The newly-created class automatically includes the "content"
2509+
and "type" properties.
2510+
'''
2511+
if not properties.has_key('content'):
2512+
properties['content'] = hyperdb.String(indexme='yes')
2513+
if not properties.has_key('type'):
2514+
properties['type'] = hyperdb.String()
2515+
Class.__init__(self, db, classname, **properties)
25082516

25092517
def create(self, **propvalues):
25102518
''' snaffle the file propvalue and store in a file
@@ -2524,8 +2532,9 @@ def create(self, **propvalues):
25242532
mime_type = propvalues.get('type', self.default_mime_type)
25252533

25262534
# and index!
2527-
self.db.indexer.add_text((self.classname, newid, 'content'), content,
2528-
mime_type)
2535+
if self.properties['content'].indexme:
2536+
self.db.indexer.add_text((self.classname, newid, 'content'),
2537+
content, mime_type)
25292538

25302539
# fire reactors
25312540
self.fireReactors('create', newid, None)
@@ -2581,35 +2590,37 @@ def set(self, itemid, **propvalues):
25812590

25822591
# do content?
25832592
if content:
2584-
# store and index
2593+
# store and possibly index
25852594
self.db.storefile(self.classname, itemid, None, content)
2586-
mime_type = None
2587-
if self.getprops().has_key('type'):
2588-
mime_type = propvalues.get('type', self.get(itemid, 'type'))
2589-
if not mime_type:
2590-
mime_type = self.default_mime_type
2591-
self.db.indexer.add_text((self.classname, itemid, 'content'),
2592-
content, mime_type)
2593-
2595+
if self.properties['content'].indexme:
2596+
mime_type = self.get(itemid, 'type', self.default_mime_type)
2597+
self.db.indexer.add_text((self.classname, itemid, 'content'),
2598+
content, mime_type)
25942599
propvalues['content'] = content
25952600

25962601
# fire reactors
25972602
self.fireReactors('set', itemid, oldvalues)
25982603
return propvalues
25992604

26002605
def index(self, nodeid):
2601-
'''Add (or refresh) the node to search indexes.
2602-
2603-
Pass on the content-type property for the content property.
2604-
'''
2605-
Class.index(self, nodeid)
2606-
mime_type = None
2607-
if self.getprops().has_key('type'):
2608-
mime_type = self.get(nodeid, 'type')
2609-
if not mime_type:
2610-
mime_type = self.default_mime_type
2611-
self.db.indexer.add_text((self.classname, nodeid, 'content'),
2612-
str(self.get(nodeid, 'content')), mime_type)
2606+
''' Add (or refresh) the node to search indexes.
2607+
2608+
Use the content-type property for the content property.
2609+
'''
2610+
# find all the String properties that have indexme
2611+
for prop, propclass in self.getprops().items():
2612+
if prop == 'content' and propclass.indexme:
2613+
mime_type = self.get(nodeid, 'type', self.default_mime_type)
2614+
self.db.indexer.add_text((self.classname, nodeid, 'content'),
2615+
str(self.get(nodeid, 'content')), mime_type)
2616+
elif isinstance(propclass, hyperdb.String) and propclass.indexme:
2617+
# index them under (classname, nodeid, property)
2618+
try:
2619+
value = str(self.get(nodeid, prop))
2620+
except IndexError:
2621+
# node has been destroyed
2622+
continue
2623+
self.db.indexer.add_text((self.classname, nodeid, prop), value)
26132624

26142625
# XXX deviation from spec - was called ItemClass
26152626
class IssueClass(Class, roundupdb.IssueClass):

roundup/hyperdb.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: hyperdb.py,v 1.118 2006-03-03 02:02:50 richard Exp $
18+
# $Id: hyperdb.py,v 1.119 2006-04-27 01:39:47 richard Exp $
1919

2020
"""Hyperdatabase implementation, especially field types.
2121
"""
@@ -855,6 +855,15 @@ class FileClass:
855855
''' A class that requires the "content" property and stores it on
856856
disk.
857857
'''
858+
default_mime_type = 'text/plain'
859+
860+
def __init__(self, db, classname, **properties):
861+
'''The newly-created class automatically includes the "content"
862+
property.
863+
'''
864+
if not properties.has_key('content'):
865+
properties['content'] = hyperdb.String(indexme='yes')
866+
858867
def export_propnames(self):
859868
''' Don't export the "content" property
860869
'''

roundup/roundupdb.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: roundupdb.py,v 1.122 2006-04-06 05:57:17 a1s Exp $
18+
# $Id: roundupdb.py,v 1.123 2006-04-27 01:39:47 richard Exp $
1919

2020
"""Extending hyperdb with types specific to issue-tracking.
2121
"""
@@ -304,7 +304,7 @@ def send_message(self, nodeid, msgid, note, sendto, from_address=None,
304304
m.append(_("New submission from %(authname)s%(authaddr)s:")
305305
% locals())
306306
else:
307-
m.append(_("%(authname)%(authaddr)s added the comment:")
307+
m.append(_("%(authname)s%(authaddr)s added the comment:")
308308
% locals())
309309
else:
310310
m.append(_("System message:"))

templates/classic/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050

5151
# FileClass automatically gets this property in addition to the Class ones:
5252
# content = String() [saved to disk in <tracker home>/db/files/]
53+
# type = String() [MIME type of the content, default 'text/plain']
5354
msg = FileClass(db, "msg",
5455
author=Link("user", do_journal='no'),
5556
recipients=Multilink("user", do_journal='no'),
@@ -60,8 +61,7 @@
6061
inreplyto=String())
6162

6263
file = FileClass(db, "file",
63-
name=String(),
64-
type=String())
64+
name=String())
6565

6666
# IssueClass automatically gets these properties in addition to the Class ones:
6767
# title = String()

test/db_test_base.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: db_test_base.py,v 1.68 2006-03-03 02:02:50 richard Exp $
18+
# $Id: db_test_base.py,v 1.69 2006-04-27 01:39:47 richard Exp $
1919

2020
import unittest, os, shutil, errno, imp, sys, time, pprint, sets
2121

@@ -73,6 +73,7 @@ def setupSchema(db, create, module):
7373
user.setkey("username")
7474
file = module.FileClass(db, "file", name=String(), type=String(),
7575
comment=String(indexme="yes"), fooz=Password())
76+
file_nidx = module.FileClass(db, "file_nidx", content=String(indexme='no'))
7677
issue = module.IssueClass(db, "issue", title=String(indexme="yes"),
7778
status=Link("status"), nosy=Multilink("user"), deadline=Date(),
7879
foo=Interval(), files=Multilink("file"), assignedto=Link('user'),
@@ -784,6 +785,17 @@ def testFileClassReindexing(self):
784785
self.assertEquals(self.db.indexer.search(['hello'], self.db.issue),
785786
{i1: {'files': [f2]}})
786787

788+
def testFileClassIndexingNoNoNo(self):
789+
f1 = self.db.file.create(content='hello')
790+
self.db.commit()
791+
self.assertEquals(self.db.indexer.search(['hello'], self.db.file),
792+
{'1': {}})
793+
794+
f1 = self.db.file_nidx.create(content='hello')
795+
self.db.commit()
796+
self.assertEquals(self.db.indexer.search(['hello'], self.db.file_nidx),
797+
{})
798+
787799
def testForcedReindexing(self):
788800
self.db.issue.create(title="flebble frooz")
789801
self.db.commit()
@@ -1258,6 +1270,14 @@ def init_a(self):
12581270
a.setkey("name")
12591271
self.db.post_init()
12601272

1273+
def test_fileClassProps(self):
1274+
self.db = self.module.Database(config, 'admin')
1275+
a = self.module.FileClass(self.db, 'a')
1276+
l = a.getprops().keys()
1277+
l.sort()
1278+
self.assert_(l, ['activity', 'actor', 'content', 'created',
1279+
'creation', 'type'])
1280+
12611281
def init_ab(self):
12621282
self.db = self.module.Database(config, 'admin')
12631283
a = self.module.Class(self.db, "a", name=String())

0 commit comments

Comments
 (0)