<div dir="ltr">Hi,<div><br></div><div style>Some of what you mention may be partially implemented in a branch (upgrade history). Note that "Don't create if it exists" concept is not something we're targeting at. Our approach is to register upgrade files so they can not be applied twice so easy.</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jun 21, 2013 at 8:52 AM, Craig Ringer <span dir="ltr"><<a href="mailto:craig@2ndquadrant.com" target="_blank">craig@2ndquadrant.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all<br>
<br>
I'm in the process of packing up various small bits of RT code for our<br>
RT install into an extension that can be properly versioned and tracked.<br>
<br>
There's just one frustrating barrier to this: RT's extension system<br>
provides a "make initdb", but no way to make the application of the<br>
initial data provided in etc/initialdata idempotent. If you run "make<br>
initdb" twice, it duplicates everything, not just adding any new records.<br>
<br>
Is this a problem anyone else has looked into? I'm considering teaching<br>
"make initdb" to do a basic upsert: Lock the table in question in<br>
EXCLUSIVE mode (PostgreSQL, allows SELECTs but nothing else in other<br>
transactions), then do the usual portable two-command sequence:<br>
<br>
UPDATE thetable<br>
SET description = 'thedescription', ...<br>
WHERE name = 'thename';<br>
<br>
INSERT INTO thetable(name, description, ...)<br>
SELECT 'thename', 'thedescription', ...<br>
WHERE NOT EXISTS (SELECT 1 FROM thetable WHERE <a href="http://thetable.name" target="_blank">thetable.name</a> = 'thename');<br>
<br>
<br>
For other DBs, just do a "LOCK tablename;" (unless MySQL, etc, users<br>
want to suggest an appropriate lock mode).<br>
<br>
The problem with this is that the name isn't really meant to be a key,<br>
for all sorts of reasons. It's user-visible, it's in natural language,<br>
and it's translatable.<br>
<br>
It'd be strongly preferable to add a new field to the initdb parameter<br>
hash that provides a non-translatable internal text identifier for the<br>
command of interest. Here's what I'm thinking of:<br>
<br>
- Add a new nullable unique text column to scrips, scripactions, and<br>
scripconditions named 'extension_identifier'.<br>
<br>
- Have 'make initdb' check for a hash param 'ExtensionIdentifier' in<br>
each row. If none is present, behave exactly as now, leaving the<br>
extension_identifier column NULL.<br>
<br>
- If the ExtensionIdentifier key is found, Do an upsert with table lock<br>
as described above for each row when we 'make initdb', but instead of<br>
using the 'name' field, discriminate based on the 'extension_identifier'<br>
column.<br>
<br>
<br>
<br>
<br>
This would allow extensions to provide a unique identifier for their<br>
scrips, scrip actions, scrip conditions, etc, that if used consistently<br>
would let them make the initdb command idempotent, so it can be used<br>
when an extension is updated, not just first installed.<br>
<br>
Guidance for extension authors would suggest that the extension's name<br>
be used to prefix the extension identifier so as to avoid clashes.<br>
<br>
No support for deleting obsolete entries would be provided; if an entry<br>
vanishes from the initialdata but was installed from a previous version,<br>
it would not be touched in the DB. That's let extensions continue to<br>
provide support for old actions, conditions, etc without exposing them<br>
to new users.<br>
<br>
By using the extension name and a text identifier the need to have a<br>
central identifier registry is avoided; CPAN's Perl namespace registry<br>
already serves the required purpose.<br>
<br>
Thoughts/opinions?<br>
<br>
Would the RT team consider accepting a patch implementing the above as a<br>
change to RTxInitDB ?<br>
<br>
If so, how would you deal with the addition of the new column to each of<br>
the tables? Do it as part of the upgrade script for the next RT release<br>
that needs an upgrade script anyway, and if it isn't present, ignore the<br>
ExtensionIdentifier field in the initialdata for backward compatibility?<br>
<span class="HOEnZb"><font color="#888888">--<br>
 Craig Ringer                   <a href="http://www.2ndQuadrant.com/" target="_blank">http://www.2ndQuadrant.com/</a><br>
 PostgreSQL Development, 24x7 Support, Training & Services<br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br>Best regards, Ruslan.
</div>