File: Store.py

package info (click to toggle)
pyrite 0.9.3
  • links: PTS
  • area: main
  • in suites: potato
  • size: 1,504 kB
  • ctags: 1,924
  • sloc: python: 6,064; ansic: 5,094; makefile: 275; sh: 172
file content (207 lines) | stat: -rw-r--r-- 6,897 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#
#  $Id: Store.py,v 1.10 1999/11/29 06:57:18 rob Exp $
#
#  Copyright 1999 Rob Tillotson <robt@debian.org>
#  All Rights Reserved
#
#  Permission to use, copy, modify, and distribute this software and
#  its documentation for any purpose and without fee or royalty is
#  hereby granted, provided that the above copyright notice appear in
#  all copies and that both the copyright notice and this permission
#  notice appear in supporting documentation or portions thereof,
#  including modifications, that you you make.
#
#  THE AUTHOR ROB TILLOTSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
#  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
#  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
#  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
#  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
#  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE!
#
"""Data Store API.

Stores may have the following properties:

  read    - can open existing databases for reading
  write   - can open existing databases for writing
  create  - can create new databases (which are implicitly open for writing)
  delete  - can delete databases
  list    - can list databases and their info
  install - has an install method which should be used when copying into
            this store, instead of using the normal 'copy' method
"""

__version__ = '$Id: Store.py,v 1.10 1999/11/29 06:57:18 rob Exp $'

__copyright__ = 'Copyright 1999 Rob Tillotson <robt@debian.org>'

import Pyrite
from Pyrite import Plugin, Database, PrefBlock, _

import sys
#import DBTypes

class BaseStore:
    properties = ()
    db_properties = ()
    
    def __init__(self):
	self.context = None

    def set_context(self, c):
	self.context = c

    def __getattr__(self, k):
	if hasattr(self.context, 'option_values') and \
	   self.context.option_values.has_key(k):
	    return self.context.option_values[k]
	else: raise AttributeError, k
	
    def has_option(self, k):
	return hasattr(self.context, 'option_values') and \
	       self.context.option_values.has_key(k)

    def get_option(self, k):
	if hasattr(self.context, 'option_values'):
	    return self.context.option_values[k]
	else: raise KeyError, k

    def get_plugin(self, *a, **kw):
	return apply(self.context.get_plugin, a, kw)

    def list_plugins(self, *a, **kw):
	return apply(self.context.list_plugins, a, kw)

    def list_plugin_info(self, *a, **kw):
	return apply(self.context.list_plugin_info, a, kw)
    
    # property support
    def has_property(self, p): return p in self.properties

    def test_db_properties(self, properties):
	"""Check whether this store can provide a particular type of database.
	
	Given a list of DB properties, this function tests whether a database
	with the requested properties is possible using this store.  If it is,
	this function returns a propertly list which describes the resulting
	database.  (Note that the returned property list might be LONGER than
	the one supplied to this function: that is, if you ask for a database
	with the 'foo' property and the only way the store can grant that is
	by returning a ['foo', 'bar', 'baz'] database, that's what will be
	returned.  If the property combination isn't possible, returns None.

	The standard behavior of this function assumes that all databases opened
	by a particular Store have the same properties.  Should this not be
	the case, the Store should override.
	"""
	for p in properties:
	    if p not in self.db_properties: return None
	return self.db_properties

    def open(self, name, mode='rs', dbclass=Database, properties=(), **kw):
	if not self.test_db_properties(properties):
	    raise RuntimeError, _("cannot provide db with properties %s") % properties
	t = apply(self._open, (name, mode, properties), kw)
	return apply(dbclass, t)
    
    def create(self, name, creator, type, flags=0, version=1, dbclass=Database,
	       properties=(),
	       filename = None, info=None, **kw):
	if not self.test_db_properties(properties):
	    raise RuntimeError, _("cannot provide db with properties %s") % properties
	t = apply(self._create, (name, creator, type, flags, version, filename,
				 info), kw)
	return apply(dbclass, t)

    def delete(self, name, **kw):
	"""Delete a database in the store."""
	raise RuntimeError, _("unimplemented method")

    def info(self, name, **kw):
	"""Get info about a database."""
	raise RuntimeError, _("unimplemented method")

    def list(self, **kw):
	"""Return a list of database names."""
	raise RuntimeError, _("unimplemented method")

    def listinfo(self, name=None, creator=None, type=None, **kw):
	"""Return a list of database names with information."""
	raise RuntimeError, _("unimplemented method")

    def getpref(self, creator, id, saved=1):
	"""Return a preference (as a raw string!)."""
	raise RuntimeError, _("unimplemented method")

    def setpref(self, raw, creator, id, version=0, saved=1):
	"""Set a preference."""
	raise RuntimeError, _("unimplemented method")
	
    #####
    def install(self, store, name):
	store.copy(self, name)
	
    def copy(self, store, name):
	"""Copy a database into another store."""
	idb = self.open(name, 'rs')
	try:
	    store.delete(name)
	except:
	    pass
	flags = 0
	if idb.info['flagReset']: flags = flags | 0x0020
	if idb.info['flagResource']: flags = flags | 0x0001
	if idb.info['flagNewer']: flags = flags | 0x0010
	if idb.info['flagExcludeFromSync']: flags = flags | 0x0080
	if idb.info['flagAppInfoDirty']: flags = flags | 0x0004
	if idb.info['flagReadOnly']: flags = flags | 0x0002
	if idb.info['flagBackup']: flags = flags | 0x0008
	if idb.info['flagOpen']: flags = flags | 0x8000
	odb = store.create(name, idb.info['creator'], idb.info['type'],
			   flags, idb.info['version'], info=idb.info)

	try:
	    a = idb.get_appblock()
	    odb.set_appblock(a)
	except:
	    pass

	# For some reason, there is a segfault inside pilot-link on my
	# system.  For now, this part is just skipped as a result.  For
	# anyone who is saying "but that means the sortblock isn't copied",
	# I simply point to the source to pilot-link, and note that it isn't
	# copied there either...
	#a = idb.getSortBlock()
	#odb.setSortBlock(a)
	#print "sortblock"

	if idb.info['flagResource']:
	    for i in range(0, len(idb)):
		r = idb[i]
		odb.append(r)
	else:
	    for i in range(0, len(idb)):
		r = idb[i]
		if r.deleted or r.archived:
		    continue
		odb.append(r)

	idb.close()
	odb.close()
    
class Store(Plugin.Plugin):
    type = 'Store'
    store_class = BaseStore

    def __call__(self, *a, **kw):
	o = apply(self.store_class, a, kw)
	o.set_context(self)
	# copy plugin attributes
	o.name = self.name
	o.version = self.version
	o.author = self.author
	o.description = self.description
	o.url = self.url
	return o