Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/recipe-books.git

Merge branch 'master' of https://bitbucket.org/djarvis/recipe-books

Author liantze <email>
Date 2013-01-16 00:02:08 GMT+0800
Commit b618d366fee514ae042bb5e438d869cad840b62f
Parent 05509d7
Delta 1652 lines added, 1 line removed, 1651-line increase
html/recipe-book.html
+<?xml version='1.0' encoding='ISO-8859-1' standalone='yes'?>
+<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN' 'http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd'>
+<html xmlns='http://www.w3.org/1999/xhtml' >
+<head>
+<title>Database documentation</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
+<style type='text/css'>
+ #dbs {font-family:Tahoma,Dialog,Sans-Serif;font-size:11px;background:#fff;width:80%;border-collapse:collapse;text-align:left;margin:20px;}
+ #dbs thead{background:#ddd;}
+ #dbs th{font-size:12px;font-weight:bold;color:#039;border-bottom:2px solid #6678b1;padding:7px 8px;}
+ #dbs td{border-bottom:1px solid #ccc;color:#336;padding:3px 8px;white-space: pre;}
+ td.subpart{font-weight:bold;background:#ddd}
+ td.name{background:#f2f2f2}
+ #dbs tbody tr:hover td{color:#000;background:#fffcea;}
+</style>
+</head>
+
+<body>
+<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='832' height='640' viewbox='0 0 832 640' >
+<style type='text/css'>
+ text { text-rendering: optimizeLegibility; fill:#000000; font-family: Tahoma, Trebuchet MS, Arial; font-size:11px; }
+ text.colType { fill:#a9bdc6; font-size:10px; }
+ text.tableTitle { fill:#333333; font-size:11px; font-weight:bold; }
+ path { stroke:#363025; stroke-width:1.2; fill:none; }
+ rect.grp { opacity:0.5; stroke:#c2ab83; stroke-width:1; }
+ rect.table { fill:url(#tableBodyGradient); stroke:#677e94; stroke-width:1; }
+ rect.shadow { fill:#bbbbbb; stroke-width:0; }
+ line.table { stroke:#677e94; stroke-width:1; }
+ rect.callout { fill:#f7fbf7; stroke:none; }
+ rect.calloutBorder { fill:none; filter:url(#tableShadow); stroke:#8d9380; stroke-width:1; }
+</style>
+<defs>
+ <pattern id='layoutGradient' patternUnits='userSpaceOnUse' x='0' y='0' width='10' height='10' viewBox='0 0 10 10'>
+ <rect x='0' y='0' width='10' height='10' style='fill:#e5f1f3;' />
+ <line x1='5' y1='10' x2='5' y2='0' style='stroke:#949494;stroke-width:0.5;stroke-dasharray:1,9;' />
+ </pattern>
+ <radialGradient id='layoutGradientOld' cx='20%' cy='20%' r='25%' fx='10%' fy='0%'>
+ <stop offset='0%' stop-color='#fefdee' />
+ <stop offset='100%' stop-color='#eee2c3' />
+ </radialGradient>
+ <filter id='tableShadow' filterUnits='objectBoundingBox' x='-1.2' y='-1.2' width='6' height='6'>
+ <feGaussianBlur in='SourceAlpha' stdDeviation='2' />
+ <feComponentTransfer result='shadow'>
+ <feFuncA type='linear' slope='.3' intercept='0' />
+ </feComponentTransfer>
+ <feComposite in2='shadow' in='SourceGraphic'/>
+ </filter>
+ <radialGradient id='tableHeaderGradient' fx='5%' fy='5%' r='75%' spreadMethod='pad'>
+ <stop offset='0%' stop-color='#dfebf6' stop-opacity='1'/>
+ <stop offset='100%' stop-color='#9db4cb' stop-opacity='1' />
+ </radialGradient>
+ <radialGradient id='tableBodyGradient' fx='5%' fy='5%' r='75%' spreadMethod='pad'>
+ <stop offset='0%' stop-color='#ffffff' stop-opacity='1'/>
+ <stop offset='100%' stop-color='#e4e4e4' stop-opacity='1' />
+ </radialGradient>
+ <radialGradient id='legendGradient' fx='5%' fy='5%' r='75%' spreadMethod='pad'>
+ <stop offset='0%' stop-color='#6985ff' stop-opacity='1'/>
+ <stop offset='100%' stop-color='#1e2a5f' stop-opacity='1' />
+ </radialGradient>
+ <pattern id='hintPointerSV' patternUnits='userSpaceOnUse' x='0' y='0' width='13' height='13' viewBox='0 0 13 13' >
+ <path d='M 0,0 Q 7,7,0,13 Q 13,7,13,0' style='fill:#f7fbf7;stroke:#8d9380;' />
+ </pattern>
+ <pattern id='hintPointerSE' patternUnits='userSpaceOnUse' x='0' y='0' width='13' height='13' viewBox='0 0 13 13' >
+ <path d='M 0,0 Q 3,7,13,13 Q 7,7,13,0' style='fill:#f7fbf7;stroke:#8d9380;' />
+ </pattern>
+ <pattern id='hintPointerNV' patternUnits='userSpaceOnUse' x='0' y='0' width='13' height='13' viewBox='0 0 13 13' >
+ <path d='M 0,13 Q 7,7,0,0 Q 13,7,13,13' style='fill:#f7fbf7;stroke:#8d9380;' />
+ </pattern>
+ <pattern id='hintPointerNE' patternUnits='userSpaceOnUse' x='0' y='0' width='13' height='13' viewBox='0 0 13 13' >
+ <path d='M 0,13 Q 3,7,13,0 Q 7,7,13,13' style='fill:#f7fbf7;stroke:#8d9380;' />
+ </pattern>
+ <symbol id='pk' overflow='visible' >
+ <path d='M 4 0 L 9 0 L 10 1 L 10 3 L 9 4 L 7 4 L 7 6 L 9 8 L 7 11 L 5 10 L 5 5 L 3 3 L 3 1 z' style='fill:#f2e421;stroke-width:0.8;stroke:#5f3312;stroke-linejoin:round;' />
+ </symbol>
+ <symbol id='idx' overflow='visible' >
+ <path d='M 4,2 L 10,6 L 4,10 z' style='fill:#f2e421;stroke-width:0.8;stroke:#5f3312;stroke-linejoin:round;' />
+ </symbol>
+ <marker id='arrow' viewBox='0 0 6 6' refX='0' refY='3' markerUnits='strokeWidth' markerWidth='6' markerHeight='6' orient='auto'>
+ <path d='M 0,0 L 6, 3 L 0,6 z' style='fill:#776c57; stroke-width:0px;' />
+ </marker>
+ <marker id='foot' viewBox='0 0 6 6' refX='6' refY='3' markerUnits='strokeWidth' markerWidth='6' markerHeight='6' orient='auto'>
+ <path d='M 0,3 L 13, 3 z' style='stroke:#776c57;' />
+ </marker>
+</defs>
+
+<!-- ============= Desktop ============= -->
+<rect x='1' y='1' width='830' height='638' rx='6' ry='6' style='fill:url(#layoutGradient); stroke:#7292aa; stroke-width:0.5;' />
+
+<!-- ============= Group 'Book' ============= -->
+<rect class='grp' style='fill:#33cc00;' x='27' y='19' width='544' height='482' rx='7' ry='7'/>
+<text x='40' y='32'>Book</text>
+
+<!-- ============= Group 'Recipe' ============= -->
+<rect class='grp' style='fill:#0066ff;' x='625' y='19' width='115' height='287' rx='7' ry='7'/>
+<text x='638' y='32'>Recipe</text>
+
+<!-- ============= Group 'Latex' ============= -->
+<rect class='grp' style='fill:#cc00ff;' x='599' y='318' width='206' height='183' rx='7' ry='7'/>
+<text x='612' y='331'>Latex</text>
+
+<!-- ============= Table 'account' ============= -->
+<rect class='shadow' x='643' y='39' width='78' height='104' rx='6' ry='6' />
+<rect class='table' x='637' y='33' width='78' height='104' rx='6' ry='6' />
+<path d='M 638 53 L 638 40 Q 638 34 644 34 L 708 34 Q 714 34 714 40 L 714 53 L638 53 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='637' y1='52' x2='715' y2='52'/>
+<a xlink:href='#account' title='List of accounts used by people to author recipes&#046;' ><text x='650' y='48' class='tableTitle'>account</text></a>
+ <use id='pk' x='637' y='61' xlink:href='#pk'/><a xlink:href='#id' title='id bigserial Uniquely identifies each account&#046;'><text x='650' y='71'>id</text></a>
+ <a xlink:href='#email' title='email varchar Email address associated with the account&#046;'><text x='650' y='84'>email</text></a>
+ <a xlink:href='#created' title='created date Date the account was created&#046;'><text x='650' y='97'>created</text></a>
+ <a xlink:href='#updated' title='updated date Date the account was last updated&#046;'><text x='650' y='110'>updated</text></a>
+ <a xlink:href='#deleted' title='deleted date Date the account was deleted&#046;'><text x='650' y='123'>deleted</text></a>
+
+<!-- ============= Table 'book' ============= -->
+<rect class='shadow' x='318' y='39' width='91' height='143' rx='6' ry='6' />
+<rect class='table' x='312' y='33' width='91' height='143' rx='6' ry='6' />
+<path d='M 313 53 L 313 40 Q 313 34 319 34 L 396 34 Q 402 34 402 40 L 402 53 L313 53 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='312' y1='52' x2='403' y2='52'/>
+<a xlink:href='#book' title='Defines the common items to every book&#046;' ><text x='342' y='48' class='tableTitle'>book</text></a>
+ <use id='pk' x='312' y='61' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='325' y='71'>id</text></a>
+ <a xlink:href='#label' title='label varchar Book title&#046;'><text x='325' y='84'>label</text></a>
+ <a xlink:href='#spine_label' title='spine&#095;label varchar Book spine label&#046;'><text x='325' y='97'>spine_label</text></a>
+ <a xlink:href='#dedication' title='dedication text Text for the dedication&#046;'><text x='325' y='110'>dedication</text></a>
+ <a xlink:href='#isbn' title='isbn varchar International standard book number and EAN&#044; can be null&#046;'><text x='325' y='123'>isbn</text></a>
+ <a xlink:href='#created' title='created timestamptz Date the book was created&#046;'><text x='325' y='136'>created</text></a>
+ <a xlink:href='#deleted' title='deleted timestamptz Date the book was &#040;or is to be&#063;&#041; deleted&#046;'><text x='325' y='149'>deleted</text></a>
+ <a xlink:href='#updated' title='updated timestamptz Date the book was last updated&#046;'><text x='325' y='162'>updated</text></a>
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;account&#095;book&#095;id' d='M 442 52 L 403,52' />
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;account&#095;account&#095;id' d='M 559 52 L 624,52' />
+
+<!-- ============= Table 'book_account' ============= -->
+<rect class='shadow' x='461' y='39' width='104' height='78' rx='6' ry='6' />
+<rect class='table' x='455' y='33' width='104' height='78' rx='6' ry='6' />
+<path d='M 456 53 L 456 40 Q 456 34 462 34 L 552 34 Q 558 34 558 40 L 558 53 L456 53 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='455' y1='52' x2='559' y2='52'/>
+<a xlink:href='#book_account' title='Associates a book with an account&#046;' ><text x='463' y='48' class='tableTitle'>book_account</text></a>
+ <use id='pk' x='455' y='61' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='468' y='71'>id</text></a>
+ <use id='idx' x='455' y='74' xlink:href='#idx'/><a xlink:href='#book_id' title='book&#095;id int4 The book associated with an account&#046;'><text x='468' y='84'>book_id</text></a>
+ <use id='idx' x='455' y='87' xlink:href='#idx'/><a xlink:href='#account_id' title='account&#095;id int4 The account associated with a book&#046;'><text x='468' y='97'>account_id</text></a>
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;photograph&#095;book&#095;id' d='M 234 52 L 299,52' />
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;photograph&#095;book&#095;photograph&#095;category&#095;id' d='M 52 130 L 52,247' />
+
+<!-- ============= Table 'book_photograph' ============= -->
+<rect class='shadow' x='45' y='39' width='195' height='91' rx='6' ry='6' />
+<rect class='table' x='39' y='33' width='195' height='91' rx='6' ry='6' />
+<path d='M 40 53 L 40 40 Q 40 34 46 34 L 227 34 Q 233 34 233 40 L 233 53 L40 53 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='39' y1='52' x2='234' y2='52'/>
+<a xlink:href='#book_photograph' title='Describes attributes about a photograph that can be used in the book&#046;' ><text x='81' y='48' class='tableTitle'>book_photograph</text></a>
+ <use id='pk' x='39' y='61' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='52' y='71'>id</text></a>
+ <use id='idx' x='39' y='74' xlink:href='#idx'/><a xlink:href='#book_id' title='book&#095;id int4 The book to which this photograph belongs&#046;'><text x='52' y='84'>book_id</text></a>
+ <a xlink:href='#image_url' title='image&#095;url varchar The website address where the image can be retrieved&#046;'><text x='52' y='97'>image_url</text></a>
+ <use id='idx' x='39' y='100' xlink:href='#idx'/><a xlink:href='#book_photograph_category_id' title='book&#095;photograph&#095;category&#095;id int4 The type of photograph &#040;e&#046;g&#046;&#044; cover page&#044; meal inset&#044; divider page&#044; category section page&#041;&#046;'><text x='52' y='110'>book_photograph_category_id</text></a>
+
+<!-- ============= Table 'book_photograph_category' ============= -->
+<rect class='shadow' x='45' y='260' width='195' height='78' rx='6' ry='6' />
+<rect class='table' x='39' y='254' width='195' height='78' rx='6' ry='6' />
+<path d='M 40 274 L 40 261 Q 40 255 46 255 L 227 255 Q 233 255 233 261 L 233 274 L40 274 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='39' y1='273' x2='234' y2='273'/>
+<a xlink:href='#book_photograph_category' title='Contains a list of categories for book photographs&#046;' ><text x='50' y='269' class='tableTitle'>book_photograph_category</text></a>
+ <use id='pk' x='39' y='282' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='52' y='292'>id</text></a>
+ <a xlink:href='#label' title='label varchar Text to display to the user&#046;'><text x='52' y='305'>label</text></a>
+ <a xlink:href='#description' title='description varchar Brief description regarding how the category is used&#046;'><text x='52' y='318'>description</text></a>
+
+<!-- ============= Table 'book_preamble' ============= -->
+<rect class='shadow' x='617' y='338' width='117' height='52' rx='6' ry='6' />
+<rect class='table' x='611' y='332' width='117' height='52' rx='6' ry='6' />
+<path d='M 612 352 L 612 339 Q 612 333 618 333 L 721 333 Q 727 333 727 339 L 727 352 L612 352 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='611' y1='351' x2='728' y2='351'/>
+<a xlink:href='#book_preamble' title='book&#095;preamble' ><text x='621' y='347' class='tableTitle'>book_preamble</text></a>
+ <use id='pk' x='611' y='360' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='624' y='370'>id</text></a>
+
+<!-- ============= Table 'book_preamble_category' ============= -->
+<rect class='shadow' x='617' y='429' width='182' height='52' rx='6' ry='6' />
+<rect class='table' x='611' y='423' width='182' height='52' rx='6' ry='6' />
+<path d='M 612 443 L 612 430 Q 612 424 618 424 L 786 424 Q 792 424 792 430 L 792 443 L612 443 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='611' y1='442' x2='793' y2='442'/>
+<a xlink:href='#book_preamble_category' title='book&#095;preamble&#095;category' ><text x='622' y='438' class='tableTitle'>book_preamble_category</text></a>
+ <use id='pk' x='611' y='451' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='624' y='461'>id</text></a>
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;preference&#095;book&#095;id' d='M 325 247 L 325,182' />
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;preference&#095;book&#095;preference&#095;code&#095;id' d='M 286 338 L 286,364' />
+
+<!-- ============= Table 'book_preference' ============= -->
+<rect class='shadow' x='266' y='260' width='169' height='78' rx='6' ry='6' />
+<rect class='table' x='260' y='254' width='169' height='78' rx='6' ry='6' />
+<path d='M 261 274 L 261 261 Q 261 255 267 255 L 422 255 Q 428 255 428 261 L 428 274 L261 274 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='260' y1='273' x2='429' y2='273'/>
+<a xlink:href='#book_preference' title='Stores configuration parameters used to generate the book &#040;e&#046;g&#046;&#044; layout&#044; fonts&#044; colours&#041;&#046; The system must select default values for a book&#046; This table allows users to override the defaults&#046; This indirectly drives the settings for generating a book&#046;' ><text x='291' y='269' class='tableTitle'>book_preference</text></a>
+ <use id='pk' x='260' y='282' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='273' y='292'>id</text></a>
+ <use id='idx' x='260' y='295' xlink:href='#idx'/><a xlink:href='#book_id' title='book&#095;id int4 The preference&#039;s reference to a book&#046;'><text x='273' y='305'>book_id</text></a>
+ <a xlink:href='#book_preference_code_id' title='book&#095;preference&#095;code&#095;id int4 Reference to the book preference code table&#046;'><text x='273' y='318'>book_preference_code_id</text></a>
+
+<!-- ============= Table 'book_preference_code' ============= -->
+<rect class='shadow' x='279' y='377' width='156' height='104' rx='6' ry='6' />
+<rect class='table' x='273' y='371' width='156' height='104' rx='6' ry='6' />
+<path d='M 274 391 L 274 378 Q 274 372 280 372 L 422 372 Q 428 372 428 378 L 428 391 L274 391 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='273' y1='390' x2='429' y2='390'/>
+<a xlink:href='#book_preference_code' title='List of domains&#044; codes&#044; and values related to book preferences&#046; If later need arises&#044; this table can be split into separate tables to establish foreign key constraints&#046;' ><text x='279' y='386' class='tableTitle'>book_preference_code</text></a>
+ <use id='pk' x='273' y='399' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='286' y='409'>id</text></a>
+ <a xlink:href='#domain' title='domain varchar Grouping for codes and values &#040;e&#046;g&#046;&#044; BOOK&#095;LAYOUT&#041;&#046;'><text x='286' y='422'>domain</text></a>
+ <a xlink:href='#code' title='code varchar Unique identifier within a given domain&#046;'><text x='286' y='435'>code</text></a>
+ <a xlink:href='#label' title='label varchar Text that can be displayed to the user&#046;'><text x='286' y='448'>label</text></a>
+ <a xlink:href='#description' title='description varchar Brief description about how the code is used&#046;'><text x='286' y='461'>description</text></a>
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;recipe&#095;recipe&#095;id' d='M 559 182 L 624,182' />
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;book&#095;recipe&#095;book&#095;id' d='M 455 143 L 403,143' />
+
+<!-- ============= Table 'book_recipe' ============= -->
+<rect class='shadow' x='474' y='143' width='91' height='78' rx='6' ry='6' />
+<rect class='table' x='468' y='137' width='91' height='78' rx='6' ry='6' />
+<path d='M 469 157 L 469 144 Q 469 138 475 138 L 552 138 Q 558 138 558 144 L 558 157 L469 157 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='468' y1='156' x2='559' y2='156'/>
+<a xlink:href='#book_recipe' title='Associates a book with a recipe&#046;' ><text x='475' y='152' class='tableTitle'>book_recipe</text></a>
+ <use id='pk' x='468' y='165' xlink:href='#pk'/><a xlink:href='#id' title='id serial Primary key&#046;'><text x='481' y='175'>id</text></a>
+ <use id='idx' x='468' y='178' xlink:href='#idx'/><a xlink:href='#book_id' title='book&#095;id int4 Reference to the book table&#046;'><text x='481' y='188'>book_id</text></a>
+ <use id='idx' x='468' y='191' xlink:href='#idx'/><a xlink:href='#recipe_id' title='recipe&#095;id serial Reference to the recipe table&#046;'><text x='481' y='201'>recipe_id</text></a>
+
+<path transform='translate(6,0)' marker-start='url(#foot)' marker-end='url(#arrow)' title='fk&#095;recipe&#095;account' d='M 650 169 L 650,143' />
+
+<!-- ============= Table 'recipe' ============= -->
+<rect class='shadow' x='643' y='182' width='91' height='104' rx='6' ry='6' />
+<rect class='table' x='637' y='176' width='91' height='104' rx='6' ry='6' />
+<path d='M 638 196 L 638 183 Q 638 177 644 177 L 721 177 Q 727 177 727 183 L 727 196 L638 196 ' style='fill:url(#tableHeaderGradient);; stroke:none;' />
+<line class='table' x1='637' y1='195' x2='728' y2='195'/>
+<a xlink:href='#recipe' title='recipe' ><text x='662' y='191' class='tableTitle'>recipe</text></a>
+ <use id='pk' x='637' y='204' xlink:href='#pk'/><a xlink:href='#id' title='id bigserial Every recipe is uniquely identified&#046;'><text x='650' y='214'>id</text></a>
+ <use id='idx' x='637' y='217' xlink:href='#idx'/><a xlink:href='#account_id' title='account&#095;id bigserial Recipe author&#046;'><text x='650' y='227'>account_id</text></a>
+ <a xlink:href='#created' title='created date When the recipe was inserted into the system&#046;'><text x='650' y='240'>created</text></a>
+ <a xlink:href='#updated' title='updated date When the recipe was changed in the system&#046;'><text x='650' y='253'>updated</text></a>
+ <a xlink:href='#deleted' title='deleted date When the recipe was deleted from the system&#046;'><text x='650' y='266'>deleted</text></a>
+
+<g transform='translate(552,520)'> <rect x='10' y='10' width='240' height='45' rx='6' ry='6' style='fill:url(#legendGradient);filter:url(#tableShadow); ' />
+ <text x='25' y='22' style='fill:white;' >Layout recipe_book</text>
+ <text x='25' y='36' style='fill:white;' >Project recipe</text>
+ <a xlink:href='http://www.dbschema.com'>
+ <text x='150' y='50' style='fill:white;' > by DbSchema.com</text>
+ </a>
+</g>
+
+</svg>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='account'>Table account</a> <br/>List of accounts used by people to author recipes. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> bigserial&#040; 19 &#041; NOT NULL DEFO nextval('accounts_id_seq'::regclass) </td>
+<td> Uniquely identifies each account&#046; </td>
+</tr>
+<tr><td class='name'><a name='email'>email</a></td>
+<td> varchar&#040; 256 &#041; NOT NULL </td>
+<td> Email address associated with the account&#046; </td>
+</tr>
+<tr><td class='name'><a name='created'>created</a></td>
+<td> date NOT NULL DEFO ('now'::text)::date </td>
+<td> Date the account was created&#046; </td>
+</tr>
+<tr><td class='name'><a name='updated'>updated</a></td>
+<td> date </td>
+<td> Date the account was last updated&#046; </td>
+</tr>
+<tr><td class='name'><a name='deleted'>deleted</a></td>
+<td> date </td>
+<td> Date the account was deleted&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;accounts primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book'>Table book</a> <br/>Defines the common items to every book. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='label'>label</a></td>
+<td> varchar&#040; 128 &#041; NOT NULL </td>
+<td> Book title&#046; </td>
+</tr>
+<tr><td class='name'><a name='spine_label'>spine&#095;label</a></td>
+<td> varchar&#040; 128 &#041; NOT NULL </td>
+<td> Book spine label&#046; </td>
+</tr>
+<tr><td class='name'><a name='dedication'>dedication</a></td>
+<td> text </td>
+<td> Text for the dedication&#046; </td>
+</tr>
+<tr><td class='name'><a name='isbn'>isbn</a></td>
+<td> varchar&#040; 13 &#041; </td>
+<td> International standard book number and EAN&#044; can be null&#046; </td>
+</tr>
+<tr><td class='name'><a name='created'>created</a></td>
+<td> timestamptz NOT NULL DEFO current_timestamp </td>
+<td> Date the book was created&#046; </td>
+</tr>
+<tr><td class='name'><a name='deleted'>deleted</a></td>
+<td> timestamptz </td>
+<td> Date the book was &#040;or is to be&#063;&#041; deleted&#046; </td>
+</tr>
+<tr><td class='name'><a name='updated'>updated</a></td>
+<td> timestamptz </td>
+<td> Date the book was last updated&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_account'>Table book_account</a> <br/>Associates a book with an account. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='book_id'>book&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> The book associated with an account&#046; </td>
+</tr>
+<tr><td class='name'><a name='account_id'>account&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> The account associated with a book&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;account primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;account </td>
+<td> ( book&#095;id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;account&#095;0 </td>
+<td> ( account&#095;id) </td><td> </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Foreign Keys</b></td></tr>
+<tr>
+<td class='name'>fk_book_account_book_id</td><td > ( book&#095;id ) ref <a href='#book'>book</a> ( id ) </td>
+<td> </td>
+</tr>
+<tr>
+<td class='name'>fk_book_account_account_id</td><td > ( account&#095;id ) ref <a href='#account'>account</a> ( id ) </td>
+<td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_photograph'>Table book_photograph</a> <br/>Describes attributes about a photograph that can be used in the book. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='book_id'>book&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> The book to which this photograph belongs&#046; </td>
+</tr>
+<tr><td class='name'><a name='image_url'>image&#095;url</a></td>
+<td> varchar&#040; 256 &#041; NOT NULL </td>
+<td> The website address where the image can be retrieved&#046; </td>
+</tr>
+<tr><td class='name'><a name='book_photograph_category_id'>book&#095;photograph&#095;category&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> The type of photograph &#040;e&#046;g&#046;&#044; cover page&#044; meal inset&#044; divider page&#044; category section page&#041;&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;photograph primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;photograph </td>
+<td> ( book&#095;id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;photograph&#095;0 </td>
+<td> ( book&#095;photograph&#095;category&#095;id) </td><td> </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Foreign Keys</b></td></tr>
+<tr>
+<td class='name'>fk_book_photograph_book_id</td><td > ( book&#095;id ) ref <a href='#book'>book</a> ( id ) </td>
+<td> </td>
+</tr>
+<tr>
+<td class='name'>fk_book_photograph_book_photograph_category_id</td><td > ( book&#095;photograph&#095;category&#095;id ) ref <a href='#book&#095;photograph&#095;category'>book&#095;photograph&#095;category</a> ( id ) </td>
+<td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_photograph_category'>Table book_photograph_category</a> <br/>Contains a list of categories for book photographs. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='label'>label</a></td>
+<td> varchar NOT NULL </td>
+<td> Text to display to the user&#046; </td>
+</tr>
+<tr><td class='name'><a name='description'>description</a></td>
+<td> varchar&#040; 128 &#041; NOT NULL </td>
+<td> Brief description regarding how the category is used&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;photograph&#095;category primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_preamble'>Table book_preamble</a> <br/> </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;preamble primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_preamble_category'>Table book_preamble_category</a> <br/> </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;preamble&#095;category primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_preference'>Table book_preference</a> <br/>Stores configuration parameters used to generate the book (e.g., layout, fonts, colours). The system must select default values for a book. This table allows users to override the defaults. This indirectly drives the settings for generating a book. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='book_id'>book&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> The preference&#039;s reference to a book&#046; </td>
+</tr>
+<tr><td class='name'><a name='book_preference_code_id'>book&#095;preference&#095;code&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> Reference to the book preference code table&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;preference primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;preference </td>
+<td> ( book&#095;id) </td><td> </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Foreign Keys</b></td></tr>
+<tr>
+<td class='name'>fk_book_preference_book_id</td><td > ( book&#095;id ) ref <a href='#book'>book</a> ( id ) </td>
+<td> </td>
+</tr>
+<tr>
+<td class='name'>fk_book_preference_book_preference_code_id</td><td > ( book&#095;id ) ref <a href='#book&#095;preference&#095;code'>book&#095;preference&#095;code</a> ( id ) </td>
+<td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_preference_code'>Table book_preference_code</a> <br/>List of domains, codes, and values related to book preferences. If later need arises, this table can be split into separate tables to establish foreign key constraints. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='domain'>domain</a></td>
+<td> varchar&#040; 32 &#041; NOT NULL </td>
+<td> Grouping for codes and values &#040;e&#046;g&#046;&#044; BOOK&#095;LAYOUT&#041;&#046; </td>
+</tr>
+<tr><td class='name'><a name='code'>code</a></td>
+<td> varchar&#040; 32 &#041; NOT NULL </td>
+<td> Unique identifier within a given domain&#046; </td>
+</tr>
+<tr><td class='name'><a name='label'>label</a></td>
+<td> varchar NOT NULL </td>
+<td> Text that can be displayed to the user&#046; </td>
+</tr>
+<tr><td class='name'><a name='description'>description</a></td>
+<td> varchar&#040; 128 &#041; NOT NULL </td>
+<td> Brief description about how the code is used&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;preference&#095;code primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='book_recipe'>Table book_recipe</a> <br/>Associates a book with a recipe. </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> serial NOT NULL </td>
+<td> Primary key&#046; </td>
+</tr>
+<tr><td class='name'><a name='book_id'>book&#095;id</a></td>
+<td> int4 NOT NULL </td>
+<td> Reference to the book table&#046; </td>
+</tr>
+<tr><td class='name'><a name='recipe_id'>recipe&#095;id</a></td>
+<td> serial NOT NULL </td>
+<td> Reference to the recipe table&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;book&#095;recipe primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;recipe </td>
+<td> ( recipe&#095;id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;book&#095;recipe&#095;0 </td>
+<td> ( book&#095;id) </td><td> </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Foreign Keys</b></td></tr>
+<tr>
+<td class='name'>fk_book_recipe_recipe_id</td><td > ( recipe&#095;id ) ref <a href='#recipe'>recipe</a> ( id ) </td>
+<td> </td>
+</tr>
+<tr>
+<td class='name'>fk_book_recipe_book_id</td><td > ( book&#095;id ) ref <a href='#book'>book</a> ( id ) </td>
+<td> </td>
+</tr>
+</tbody>
+</table>
+
+<br/><br/>
+<table id='dbs' >
+<thead>
+<tr><th colspan='3'><a name='recipe'>Table recipe</a> <br/> </th></tr>
+</thead>
+<tbody>
+<tr><td class='name'><a name='id'>id</a></td>
+<td> bigserial&#040; 19 &#041; NOT NULL DEFO nextval('recipe_id_seq'::regclass) </td>
+<td> Every recipe is uniquely identified&#046; </td>
+</tr>
+<tr><td class='name'><a name='account_id'>account&#095;id</a></td>
+<td> bigserial&#040; 19 &#041; NOT NULL DEFO nextval('recipe_account_id_seq1'::regclass) </td>
+<td> Recipe author&#046; </td>
+</tr>
+<tr><td class='name'><a name='created'>created</a></td>
+<td> date NOT NULL DEFO ('now'::text)::date </td>
+<td> When the recipe was inserted into the system&#046; </td>
+</tr>
+<tr><td class='name'><a name='updated'>updated</a></td>
+<td> date </td>
+<td> When the recipe was changed in the system&#046; </td>
+</tr>
+<tr><td class='name'><a name='deleted'>deleted</a></td>
+<td> date </td>
+<td> When the recipe was deleted from the system&#046; </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Indexes</b></td></tr>
+<tr><td class='name'>pk&#095;recipe primary key</td>
+<td> ( id) </td><td> </td>
+</tr>
+<tr><td class='name'>idx&#095;recipe </td>
+<td> ( account&#095;id) </td><td> </td>
+</tr>
+<tr><td colspan='3' class='subpart'><b>Foreign Keys</b></td></tr>
+<tr>
+<td class='name'>fk_recipe_account</td><td > ( account&#095;id ) ref <a href='#account'>account</a> ( id ) </td>
+<td> </td>
+</tr>
+</tbody>
+</table>
+</body></html>
recipe-book.dbs
-
+<?xml version="1.0" encoding="UTF-8" ?>
+<project name="recipe" version="42" database="PostgreSQL" >
+ <schema name="public" catalogname="recipe" schemaname="public" defo="y" >
+ <table name="xpath_relations" >
+ <comment>Map of tables and columns to XPaths for use in creating XML documents.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;xpath_relations_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies each row.]]> </comment>
+ </column>
+ <column name="table_name" type="varchar" length="64" jt="12" >
+ <comment> <![CDATA[Name of a table.]]> </comment>
+ </column>
+ <column name="column_name" type="varchar" length="64" jt="12" >
+ <comment> <![CDATA[Name of a column in the table.]]> </comment>
+ </column>
+ <column name="relation" type="varchar" length="3" jt="12" >
+ <comment> <![CDATA[Type of relationship between the table_ and column_name and XPath expression. For example: >, ->, =>.]]> </comment>
+ </column>
+ <column name="expression" type="varchar" length="128" jt="12" >
+ <comment> <![CDATA[Expression that defines how to construct the XML document. This is usually an XPath expression, but could also be a fully qualified PK in a PK-FK relationship.]]> </comment>
+ </column>
+ <column name="document_name" type="varchar" length="64" jt="12" >
+ <comment> <![CDATA[GROUP BY condition for the mapping.]]> </comment>
+ </column>
+ <column name="schema_name" type="varchar" length="64" jt="12" >
+ <comment> <![CDATA[Name of a schema in which the table exists.]]> </comment>
+ </column>
+ <index name="pk_xpath_relations" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <sequence name="xpath_relations_id_seq" start="1" />
+ <function name="execute_xpath" >
+ <string> <![CDATA[CREATE OR REPLACE FUNCTION public.execute_xpath(document_name text)
+ RETURNS text
+ LANGUAGE plpgsql
+AS $function$
+BEGIN
+
+END;
+$function$
+]]> </string>
+ </function>
+ </schema>
+ <schema name="recipe" schemaname="recipe" defo="y" >
+ <table name="account" >
+ <comment>List of accounts used by people to author recipes.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;accounts_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies each account.]]> </comment>
+ </column>
+ <column name="email" type="varchar" length="256" jt="12" mandatory="y" >
+ <comment> <![CDATA[Email address associated with the account.]]> </comment>
+ </column>
+ <column name="created" type="date" jt="91" mandatory="y" >
+ <defo>(&#039;now&#039;::text)::date</defo>
+ <comment> <![CDATA[Date the account was created.]]> </comment>
+ </column>
+ <column name="updated" type="date" jt="91" >
+ <comment> <![CDATA[Date the account was last updated.]]> </comment>
+ </column>
+ <column name="deleted" type="date" jt="91" >
+ <comment> <![CDATA[Date the account was deleted.]]> </comment>
+ </column>
+ <index name="pk_accounts" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="action" >
+ <comment>Name of an action that begins any given step.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;action_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the action.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="15" jt="12" mandatory="y" >
+ <comment> <![CDATA[Name of this action (e.g., cut, fry, mash, slice).]]> </comment>
+ </column>
+ <index name="pk_action" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="cuisine" >
+ <comment>All known cuisines.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;cuisine_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the known cuisines.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="30" jt="12" mandatory="y" />
+ <index name="pk_cuisine" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_cuisine_label" unique="UNIQUE" >
+ <column name="label" />
+ </index>
+ </table>
+ <table name="description" >
+ <comment>Meta data about the recipe.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;description_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies this row.]]> </comment>
+ </column>
+ <column name="recipe_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;description_recipe_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Every recipe is uniquely identified.]]> </comment>
+ </column>
+ <column name="cuisine_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;description_cuisine_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the known cuisines.]]> </comment>
+ </column>
+ <column name="title" type="varchar" length="55" jt="12" mandatory="y" >
+ <comment> <![CDATA[Recipe title.]]> </comment>
+ </column>
+ <column name="diet_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;description_diet_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the row.]]> </comment>
+ </column>
+ <index name="pk_description" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_description" unique="NORMAL" >
+ <column name="recipe_id" />
+ </index>
+ <index name="idx_description_0" unique="NORMAL" >
+ <column name="cuisine_id" />
+ </index>
+ <index name="idx_description_1" unique="NORMAL" >
+ <column name="diet_id" />
+ </index>
+ <fk name="fk_description" to_schema="recipe" to_table="recipe" delete_action="CASCADE" >
+ <fk_column name="recipe_id" pk="id" />
+ </fk>
+ <fk name="fk_description_cuisine" to_schema="recipe" to_table="cuisine" delete_action="CASCADE" >
+ <fk_column name="cuisine_id" pk="id" />
+ </fk>
+ <fk name="fk_description_diet" to_schema="recipe" to_table="diet" delete_action="CASCADE" >
+ <fk_column name="diet_id" pk="id" />
+ </fk>
+ </table>
+ <table name="diet" >
+ <comment>Types of diets.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;diet_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the row.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="15" jt="12" mandatory="y" >
+ <comment> <![CDATA[The diet's name.]]> </comment>
+ </column>
+ <index name="pk_diet" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="direction" >
+ <comment>Represents a single step in the set of directions that belong to a direction group.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;direction_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies this instruction.]]> </comment>
+ </column>
+ <column name="instruction" type="varchar" length="100" jt="12" mandatory="y" >
+ <comment> <![CDATA[Each step in the directions should be a short blurb that describes what to do with the action.]]> </comment>
+ </column>
+ <column name="min_time" type="int2" jt="5" mandatory="y" >
+ <defo>1</defo>
+ <comment> <![CDATA[The minimum amount of time the step requires.]]> </comment>
+ </column>
+ <column name="max_time" type="int2" jt="5" >
+ <comment> <![CDATA[The maximum amount of time the step requires.]]> </comment>
+ </column>
+ <column name="action_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;direction_action_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the action.]]> </comment>
+ </column>
+ <column name="direction_group_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;direction_direction_group_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Associates a step in directions with a group of directions.]]> </comment>
+ </column>
+ <column name="seq" type="int2" jt="5" mandatory="y" >
+ <defo>1</defo>
+ <comment> <![CDATA[Sequence of steps to complete the directions.]]> </comment>
+ </column>
+ <index name="pk_direction" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_direction" unique="NORMAL" >
+ <column name="action_id" />
+ </index>
+ <index name="idx_direction_0" unique="NORMAL" >
+ <column name="direction_group_id" />
+ </index>
+ <fk name="fk_direction" to_schema="recipe" to_table="action" delete_action="CASCADE" >
+ <fk_column name="action_id" pk="id" />
+ </fk>
+ <fk name="fk_direction_group_direction_id" to_schema="recipe" to_table="direction_group" delete_action="CASCADE" >
+ <fk_column name="direction_group_id" pk="id" />
+ </fk>
+ </table>
+ <table name="direction_group" >
+ <comment>Joins ingredient groups to recipes.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_ingredient_group_0_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the row that associates a recipe with an ingredient group.]]> </comment>
+ </column>
+ <column name="recipe_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_direction_group_recipe_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Every recipe is uniquely identified.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="30" jt="12" mandatory="y" >
+ <comment> <![CDATA[Name of a set of directions.]]> </comment>
+ </column>
+ <index name="pk_recipe_ingredient_group_0" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_recipe_direction_group" unique="NORMAL" >
+ <column name="recipe_id" />
+ </index>
+ <fk name="fk_recipe_direction_group" to_schema="recipe" to_table="recipe" delete_action="CASCADE" >
+ <fk_column name="recipe_id" pk="id" />
+ </fk>
+ </table>
+ <table name="equipment" >
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;equipment_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the type of equipment required by a recipe.]]> </comment>
+ </column>
+ <column name="name" type="varchar" length="30" jt="12" mandatory="y" >
+ <comment> <![CDATA[Name of the piece of equipment required to make this recipe.]]> </comment>
+ </column>
+ <column name="abridge" type="varchar" length="15" jt="12" >
+ <comment> <![CDATA[Shorter name for this piece of equipment (the alias, were alias not a keyword).]]> </comment>
+ </column>
+ <column name="equipment_group_id" type="serial" jt="4" mandatory="y" >
+ <defo>nextval(&#039;equipment_equipment_group_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the type of equipment.]]> </comment>
+ </column>
+ <column name="seq" type="int2" jt="5" mandatory="y" >
+ <defo>1</defo>
+ <comment> <![CDATA[Uniquely defines the order of each equipment object, independent of group.]]> </comment>
+ </column>
+ <index name="pk_eqiupment" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_equipment" unique="NORMAL" >
+ <column name="equipment_group_id" />
+ </index>
+ <index name="uk_equipment" unique="UNIQUE" >
+ <column name="name" />
+ <column name="equipment_group_id" />
+ </index>
+ <fk name="fk_equipment" to_schema="recipe" to_table="equipment_group" delete_action="CASCADE" >
+ <fk_column name="equipment_group_id" pk="id" />
+ </fk>
+ </table>
+ <table name="equipment_group" >
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <defo>nextval(&#039;equipment_class_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the type of equipment.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="15" jt="12" mandatory="y" >
+ <comment> <![CDATA[cookware, bakeware, kitchenware, utensils, etc.]]> </comment>
+ </column>
+ <index name="pk_equipment_class" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="ingredient" >
+ <comment>An ingredient that belongs to an ingredient group, which, in turn, belongs to a recipe.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the ingredient.]]> </comment>
+ </column>
+ <column name="ingredient_name_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_ingredient_name_id_seq&#039;::regclass)</defo>
+ </column>
+ <column name="ingredient_group_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_ingredient_group_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[The ingredient group that links to this ingredient.]]> </comment>
+ </column>
+ <column name="min_quantity" type="float4" jt="7" mandatory="y" >
+ <comment> <![CDATA[Indicates how much of the ingredient that the recipe requires.]]> </comment>
+ </column>
+ <column name="max_quantity" type="float4" jt="7" >
+ <comment> <![CDATA[Indicates the maximum amount of this ingredient that the recipe requires.]]> </comment>
+ </column>
+ <column name="scalar" type="int2" jt="5" >
+ <comment> <![CDATA[Weight or length (modified by the unit of measurement).]]> </comment>
+ </column>
+ <column name="unit_id" type="bigserial" length="19" jt="-5" >
+ <defo>nextval(&#039;ingredient_unit_id_seq1&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies this ingredient unit.]]> </comment>
+ </column>
+ <column name="condition" type="varchar" length="30" jt="12" >
+ <comment> <![CDATA[Comma-separated initial preparations for this food item (e.g., "peeled,chopped").]]> </comment>
+ </column>
+ <column name="required" type="bool" jt="-7" mandatory="y" >
+ <defo>true</defo>
+ <comment> <![CDATA[Indicates whether the ingredient is optional.]]> </comment>
+ </column>
+ <column name="seq" type="int2" jt="5" mandatory="y" >
+ <defo>1</defo>
+ <comment> <![CDATA[Ingredient order (spans ingredient groups).]]> </comment>
+ </column>
+ <index name="pk_ingredient" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_ingredient_1" unique="NORMAL" >
+ <column name="unit_id" />
+ </index>
+ <index name="idx_ingredient_2" unique="NORMAL" >
+ <column name="ingredient_name_id" />
+ </index>
+ <index name="idx_ingredient" unique="NORMAL" >
+ <column name="ingredient_group_id" />
+ </index>
+ <fk name="fk_ingredient_1" to_schema="recipe" to_table="ingredient_unit" delete_action="CASCADE" >
+ <fk_column name="unit_id" pk="id" />
+ </fk>
+ <fk name="fk_ingredient_2" to_schema="recipe" to_table="ingredient_name" delete_action="CASCADE" >
+ <fk_column name="ingredient_name_id" pk="id" />
+ </fk>
+ <fk name="fk_ingredient_group_id" to_schema="recipe" to_table="ingredient_group" delete_action="CASCADE" >
+ <fk_column name="ingredient_group_id" pk="id" />
+ </fk>
+ </table>
+ <table name="ingredient_group" >
+ <comment>Joins ingredient groups to recipes.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_ingredient_group_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the row that associates a recipe with an ingredient group.]]> </comment>
+ </column>
+ <column name="recipe_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_ingredient_group_recipe_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Every recipe is uniquely identified.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="30" jt="12" mandatory="y" >
+ <comment> <![CDATA[Name of this ingredient group.]]> </comment>
+ </column>
+ <index name="pk_recipe_ingredient_group" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_recipe_ingredient_group" unique="NORMAL" >
+ <column name="recipe_id" />
+ </index>
+ <fk name="fk_recipe_ingredient_group" to_schema="recipe" to_table="recipe" delete_action="CASCADE" >
+ <fk_column name="recipe_id" pk="id" />
+ </fk>
+ </table>
+ <table name="ingredient_name" >
+ <comment>List of all the ingredient names in the world.</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_name_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the ingredient.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="30" jt="12" mandatory="y" >
+ <comment> <![CDATA[Ingredient name.]]> </comment>
+ </column>
+ <column name="abridge" type="varchar" length="15" jt="12" >
+ <comment> <![CDATA[Shorter name for the ingredient.]]> </comment>
+ </column>
+ <index name="pk_ingredient_name" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="uk_ingredient_label" unique="UNIQUE" >
+ <column name="label" />
+ </index>
+ </table>
+ <table name="ingredient_substitute" >
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_substitute_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the row.]]> </comment>
+ </column>
+ <column name="ingredient_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_substitute_ingredient_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[The ingredient that has an associated substitution.]]> </comment>
+ </column>
+ <column name="substitute_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_substitute_substitute_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[The ingredient that substitutes for ingredient_id.]]> </comment>
+ </column>
+ <index name="pk_ingredient_substitute" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_ingredient_substitute" unique="NORMAL" >
+ <column name="ingredient_id" />
+ </index>
+ <index name="idx_ingredient_substitute_0" unique="NORMAL" >
+ <column name="substitute_id" />
+ </index>
+ <fk name="fk_ingredient_substitute_ingredient" to_schema="recipe" to_table="ingredient" delete_action="CASCADE" >
+ <fk_column name="ingredient_id" pk="id" />
+ </fk>
+ <fk name="fk_ingredient_substitute_substitute" to_schema="recipe" to_table="ingredient" delete_action="CASCADE" >
+ <fk_column name="substitute_id" pk="id" />
+ </fk>
+ </table>
+ <table name="ingredient_unit" >
+ <comment>List of possible units (e.g., cup, teaspoon).</comment>
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;ingredient_unit_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies this ingredient unit.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="15" jt="12" mandatory="y" >
+ <comment> <![CDATA[Name of the unit (e.g., teaspoon, tablespoon).]]> </comment>
+ </column>
+ <index name="pk_unit" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="preparation" >
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;preparation_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies each row.]]> </comment>
+ </column>
+ <column name="recipe_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;preparation_recipe_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Recipe that requires a prehated oven.]]> </comment>
+ </column>
+ <column name="temperature" type="float4" jt="7" mandatory="y" >
+ <comment> <![CDATA[Oven temperature setting.]]> </comment>
+ </column>
+ <column name="unit" type="varchar" length="1" jt="12" mandatory="y" >
+ <comment> <![CDATA[F, C, or K.]]> </comment>
+ </column>
+ <index name="pk_preparation" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_preparation" unique="NORMAL" >
+ <column name="recipe_id" />
+ </index>
+ <fk name="fk_preparation_recipe" to_schema="recipe" to_table="recipe" delete_action="CASCADE" >
+ <fk_column name="recipe_id" pk="id" />
+ </fk>
+ </table>
+ <table name="recipe" >
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Every recipe is uniquely identified.]]> </comment>
+ </column>
+ <column name="account_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_account_id_seq1&#039;::regclass)</defo>
+ <comment> <![CDATA[Recipe author.]]> </comment>
+ </column>
+ <column name="created" type="date" jt="91" mandatory="y" >
+ <defo>(&#039;now&#039;::text)::date</defo>
+ <comment> <![CDATA[When the recipe was inserted into the system.]]> </comment>
+ </column>
+ <column name="updated" type="date" jt="91" >
+ <comment> <![CDATA[When the recipe was changed in the system.]]> </comment>
+ </column>
+ <column name="deleted" type="date" jt="91" >
+ <comment> <![CDATA[When the recipe was deleted from the system.]]> </comment>
+ </column>
+ <index name="pk_recipe" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_recipe" unique="NORMAL" >
+ <column name="account_id" />
+ </index>
+ <fk name="fk_recipe_account" to_schema="recipe" to_table="account" delete_action="CASCADE" >
+ <fk_column name="account_id" pk="id" />
+ </fk>
+ </table>
+ <table name="recipe_equipment_group" >
+ <column name="id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_equipment_group_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies each row that associates a set of equipment with a recipe.]]> </comment>
+ </column>
+ <column name="recipe_id" type="bigserial" length="19" jt="-5" mandatory="y" >
+ <defo>nextval(&#039;recipe_equipment_group_recipe_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Every recipe is uniquely identified.]]> </comment>
+ </column>
+ <column name="equipment_group_id" type="serial" jt="4" mandatory="y" >
+ <defo>nextval(&#039;recipe_equipment_group_equipment_group_id_seq&#039;::regclass)</defo>
+ <comment> <![CDATA[Uniquely identifies the type of equipment.]]> </comment>
+ </column>
+ <index name="pk_recipe_equipment_group" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_recipe_equipment_group" unique="NORMAL" >
+ <column name="recipe_id" />
+ </index>
+ <index name="idx_recipe_equipment_group_0" unique="NORMAL" >
+ <column name="equipment_group_id" />
+ </index>
+ <fk name="fk_recipe_equipment_group" to_schema="recipe" to_table="recipe" delete_action="CASCADE" >
+ <fk_column name="recipe_id" pk="id" />
+ </fk>
+ <fk name="fk_recipe_equipment_group_0" to_schema="recipe" to_table="equipment_group" delete_action="CASCADE" >
+ <fk_column name="equipment_group_id" pk="id" />
+ </fk>
+ </table>
+ <table name="result" >
+ <column name="xmlelement" type="xml" jt="1111" />
+ </table>
+ <sequence name="accounts_id_seq" start="1" />
+ <sequence name="action_id_seq" start="1" />
+ <sequence name="cuisine_id_seq" start="1" />
+ <sequence name="description_cuisine_id_seq" start="1" />
+ <sequence name="description_diet_id_seq" start="1" />
+ <sequence name="description_id_seq" start="1" />
+ <sequence name="description_recipe_id_seq" start="1" />
+ <sequence name="diet_id_seq" start="1" />
+ <sequence name="direction_action_id_seq" start="1" />
+ <sequence name="direction_direction_group_id_seq" start="1" />
+ <sequence name="direction_id_seq" start="1" />
+ <sequence name="equipment_class_id_seq" start="1" />
+ <sequence name="equipment_equipment_group_id_seq" start="1" />
+ <sequence name="equipment_id_seq" start="1" />
+ <sequence name="ingredient_id_seq" start="1" />
+ <sequence name="ingredient_ingredient_group_id_seq" start="1" />
+ <sequence name="ingredient_ingredient_name_id_seq" start="1" />
+ <sequence name="ingredient_name_id_seq" start="1" />
+ <sequence name="ingredient_substitute_id_seq" start="1" />
+ <sequence name="ingredient_substitute_ingredient_id_seq" start="1" />
+ <sequence name="ingredient_substitute_substitute_id_seq" start="1" />
+ <sequence name="ingredient_unit_id_seq" start="1" />
+ <sequence name="ingredient_unit_id_seq1" start="1" />
+ <sequence name="preparation_id_seq" start="1" />
+ <sequence name="preparation_recipe_id_seq" start="1" />
+ <sequence name="recipe_account_id_seq1" start="1" />
+ <sequence name="recipe_direction_group_recipe_id_seq" start="1" />
+ <sequence name="recipe_equipment_group_equipment_group_id_seq" start="1" />
+ <sequence name="recipe_equipment_group_id_seq" start="1" />
+ <sequence name="recipe_equipment_group_recipe_id_seq" start="1" />
+ <sequence name="recipe_id_seq" start="1" />
+ <sequence name="recipe_ingredient_group_0_id_seq" start="1" />
+ <sequence name="recipe_ingredient_group_id_seq" start="1" />
+ <sequence name="recipe_ingredient_group_recipe_id_seq" start="1" />
+ <function name="generate_equipment_xml" >
+ <string> <![CDATA[CREATE OR REPLACE FUNCTION recipe.generate_equipment_xml(recipe_id integer)
+ RETURNS text
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ result TEXT;
+BEGIN
+SELECT
+ xmlelement( name equipment, xmlconcat( array_to_string( array_agg( t.xmlelement ), '' )::xml ) )
+INTO
+ result
+FROM
+(
+SELECT
+ xmlelement( name "bakeware",
+ xmlconcat(
+ array_to_string( array_agg(
+ xmlelement( name "object",
+ xmlattributes( e.abridge AS "alias" ),
+ e.name
+ )
+ ), '')::xml
+ )
+ )
+FROM
+ recipe.equipment_group eg,
+ recipe.equipment e,
+ recipe.recipe_equipment_group reg
+WHERE
+ eg.label='bakeware' AND
+ eg.id = e.equipment_group_id AND
+ eg.id = reg.equipment_group_id AND
+ reg.recipe_id = recipe_id
+UNION ALL
+SELECT
+ xmlelement( name "cookware",
+ xmlconcat(
+ array_to_string( array_agg(
+ xmlelement( name "object",
+ xmlattributes( e.abridge AS "alias" ),
+ e.name
+ )
+ ), '')::xml
+ )
+ )
+FROM
+ recipe.equipment_group eg,
+ recipe.equipment e,
+ recipe.recipe_equipment_group reg
+WHERE
+ eg.label='cookware' AND
+ eg.id = e.equipment_group_id AND
+ eg.id = reg.equipment_group_id AND
+ reg.recipe_id = recipe_id
+UNION ALL
+SELECT
+ xmlelement( name "kitchenware",
+ xmlconcat(
+ array_to_string( array_agg(
+ xmlelement( name "object",
+ xmlattributes( e.abridge AS "alias" ),
+ e.name
+ )
+ ), '')::xml
+ )
+ )
+FROM
+ recipe.equipment_group eg,
+ recipe.equipment e,
+ recipe.recipe_equipment_group reg
+WHERE
+ eg.label='kitchenware' AND
+ eg.id = e.equipment_group_id AND
+ eg.id = reg.equipment_group_id AND
+ reg.recipe_id = recipe_id
+UNION ALL
+SELECT
+ xmlelement( name "utensils",
+ xmlconcat(
+ array_to_string( array_agg(
+ xmlelement( name "object",
+ xmlattributes( e.abridge AS "alias" ),
+ e.name
+ )
+ ), '')::xml
+ )
+ )
+FROM
+ recipe.equipment_group eg,
+ recipe.equipment e,
+ recipe.recipe_equipment_group reg
+WHERE
+ eg.label='utensils' AND
+ eg.id = e.equipment_group_id AND
+ eg.id = reg.equipment_group_id AND
+ reg.recipe_id = recipe_id
+) t;
+ RETURN result;
+END;
+$function$
+]]> </string>
+ </function>
+ <function name="generate_ingredients_xml" >
+ <string> <![CDATA[CREATE OR REPLACE FUNCTION recipe.generate_ingredients_xml(recipe_id integer)
+ RETURNS text
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ recipe_group_id INTEGER;
+ ingredients_xml TEXT;
+ ingredient_list TEXT;
+ result TEXT;
+BEGIN
+ result = '';
+ /**
+ * Remove this loop. It should be possible to build the entire
+ * list of ingredients with a single SQL statement. This is an
+ * optimization to do later.
+ */
+ FOR recipe_group_id IN
+ SELECT
+ rig.id
+ FROM
+ recipe.ingredient_group rig
+ WHERE
+ rig.recipe_id = recipe_id
+ LOOP
+ /* Build the inner <ingredient> elements, one per ingredient group. */
+ SELECT
+ array_to_string(
+ array_agg(
+ xmlelement( name "ingredient",
+ xmlattributes(
+ ri.id AS "id",
+ ri.min_quantity AS "min-quantity",
+ ri.max_quantity AS "max-quantity",
+ riu.label AS "unit",
+ ri.condition AS "condition",
+ not(ri.required) AS "optional",
+ rin.abridge AS "alias",
+ ris.substitute_id AS "subtitute" ),
+ rin.label
+ ) ), '' )
+ INTO
+ ingredient_list
+ FROM
+ recipe.ingredient ri
+ LEFT OUTER JOIN recipe.ingredient_unit riu ON
+ ri.unit_id = riu.id
+ LEFT OUTER JOIN recipe.ingredient_substitute ris ON
+ ri.id = ris.ingredient_id
+ INNER JOIN recipe.ingredient_group rig ON
+ rig.id = ri.ingredient_group_id AND
+ rig.id = recipe_group_id
+ INNER JOIN recipe.ingredient_name rin ON
+ rin.id = ri.ingredient_name_id;
+ /* Build the outer <ingredients> elements around the ingredients_list elements. */
+ SELECT
+ xmlelement( name "ingredients",
+ xmlattributes( rig.label AS "label" ),
+ xmlconcat( ingredient_list::xml )
+ )
+ INTO
+ ingredients_xml
+ FROM
+ recipe.ingredient_group rig
+ WHERE
+ rig.id = recipe_group_id;
+ /* Append all the <ingredients> elements together. */
+ result = result || ingredients_xml;
+ END LOOP;
+ RETURN result;
+END;
+$function$
+]]> </string>
+ </function>
+ <function name="generate_xml" >
+ <string> <![CDATA[CREATE OR REPLACE FUNCTION recipe.generate_xml(recipe_id integer)
+ RETURNS text
+ LANGUAGE plpgsql
+AS $function$
+DECLARE
+ result TEXT;
+BEGIN
+ SELECT
+ xmlelement( name recipe,
+ xmlelement( name description,
+ xmlelement( name title, d.title ),
+ xmlelement( name diet, diet.label ) ),
+ xmlelement( name equipment,
+ xmlconcat( ('<'||eg.label||'>')::xml,
+ xmlelement( name object,
+ xmlattributes( e.abridge AS "alias" ) )
+ )
+ )
+ )
+ INTO
+ result
+ FROM
+ recipe.recipe r,
+ recipe.description d,
+ recipe.diet diet,
+ recipe.equipment e,
+ recipe.equipment_group eg,
+ recipe.recipe_equipment_group reg
+ WHERE
+ r.id = recipe_id AND
+ r.id = d.recipe_id AND
+ d.diet_id = diet.id AND
+ r.id = reg.recipe_id AND
+ reg.equipment_group_id = eg.id AND
+ e.equipment_group_id = eg.id;
+ RETURN result;
+END;
+$function$
+]]> </string>
+ </function>
+ </schema>
+ <schema name="recipe_book" schemaname="recipe_book" defo="y" >
+ <comment>Defines operations and data stores for information related to generating books.</comment>
+ <table name="book" >
+ <comment>Defines the common items to every book.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="label" type="varchar" length="128" jt="12" mandatory="y" >
+ <comment> <![CDATA[Book title.]]> </comment>
+ </column>
+ <column name="spine_label" type="varchar" length="128" jt="12" mandatory="y" >
+ <comment> <![CDATA[Book spine label.]]> </comment>
+ </column>
+ <column name="dedication" type="text" jt="12" >
+ <comment> <![CDATA[Text for the dedication.]]> </comment>
+ </column>
+ <column name="isbn" type="varchar" length="13" jt="12" >
+ <comment> <![CDATA[International standard book number and EAN, can be null.]]> </comment>
+ </column>
+ <column name="created" type="timestamptz" jt="93" mandatory="y" >
+ <defo>current_timestamp</defo>
+ <comment> <![CDATA[Date the book was created.]]> </comment>
+ </column>
+ <column name="deleted" type="timestamptz" jt="93" >
+ <comment> <![CDATA[Date the book was (or is to be?) deleted.]]> </comment>
+ </column>
+ <column name="updated" type="timestamptz" jt="93" >
+ <comment> <![CDATA[Date the book was last updated.]]> </comment>
+ </column>
+ <index name="pk_book" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="book_account" >
+ <comment>Associates a book with an account.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="book_id" type="int4" jt="4" mandatory="y" >
+ <comment> <![CDATA[The book associated with an account.]]> </comment>
+ </column>
+ <column name="account_id" type="int4" jt="4" mandatory="y" >
+ <comment> <![CDATA[The account associated with a book.]]> </comment>
+ </column>
+ <index name="pk_book_account" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_book_account" unique="NORMAL" >
+ <column name="book_id" />
+ </index>
+ <index name="idx_book_account_0" unique="NORMAL" >
+ <column name="account_id" />
+ </index>
+ <fk name="fk_book_account_book_id" to_schema="recipe_book" to_table="book" delete_action="CASCADE" >
+ <fk_column name="book_id" pk="id" />
+ </fk>
+ <fk name="fk_book_account_account_id" to_schema="recipe" to_table="account" delete_action="CASCADE" >
+ <fk_column name="account_id" pk="id" />
+ </fk>
+ </table>
+ <table name="book_photograph" >
+ <comment>Describes attributes about a photograph that can be used in the book.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="book_id" type="int4" length="256" jt="4" mandatory="y" >
+ <comment> <![CDATA[The book to which this photograph belongs.]]> </comment>
+ </column>
+ <column name="image_url" type="varchar" length="256" jt="12" mandatory="y" >
+ <comment> <![CDATA[The website address where the image can be retrieved.]]> </comment>
+ </column>
+ <column name="book_photograph_category_id" type="int4" jt="4" mandatory="y" >
+ <comment> <![CDATA[The type of photograph (e.g., cover page, meal inset, divider page, category section page).]]> </comment>
+ </column>
+ <index name="pk_book_photograph" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_book_photograph" unique="NORMAL" >
+ <column name="book_id" />
+ </index>
+ <index name="idx_book_photograph_0" unique="NORMAL" >
+ <column name="book_photograph_category_id" />
+ </index>
+ <fk name="fk_book_photograph_book_id" to_schema="recipe_book" to_table="book" delete_action="CASCADE" >
+ <fk_column name="book_id" pk="id" />
+ </fk>
+ <fk name="fk_book_photograph_book_photograph_category_id" to_schema="recipe_book" to_table="book_photograph_category" delete_action="CASCADE" >
+ <fk_column name="book_photograph_category_id" pk="id" />
+ </fk>
+ </table>
+ <table name="book_photograph_category" >
+ <comment>Contains a list of categories for book photographs.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="label" type="varchar" jt="12" mandatory="y" >
+ <comment> <![CDATA[Text to display to the user.]]> </comment>
+ </column>
+ <column name="description" type="varchar" length="128" jt="12" mandatory="y" >
+ <comment> <![CDATA[Brief description regarding how the category is used.]]> </comment>
+ </column>
+ <index name="pk_book_photograph_category" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="book_preamble" >
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <index name="pk_book_preamble" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="book_preamble_category" >
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <index name="pk_book_preamble_category" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="book_preference" >
+ <comment>Stores configuration parameters used to generate the book (e.g., layout, fonts, colours). The system must select default values for a book. This table allows users to override the defaults. This indirectly drives the settings for generating a book.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="book_id" type="int4" jt="4" mandatory="y" >
+ <comment> <![CDATA[The preference's reference to a book.]]> </comment>
+ </column>
+ <column name="book_preference_code_id" type="int4" jt="4" mandatory="y" >
+ <comment> <![CDATA[Reference to the book preference code table.]]> </comment>
+ </column>
+ <index name="pk_book_preference" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_book_preference" unique="NORMAL" >
+ <column name="book_id" />
+ </index>
+ <fk name="fk_book_preference_book_id" to_schema="recipe_book" to_table="book" delete_action="CASCADE" >
+ <fk_column name="book_id" pk="id" />
+ </fk>
+ <fk name="fk_book_preference_book_preference_code_id" to_schema="recipe_book" to_table="book_preference_code" delete_action="CASCADE" >
+ <fk_column name="book_id" pk="id" />
+ </fk>
+ </table>
+ <table name="book_preference_code" >
+ <comment>List of domains, codes, and values related to book preferences. If later need arises, this table can be split into separate tables to establish foreign key constraints.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="domain" type="varchar" length="32" jt="12" mandatory="y" >
+ <comment> <![CDATA[Grouping for codes and values (e.g., BOOK_LAYOUT).]]> </comment>
+ </column>
+ <column name="code" type="varchar" length="32" jt="12" mandatory="y" >
+ <comment> <![CDATA[Unique identifier within a given domain.]]> </comment>
+ </column>
+ <column name="label" type="varchar" jt="12" mandatory="y" >
+ <comment> <![CDATA[Text that can be displayed to the user.]]> </comment>
+ </column>
+ <column name="description" type="varchar" length="128" jt="12" mandatory="y" >
+ <comment> <![CDATA[Brief description about how the code is used.]]> </comment>
+ </column>
+ <index name="pk_book_preference_code" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ </table>
+ <table name="book_recipe" >
+ <comment>Associates a book with a recipe.</comment>
+ <column name="id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Primary key.]]> </comment>
+ </column>
+ <column name="book_id" type="int4" jt="4" mandatory="y" >
+ <comment> <![CDATA[Reference to the book table.]]> </comment>
+ </column>
+ <column name="recipe_id" type="serial" jt="4" mandatory="y" >
+ <comment> <![CDATA[Reference to the recipe table.]]> </comment>
+ </column>
+ <index name="pk_book_recipe" unique="PRIMARY_KEY" >
+ <column name="id" />
+ </index>
+ <index name="idx_book_recipe" unique="NORMAL" >
+ <column name="recipe_id" />
+ </index>
+ <index name="idx_book_recipe_0" unique="NORMAL" >
+ <column name="book_id" />
+ </index>
+ <fk name="fk_book_recipe_recipe_id" to_schema="recipe" to_table="recipe" delete_action="CASCADE" >
+ <fk_column name="recipe_id" pk="id" />
+ </fk>
+ <fk name="fk_book_recipe_book_id" to_schema="recipe_book" to_table="book" delete_action="CASCADE" >
+ <fk_column name="book_id" pk="id" />
+ </fk>
+ </table>
+ </schema>
+ <connector name="recipe" database="PostgreSQL" driver_class="org.postgresql.Driver" driver_jar="postgresql-8.4-701.jdbc3.jar" host="localhost" port="5432" instance="recipe" user="recipe" schema_mapping="information_schema:null;pg_catalog:null;pg_toast_temp_1:null;pg_toast_temp_3:null;public:null;recipe:null;recipe_book:null" />
+ <layout name="Chaos" >
+ <entity schema="recipe" name="account" x="481" y="416" />
+ <entity schema="recipe" name="action" x="351" y="416" />
+ <entity schema="recipe" name="cuisine" x="689" y="78" />
+ <entity schema="recipe" name="description" x="637" y="416" />
+ <entity schema="recipe" name="direction" x="481" y="221" />
+ <entity schema="recipe" name="direction_group" x="806" y="416" />
+ <entity schema="recipe" name="equipment" x="637" y="598" />
+ <entity schema="recipe" name="equipment_group" x="273" y="273" />
+ <entity schema="recipe" name="ingredient" x="260" y="598" />
+ <entity schema="recipe" name="ingredient_group" x="806" y="260" />
+ <entity schema="recipe" name="ingredient_name" x="858" y="598" />
+ <entity schema="recipe" name="ingredient_substitute" x="39" y="117" />
+ <entity schema="recipe" name="ingredient_unit" x="156" y="416" />
+ <entity schema="recipe" name="recipe" x="481" y="39" />
+ <entity schema="recipe" name="recipe_equipment_group" x="858" y="767" />
+ <entity schema="recipe" name="result" x="312" y="91" />
+ <callout x="91" y="78" pointer="SV" >
+ <comment> <![CDATA[Use this layer for database synch.]]> </comment>
+ </callout>
+ </layout>
+ <layout name="recipe_book" >
+ <entity schema="recipe" name="account" x="637" y="39" />
+ <entity schema="recipe_book" name="book" x="312" y="39" />
+ <entity schema="recipe_book" name="book_account" x="455" y="39" />
+ <entity schema="recipe_book" name="book_photograph" x="39" y="39" />
+ <entity schema="recipe_book" name="book_photograph_category" x="39" y="260" />
+ <entity schema="recipe_book" name="book_preamble" x="611" y="338" />
+ <entity schema="recipe_book" name="book_preamble_category" x="611" y="429" />
+ <entity schema="recipe_book" name="book_preference" x="260" y="260" />
+ <entity schema="recipe_book" name="book_preference_code" x="273" y="377" />
+ <entity schema="recipe_book" name="book_recipe" x="468" y="143" />
+ <entity schema="recipe" name="recipe" x="637" y="182" />
+ <group name="Book" color="33cc00" >
+ <entity schema="recipe_book" name="book_account" />
+ <entity schema="recipe_book" name="book_photograph" />
+ <entity schema="recipe_book" name="book" />
+ <entity schema="recipe_book" name="book_photograph_category" />
+ <entity schema="recipe_book" name="book_preference" />
+ <entity schema="recipe_book" name="book_preference_code" />
+ <entity schema="recipe_book" name="book_recipe" />
+ </group>
+ <group name="Recipe" color="0066ff" >
+ <entity schema="recipe" name="account" />
+ <entity schema="recipe" name="recipe" />
+ </group>
+ <group name="Latex" color="cc00ff" >
+ <entity schema="recipe_book" name="book_preamble_category" />
+ <entity schema="recipe_book" name="book_preamble" />
+ </group>
+ </layout>
+ <layout name="recipe_zeal" >
+ <entity schema="recipe" name="account" x="195" y="377" />
+ <entity schema="recipe" name="action" x="793" y="494" />
+ <entity schema="recipe" name="cuisine" x="468" y="533" />
+ <entity schema="recipe" name="description" x="325" y="546" />
+ <entity schema="recipe" name="diet" x="468" y="624" />
+ <entity schema="recipe" name="direction" x="598" y="494" />
+ <entity schema="recipe" name="direction_group" x="598" y="377" />
+ <entity schema="recipe" name="equipment" x="39" y="117" />
+ <entity schema="recipe" name="equipment_group" x="234" y="117" />
+ <entity schema="recipe" name="ingredient" x="468" y="156" />
+ <entity schema="recipe" name="ingredient_group" x="468" y="39" />
+ <entity schema="recipe" name="ingredient_name" x="689" y="234" />
+ <entity schema="recipe" name="ingredient_substitute" x="689" y="143" />
+ <entity schema="recipe" name="ingredient_unit" x="689" y="39" />
+ <entity schema="recipe" name="preparation" x="468" y="416" />
+ <entity schema="recipe" name="recipe" x="325" y="377" />
+ <entity schema="recipe" name="recipe_equipment_group" x="195" y="234" />
+ <group name="Recipe" color="ccffcc" >
+ <entity schema="recipe" name="preparation" />
+ <entity schema="recipe" name="cuisine" />
+ <entity schema="recipe" name="diet" />
+ <entity schema="recipe" name="direction_group" />
+ <entity schema="recipe" name="action" />
+ <entity schema="recipe" name="direction" />
+ </group>
+ <group name="Equipment" color="99ffff" >
+ <entity schema="recipe" name="recipe_equipment_group" />
+ <entity schema="recipe" name="equipment_group" />
+ <entity schema="recipe" name="equipment" />
+ </group>
+ <group name="Ingredient" color="ccccff" >
+ <entity schema="recipe" name="ingredient_name" />
+ <entity schema="recipe" name="ingredient_group" />
+ <entity schema="recipe" name="ingredient_unit" />
+ <entity schema="recipe" name="ingredient_substitute" />
+ <entity schema="recipe" name="ingredient" />
+ </group>
+ </layout>
+ <layout name="Public" >
+ <entity schema="public" name="xpath_relations" x="39" y="39" />
+ </layout>
+</project>