save the product tier on ordering
[bse.git] / site / cgi-bin / modules / BSE / DB / Mysql.pm
1 package BSE::DB::Mysql;
2 use strict;
3 use DBI;
4 use vars qw/@ISA/;
5 use Carp 'confess';
6 @ISA = qw(BSE::DB);
7
8 our $VERSION = "1.014";
9
10 use vars qw($MAX_CONNECTION_AGE);
11
12 use Carp;
13
14 my $self;
15
16 $MAX_CONNECTION_AGE = 1200;
17
18 my %statements =
19   (
20    # don't ever load the entire articles table
21    #Articles => 'select * from article',
22    replaceArticle =>
23      'replace article values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
24    addArticle =>  
25      'insert article values (null, ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
26    deleteArticle => 'delete from article where id = ?',
27    getArticleByPkey => 'select * from article where id = ?',
28    
29    getArticleByLevel => 'select * from article where level = ?',
30    getArticleByParentid => 'select * from article where parentid = ?',
31    getArticleByLinkAlias => 'select * from article where linkAlias = ?',
32    'Articles.stepParents' => <<EOS,
33 select ar.* from article ar, other_parents op
34   where ar.id = op.parentId and op.childId = ?
35 order by op.childDisplayOrder desc
36 EOS
37    'Articles.visibleStepParents' => <<EOS,
38 select ar.* from article ar, other_parents op
39   where ar.id = op.parentId and op.childId = ?
40      and date_format(?, '%Y%m%d') between date_format(op.release, '%Y%m%d') and date_format(op.expire, '%Y%m%d')
41      and listed <> 0
42 order by op.childDisplayOrder desc
43 EOS
44    'Articles.stepKids' => <<EOS,
45 select ar.* from article ar, other_parents op
46    where op.childId = ar.id and op.parentId = ?
47 EOS
48 # originally "... and ? between op.release and op.expire"
49 # but since the first argument was a string, mysql treated the comparisons
50 # as string comparisons
51    'Articles.visibleStepKids' => <<EOS,
52 select ar.* from article ar, other_parents op
53    where op.childId = ar.id 
54      and op.parentId = ? 
55      and date_format(?, '%Y%m%d') between date_format(op.release, '%Y%m%d') and date_format(op.expire, '%Y%m%d') and listed <> 0
56 EOS
57    'Articles.ids'=>'select id from article',
58    articlePossibleStepparents => <<EOS,
59 select a.id, a.title from article a
60 where a.id not in (select parentId from other_parents where childId = ?) 
61       and a.id <> ?;
62 EOS
63    articlePossibleStepchildren => <<EOS,
64 select a.id, a.title from article a 
65 where a.id not in (select childId from other_parents where parentId = ?) 
66       and a.id <> ?;
67 EOS
68    bse_MaxArticleDisplayOrder => <<EOS,
69 select max(displayOrder) as "displayOrder" from article
70 EOS
71
72    Images => 'select * from image',
73    replaceImage =>
74      'replace image values (?,?,?,?,?,?,?,?,?,?,?,?)',
75    addImage => 'insert image values(null, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
76    deleteImage => 'delete from image where id = ?',
77    getImageByArticleId => 'select * from image where articleId = ? order by displayOrder',
78    getImageByPkey => 'select * from image where id = ?',
79    getImageByArticleIdAndName => <<SQL,
80 select * from image where articleId = ? and name = ?
81 SQL
82    
83    dropIndex => 'delete from searchindex',
84    insertIndex => 'insert searchindex values(?, ?, ?, ?)',
85    searchIndex => 'select * from searchindex where id = ?',
86    searchIndexWC => 'select * from searchindex where id like ?',
87    
88    Products=> 'select article.*, product.* from article, product where id = articleId',
89    addProduct => 'insert product values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
90    getProductByPkey => 'select article.*, product.* from article, product where id=? and articleId = id',
91    getProductByProduct_code => 'select article.*, product.* from article, product where product_code=? and articleId = id',
92    getProductByLinkAlias => 'select article.*, product.* from article, product where linkAlias=? and articleId = id',
93    replaceProduct => 'replace product values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
94    'Products.stepProducts' => <<EOS,
95 select ar.*, pr.* from article ar, product pr, other_parents op
96    where ar.id = pr.articleId and op.childId = ar.id and op.parentId = ?
97 EOS
98    'Products.visibleStep' => <<EOS,
99 select ar.*, pr.* from article ar, product pr, other_parents op
100    where ar.id = pr.articleId and op.childId = ar.id 
101      and op.parentId = ? and ? between op.release and op.expire
102      and listed <> 0
103 EOS
104    'Products.subscriptionDependent' => <<SQL,
105 select ar.*, pr.* from article ar, product pr
106    where ar.id = pr.articleId
107      and (pr.subscription_id = ? or subscription_required = ?)
108 SQL
109    'Products.orderProducts' => <<SQL,
110 select ar.*, pr.* from article ar, product pr, order_item oi
111   where oi.orderId = ? and oi.productId = ar.id and ar.id = pr.articleId
112 SQL
113    deleteProduct => 'delete from product where articleId = ?',
114    'Products.userWishlist' => <<SQL,
115 select ar.*, pr.* from article ar, product pr, bse_wishlist wi
116   where wi.user_id = ? and wi.product_id = ar.id and ar.id = pr.articleId
117 order by wi.display_order desc
118 SQL
119    'Products.visible_children_of' => <<SQL,
120 select ar.*, pr.* from article ar, product pr
121    where ar.id = pr.articleId 
122      and listed <> 0
123      and ar.parentid = ?
124      and ? between ar.release and ar.expire
125 SQL
126    bse_userWishlistOrder => <<SQL,
127 select product_id, display_order
128 from bse_wishlist
129 where user_id = ?
130 order by display_order desc
131 SQL
132    bse_userWishlistReorder => <<SQL,
133 update bse_wishlist
134   set display_order = ?
135 where user_id = ? and product_id = ?
136 SQL
137    bse_addToWishlist => <<SQL,
138 insert into bse_wishlist(user_id, product_id, display_order)
139   values(?, ?, ?)
140 SQL
141    bse_removeFromWishlist => <<SQL,
142 delete from bse_wishlist where user_id = ? and product_id = ?
143 SQL
144
145    Orders => 'select * from orders',
146    #getOrderByPkey => 'select * from orders where id = ?',
147    getOrderItemByOrderId => 'select * from order_item where orderId = ?',
148    #addOrder => 'insert orders values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
149    #replaceOrder => 'replace orders values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
150    #addOrderItem => 'insert order_item values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
151    #replaceOrderItem => 'replace order_item values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
152    #getOrderByUserId => 'select * from orders where userId = ?',
153    deleteOrdersItems => 'delete from order_item where orderId = ?',
154
155    getOrderItemByProductId => 'select * from order_item where productId = ?',
156
157    OtherParents => 'select * from other_parents',
158    getOtherParentByChildId => <<EOS,
159 select * from other_parents where childId = ? order by childDisplayOrder desc
160 EOS
161    getOtherParentByParentId => <<EOS,
162 select * from other_parents where parentId = ? order by parentDisplayOrder desc
163 EOS
164    getOtherParentByParentIdAndChildId =>
165    'select * from other_parents where parentId = ? and childId = ?',
166    addOtherParent=>'insert other_parents values(null,?,?,?,?,?,?)',
167    deleteOtherParent => 'delete from other_parents where id = ?',
168    replaceOtherParent=>'replace other_parents values(?,?,?,?,?,?,?)',
169    'OtherParents.anylinks' => 
170    'select * from other_parents where childId = ? or parentId = ?',
171
172    ArticleFiles => 'select * from article_files',
173    addArticleFile =>
174    'insert into article_files values (null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
175    replaceArticleFile =>
176    'replace article_files values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
177    deleteArticleFile => 'delete from article_files where id = ?',
178    getArticleFileByArticleId =>
179    'select * from article_files where articleId = ? order by displayOrder desc',
180    getArticleFileByPkey => 'select * from article_files where id = ?',
181
182    "ArticleFiles.orderFiles" =><<SQL,
183 select distinct af.*
184 from article_files af, order_item oi
185 where af.articleId = oi.productId and oi.orderId = ?
186 order by oi.id, af.displayOrder desc
187 SQL
188    
189    # getSiteUserByUserId =>
190    # 'select * from site_users where userId = ?',
191    # getSiteUserByPkey =>
192    # 'select * from site_users where id = ?',
193    # getSiteUserByAffiliate_name =>
194    # 'select * from site_users where affiliate_name = ?',
195    # addSiteUser => 'insert site_users values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
196    # replaceSiteUser => 'replace site_users values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
197    'SiteUsers.removeSubscriptions'=>
198    'delete from subscribed_users where userId = ?',
199    'SiteUsers.removeSub'=>
200    'delete from subscribed_users where userId = ? and subId = ?',
201    'SiteUsers.subRecipients' => <<EOS,
202 select si.* from bse_siteusers si, subscribed_users su
203   where confirmed <> 0 and disabled = 0 and si.id = su.userId and su.subId = ?
204 EOS
205    SiteUsers => 'select * from bse_siteusers',
206    'SiteUsers.allSubscribers' => <<SQL,
207 select distinct su.* 
208   from bse_siteusers su, orders od, order_item oi
209   where su.id = od.siteuser_id and od.id = oi.orderId 
210         and oi.subscription_id <> -1
211 SQL
212    siteuserAllIds => 'select id from bse_siteusers',
213    getBSESiteuserImage => <<SQL,
214 select * from bse_siteuser_images
215   where siteuser_id = ? and image_id = ?
216 SQL
217    getBSESiteuserImages => <<SQL,
218 select * from bse_siteuser_images where siteuser_id = ?
219 SQL
220    addBSESiteuserImage => <<SQL,
221 insert bse_siteuser_images values(?,?,?,?,?,?,?,?)
222 SQL
223    replaceBSESiteuserImage => <<SQL,
224 replace bse_siteuser_images values(?,?,?,?,?,?,?,?)
225 SQL
226    deleteBSESiteuserImage=> <<SQL,
227 delete from bse_siteuser_images where siteuser_id = ? and image_id = ?
228 SQL
229
230    SubscriptionTypes =>
231    'select * from subscription_types',
232    addSubscriptionType=>
233    'insert subscription_types values(null,?,?,?,?,?,?,?,?,?,?,?,?)',
234    replaceSubscriptionType=>
235    'replace subscription_types values(?,?,?,?,?,?,?,?,?,?,?,?,?)',
236    getSubscriptionTypeByPkey =>
237    'select * from subscription_types where id = ? order by name',
238    deleteSubscriptionType =>
239    'delete from subscription_types where id = ?',
240    subRecipientCount => <<EOS,
241 select count(*) as "count" from bse_siteusers si, subscribed_users su
242   where confirmed <> 0 and disabled = 0 and si.id = su.userId and su.subId = ?
243 EOS
244    'SubscriptionTypes.userSubscribedTo' => <<'EOS',
245 select su.* from subscription_types su, subscribed_users us
246   where us.userId = ? and us.subId = su.id
247 EOS
248
249    addSubscribedUser=>
250    'insert subscribed_users values(null,?,?)',
251    getSubscribedUserByUserId =>
252    'select * from subscribed_users where userId = ?',
253
254    # the following don't work with the row/table classes
255    articlesList =>
256    'select id, title from article order by level, displayOrder desc',
257
258    getEmailBlackEntryByEmail =>
259    'select * from email_blacklist where email = ?',
260    addEmailBlackEntry =>
261    'insert email_blacklist values(null,?,?)',
262
263    addEmailRequest =>
264    'insert email_requests values(null,?,?,?,?)',
265    replaceEmailRequest =>
266    'replace email_requests values(?,?,?,?,?)',
267    deleteEmailRequest =>
268    'delete from email_requests where id = ?',
269    getEmailRequestByGenEmail =>
270    'select * from email_requests where genEmail = ?',
271
272    addAdminBase => 'insert into admin_base values(null, ?)',
273    replaceAdminBase => 'replace into admin_base values(?, ?)',
274    deleteAdminBase => 'delete from admin_base where id = ?',
275    getAdminBaseByPkey => 'select * from admin_base where id=?',
276    
277    AdminUsers => <<SQL,
278 select bs.*, us.* from admin_base bs, admin_users us
279   where bs.id = us.base_id
280    order by logon
281 SQL
282    getAdminUserByLogon => <<SQL,
283 select bs.*, us.* from admin_base bs, admin_users us
284   where bs.id = us.base_id and us.logon = ?
285 SQL
286    getAdminUserByPkey => <<SQL,
287 select bs.*, us.* from admin_base bs, admin_users us
288   where bs.id = us.base_id and bs.id = ?
289 SQL
290    addAdminUser => 'insert into admin_users values(?,?,?,?,?,?,?)',
291    replaceAdminUser => 'replace into admin_users values(?,?,?,?,?,?,?)',
292    deleteAdminUser => 'delete from admin_users where base_id = ?',
293    "AdminUsers.group_members" => <<SQL,
294 select bs.*, us.*
295   from admin_base bs, admin_users us, admin_membership am
296   where bs.id = us.base_id && am.group_id = ? and am.user_id = bs.id
297   order by logon
298 SQL
299    adminUsersGroups => <<SQL,
300 select bs.*, gr.*
301   from admin_base bs, admin_groups gr, admin_membership am
302   where bs.id = gr.base_id && am.user_id = ? and am.group_id = bs.id
303   order by gr.name
304 SQL
305    userGroups => 'select * from admin_membership where user_id = ?',
306    deleteUserGroups => 'delete from admin_membership where user_id = ?',
307
308    AdminGroups => <<SQL,
309 select bs.*, gr.* 
310   from admin_base bs, admin_groups gr
311   where bs.id = gr.base_id
312   order by name
313 SQL
314    getAdminGroupByName => <<SQL,
315 select bs.*, gr.* from admin_base bs, admin_groups gr
316   where bs.id = gr.base_id and gr.name = ?
317 SQL
318    getAdminGroupByPkey => <<SQL,
319 select bs.*, gr.* from admin_base bs, admin_groups gr
320   where bs.id = gr.base_id and bs.id = ?
321 SQL
322    addAdminGroup => 'insert into admin_groups values(?,?,?,?,?)',
323    replaceAdminGroup => 'replace into admin_groups values(?,?,?,?,?)',
324    deleteAdminGroup => 'delete from admin_groups where base_id = ?',
325    groupUsers => 'select * from admin_membership where group_id = ?',
326    bseAdminGroupMember => <<SQL,
327 select 1
328 from admin_membership
329 where group_id = ?
330   and user_id = ?
331 SQL
332    'AdminGroups.userPermissionGroups' => <<SQL,
333 select bs.*, ag.* from admin_base bs, admin_groups ag, admin_membership am
334 where bs.id = ag.base_id
335   and ( (ag.base_id = am.group_id and am.user_id = ?) 
336         or ag.name = 'everyone' )
337 SQL
338
339    addUserToGroup => 'insert into admin_membership values(?,?)',
340    delUserFromGroup => <<SQL,
341 delete from admin_membership where user_id = ? and group_id = ?
342 SQL
343    deleteGroupUsers => 'delete from admin_membership where group_id = ?',
344
345    articleObjectPerm => <<SQL,
346 select * from admin_perms where object_id = ? and admin_id = ?
347 SQL
348    addArticleObjectPerm => 'insert into admin_perms values(?,?,?)',
349    replaceArticleObjectPerm => 'replace into admin_perms values(?,?,?)',
350    userPerms => <<SQL,
351 select distinct ap.* 
352 from admin_perms ap
353 where ap.admin_id = ?
354 SQL
355    groupPerms => <<SQL,
356 select distinct ap.* 
357 from admin_perms ap, admin_membership am
358 where ap.admin_id = am.group_id and am.user_id = ?
359 SQL
360    commonPerms => <<SQL,
361 select distinct ap.* 
362 from admin_perms ap, admin_groups ag
363 where ap.admin_id = ag.base_id and ag.name = 'everyone'
364 SQL
365    Subscriptions => 'select * from bse_subscriptions',
366    addSubscription => 'insert bse_subscriptions values(null,?,?,?,?)',
367    replaceSubscription => 'replace bse_subscriptions values(?,?,?,?,?)',
368    deleteSubscription => <<SQL,
369 delete from bse_subscriptions where subscription_id = ?
370 SQL
371    getSubscriptionByPkey => <<SQL,
372 select * from bse_subscriptions where subscription_id = ?
373 SQL
374    getSubscriptionByText_id => <<SQL,
375 select * from bse_subscriptions where text_id = ?
376 SQL
377    subscriptionOrderItemCount => <<SQL,
378 select count(*) as "count" from order_item where subscription_id = ?
379 SQL
380    subscriptionOrderSummary => <<SQL,
381 select od.id, od.userId, od.orderDate, od.siteuser_id, od.billFirstName, od.billLastName, od.filled, 
382     sum(oi.subscription_period * oi.units) as "subscription_period"
383   from orders od, order_item oi
384   where oi.subscription_id = ? and od.id = oi.orderId and od.complete <> 0
385   group by od.id, od.userId, od.orderDate, od.siteuser_id
386   order by od.orderDate desc
387 SQL
388    subscriptionUserSummary => <<SQL,
389 select su.*, us.*
390   from bse_siteusers su, bse_user_subscribed us
391 where su.id = us.siteuser_id and us.subscription_id = ?
392 SQL
393    subscriptionProductCount => <<SQL,
394 select count(*) as "count" from product 
395   where subscription_id = ? or subscription_required = ?
396 SQL
397    removeUserSubscribed => <<SQL,
398 delete from bse_user_subscribed where subscription_id = ? and siteuser_id = ?
399 SQL
400    addUserSubscribed => <<SQL,
401 insert bse_user_subscribed values (?,?,?,?,?)
402 SQL
403    subscriptionUserBought => <<SQL,
404 select od.orderDate,
405   oi.subscription_period * oi.units as "subscription_period",
406   oi.max_lapsed, 
407   od.id as "order_id", oi.id as "item_id", oi.productId as "product_id"
408   from orders od, order_item oi
409   where oi.subscription_id = ? and od.id = oi.orderId and od.siteuser_id = ?
410         and od.complete <> 0
411 SQL
412    userSubscribedEntry => <<SQL,
413 select * from bse_user_subscribed 
414   where siteuser_id = ? and subscription_id = ?
415 SQL
416    siteuserSubscriptions => <<SQL,
417 select su.*, us.started_at, us.ends_at, us.max_lapsed
418   from bse_subscriptions su, bse_user_subscribed us
419 where us.siteuser_id = ? and us.subscription_id = su.subscription_id
420    and us.ends_at >= curdate()
421 SQL
422
423    addLocation => <<SQL,
424 insert bse_locations values(null,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
425 SQL
426    replaceLocation => <<SQL,
427 replace bse_locations values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
428 SQL
429    getLocationByPkey => 'select * from bse_locations where id = ?',
430    deleteLocation => 'delete from bse_locations where id = ?',
431    Locations => 'select * from bse_locations order by description',
432
433    Seminars => <<SQL,
434 select ar.*, pr.*, se.*
435   from article ar, product pr, bse_seminars se
436   where ar.id = pr.articleId and ar.id = se.seminar_id
437 SQL
438    addSeminar => 'insert bse_seminars values(?,?)',
439    replaceSeminar => 'replace bse_seminars values(?,?)',
440    deleteSeminar => 'delete from bse_seminars where seminar_id = ?',
441    getSeminarByPkey => <<SQL,
442 select ar.*, pr.*, se.*
443   from article ar, product pr, bse_seminars se
444   where id = ? and ar.id = pr.articleId and ar.id = se.seminar_id
445 SQL
446    getSeminarByProduct_code => <<SQL,
447 select ar.*, pr.*, se.*
448   from article ar, product pr, bse_seminars se
449   where product_code = ? and ar.id = pr.articleId and ar.id = se.seminar_id
450 SQL
451    'Locations.seminarFuture' => <<SQL,
452 select distinct lo.*
453   from bse_locations lo, bse_seminar_sessions ss
454 where ss.seminar_id = ? and ss.when_at > ?
455   and ss.location_id = lo.id
456 order by lo.description
457 SQL
458    'Locations.session_id' => <<SQL,
459 select lo.*
460   from bse_locations lo, bse_seminar_sessions ss
461 where lo.id = ss.location_id and ss.id = ?
462 SQL
463
464    seminarSessionInfo => <<SQL,
465 select se.*, lo.description
466   from bse_seminar_sessions se, bse_locations lo
467   where se.seminar_id = ? and se.location_id = lo.id
468 order by when_at desc
469 SQL
470    seminarFutureSessionInfo => <<SQL,
471 select se.*, lo.description, lo.room, lo.street1, lo.street2, lo.suburb, 
472     lo.state, lo.country, lo.postcode, lo.public_notes
473   from bse_seminar_sessions se, bse_locations lo
474   where se.seminar_id = ? and se.when_at > ? and se.location_id = lo.id
475 order by when_at desc
476 SQL
477    addSeminarSession => 'insert bse_seminar_sessions values(null,?,?,?,?)',
478    replaceSeminarSession => 'replace bse_seminar_sessions values(?,?,?,?,?)',
479    deleteSeminarSession => 'delete from bse_seminar_sessions where id = ?',
480    getSeminarSessionByPkey => 'select * from bse_seminar_sessions where id = ?',
481    getSeminarSessionByLocation_idAndWhen_at => <<SQL,
482 select * from bse_seminar_sessions
483   where location_id = ? and when_at = ?
484 SQL
485    getSeminarSessionBySeminar_id => <<SQL,
486 select * from bse_seminar_sessions
487   where seminar_id = ?
488 SQL
489    'SeminarSessions.futureSessions' => <<SQL,
490 select * from bse_seminar_sessions
491   where seminar_id = ? and when_at >= ?
492 SQL
493    'SeminarSessions.futureSeminarLocation' => <<SQL,
494 select *
495   from bse_seminar_sessions
496   where seminar_id = ? and location_id = ? and when_at > ?
497 SQL
498    'SiteUsers.sessionBookings' => <<SQL,
499 select su.* from bse_siteusers su, bse_seminar_bookings sb
500   where sb.session_id = ? and su.id = sb.siteuser_id
501 SQL
502    cancelSeminarSessionBookings => <<SQL,
503 delete from bse_seminar_bookings where session_id = ?
504 SQL
505    conflictSeminarSessions => <<SQL,
506 select bo1.siteuser_id
507   from bse_seminar_bookings bo1, bse_seminar_bookings bo2
508 where bo1.session_id = ? and bo2.session_id = ? 
509   and bo1.siteuser_id = bo2.siteuser_id
510 SQL
511    seminarSessionBookedIds => <<SQL,
512 select * from bse_seminar_bookings where session_id = ?
513 SQL
514    addSeminarBooking => <<SQL,
515 insert bse_seminar_bookings values(null,?,?,?,?,?,?)
516 SQL
517    seminarSessionRollCallEntries => <<SQL,
518 select bo.roll_present, su.id, su.userId, su.name1, su.name2, su.email,
519     bo.id as booking_id
520   from bse_seminar_bookings bo, bse_siteusers su
521 where bo.session_id = ? and bo.siteuser_id = su.id
522 SQL
523   updateSessionRollPresent => <<SQL,
524 update bse_seminar_bookings
525   set roll_present = ?
526   where session_id = ? and siteuser_id = ?
527 SQL
528    userSeminarSessionBookings => <<SQL,
529 select session_id 
530   from bse_seminar_bookings sb, bse_seminar_sessions ss
531 where ss.seminar_id = ? and ss.id = sb.session_id and siteuser_id = ?
532 SQL
533    SiteUserGroups => 'select * from bse_siteuser_groups',
534    addSiteUserGroup => 'insert bse_siteuser_groups values(null,?)',
535    replaceSiteUserGroup => 'replace bse_siteuser_groups values(?,?)',
536    deleteSiteUserGroup => 'delete from bse_siteuser_groups where id = ?',
537    getSiteUserGroupByPkey => 'select * from bse_siteuser_groups where id = ?',
538    getSiteUserGroupByName => 'select * from bse_siteuser_groups where name = ?',
539    siteuserGroupMemberIds => <<SQL,
540 select siteuser_id as "id" 
541 from bse_siteuser_membership 
542 where group_id = ?
543 SQL
544    siteuserGroupAddMember => <<SQL,
545 insert bse_siteuser_membership values(?,?)
546 SQL
547    siteuserGroupDeleteMember => <<SQL,
548 delete from bse_siteuser_membership where group_id = ? and siteuser_id = ?
549 SQL
550     siteuserGroupDeleteAllMembers => <<SQL,
551 delete from bse_siteuser_membership where group_id = ?
552 SQL
553     siteuserMemberOfGroup => <<SQL,
554 select * from bse_siteuser_membership 
555 where siteuser_id = ? and group_id = ?
556 SQL
557     siteuserGroupsForUser => <<SQL,
558 select group_id as "id" from bse_siteuser_membership where siteuser_id = ?
559 SQL
560
561     articleAccessibleToGroup => <<SQL,
562 select * from bse_article_groups
563 where article_id = ? and group_id = ?
564 SQL
565     siteuserGroupsForArticle => <<SQL,
566 select group_id as "id" from bse_article_groups
567 where article_id = ?
568 SQL
569     articleAddSiteUserGroup => <<SQL,
570 insert bse_article_groups values(?,?)
571 SQL
572     articleDeleteSiteUserGroup => <<SQL,
573 delete from bse_article_groups 
574 where article_id = ? and group_id = ?
575 SQL
576     siteuserGroupDeleteAllPermissions => <<SQL,
577 delete from bse_article_groups where group_id = ?
578 SQL
579   );
580
581 # called when we start working on a new request, mysql seems to have
582 # problems with old connections sometimes, or so it seems, so
583 # disconnect occasionally (only matters for fastcgi, mod_perl)
584 sub _startup {
585   my $class = shift;
586
587   if ($self) {
588     unless ($self->{dbh}->ping) {
589       print STDERR "Database connection lost - reconnecting\n";
590       $self->{dbh} = $class->connect;
591       $self->{birth} = time();
592     }
593   }
594 }
595
596 sub connect {
597   my ($class, $dbname) = @_;
598
599   my $dsn = $class->dsn($dbname);
600   my $un = $self->dbuser($dbname);
601   my $pass = $self->dbpassword($dbname);
602   my $dbopts = $self->dbopts($dbname);
603   my $dbh = DBI->connect( $dsn, $un, $pass, $dbopts)
604       or die "Cannot connect to database: $DBI::errstr";
605
606   # this might fail, but I don't care
607   $dbh->do("set session sql_mode='ansi_quotes'");
608
609   return $dbh;
610 }
611
612 sub _single
613 {
614   my ($class, $cfg) = @_;
615
616   warn "Incorrect number of parameters passed to BSE::DB::Mysql::single\n" unless @_ == 2;
617   
618   unless ( defined $self ) {
619     $self = bless 
620       { 
621        dbh => undef,
622        birth => time(),
623        cfg => $cfg,
624       }, $class;
625
626     $self->{dbh} = $self->connect;
627   }
628   $self;
629 }
630
631 sub _forked {
632   my $self = shift;
633
634   $self->{dbh}{InactiveDestroy} = 1;
635   delete $self->{dbh};
636   $self->{dbh} = $self->connect;
637 }
638
639
640 my $get_sql_by_name = 'select sql_statement from sql_statements where name=?';
641
642 my %sql_cache;
643
644 sub stmt_sql {
645   my ($self, $name) = @_;
646
647   $name =~ s/BSE.*:://;
648
649   my $sql = $statements{$name};
650   unless ($sql) {
651     if (exists $sql_cache{$name}) {
652       return $sql_cache{$name};
653     }
654   }
655   unless ($sql) {
656     my @row = $self->{dbh}->selectrow_array($get_sql_by_name, {}, $name);
657     if (@row) {
658       $sql = $row[0];
659       #print STDERR "Found SQL '$sql'\n";
660     }
661     else {
662       #print STDERR "SQL statment $name not found in sql_statements table\n";
663     }
664
665     $sql_cache{$name} = $sql;
666   }
667
668   return $sql;
669 }
670
671 sub stmt {
672   my ($self, $name) = @_;
673
674   my $sql = $self->stmt_sql($name)
675     or confess "Statement named '$name' not found";
676   my $sth = $self->{dbh}->prepare($sql)
677     or croak "Cannot prepare $name statment: ",$self->{dbh}->errstr;
678
679   $sth;
680 }
681
682 sub stmt_noerror {
683   my ($self, $name) = @_;
684
685   my $sql = $self->stmt_sql($name)
686     or return;
687   my $sth = $self->{dbh}->prepare($sql)
688     or croak "Cannot prepare $name statment: ",$self->{dbh}->errstr;
689
690   $sth;
691 }
692
693 sub insert_id {
694   my ($self, $sth) = @_;
695
696   my $id = $sth->{"mysql_insertid"};
697
698   return $id;
699 }
700
701 sub dbopts {
702   my ($class) = @_;
703
704   my $opts = $class->SUPER::dbopts();
705
706   if (BSE::Cfg->utf8
707       && lc(BSE::Cfg->charset) eq "utf-8") {
708     $opts->{mysql_enable_utf8} = 1;
709   }
710
711   return $opts;
712 }
713
714 # gotta love this
715 sub DESTROY
716 {
717   my ($self) = @_;
718   # this is wierd - we only need to reset this on 5.6.x (for x == 0 so
719   # far)
720   # Works fine without the reset for 5.005_03
721   if ($self->{dbh}) {
722     $self->{dbh}->disconnect;
723     delete $self->{dbh};
724   }
725 }
726
727 1;
728