Editing
Primes Software Specification
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
<span id="software-specification-primes.cbsql"></span> = Software Specification β <code>Primes.cbsql</code> = <blockquote>'''Standard:''' IEEE 830 / ISO/IEC 29148 (Requirements) Β· IEEE 1016 (Design) Β· ISO/IEC 11179 (Data Dictionary) Β· UML 2.x Activity Diagrams<br /> '''Source:''' <code>Primes.cbsql</code> β GnuCOBOL + GixSQL preprocessed source<br /> '''Date:''' 2026-03-17<br /> '''Status:''' Reverse-engineered </blockquote> ----- <span id="table-of-contents"></span> == Table of Contents == # [[#1-business-requirements-document|Business Requirements Document]] # [[#2-technical-specification--pseudocode|Technical Specification / Pseudocode]] # [[#3-data-dictionary|Data Dictionary]] # [[#4-flow-diagrams|Flow Diagrams]] ----- <span id="business-requirements-document"></span> == 1. Business Requirements Document == <span id="purpose"></span> === 1.1 Purpose === <code>Primes.cbsql</code> is a COBOL Data Access Layer (DAL) module that manages persistent storage of prime numbers in a PostgreSQL database. It is not a standalone program; it is invoked by a calling driver program that selects the desired operation via a shared linkage interface (<code>primes-dal</code>). <span id="scope"></span> === 1.2 Scope === The module handles all database interactions for the prime number generation system, including connection lifecycle management, cursor-based sequential reads, row-by-row prime retrieval for trial division, and insertion of newly discovered primes. <span id="system-context"></span> === 1.3 System Context === {| ! Item ! Value |- | '''Platform''' | Linux (GnuCOBOL + GixSQL) |- | '''Database''' | PostgreSQL 5432 @ localhost |- | '''Schema''' | <code>primes</code> |- | '''Database name''' | <code>primes</code> |- | '''DB user''' | <code>primes_user</code> |- | '''UI module''' | <code>primesui</code> (called for all status messages) |- | '''Linkage interface''' | <code>primes-dal</code> (copybook) |} <span id="business-functions"></span> === 1.4 Business Functions === {| !width="33%"| ID !width="33%"| Method Flag !width="33%"| Description |- | BF-01 | <code>db-connect</code> | Establish a connection to the PostgreSQL database |- | BF-02 | <code>db-cursor</code> | Begin a transaction and open a cursor for reading all primes |- | BF-03 | <code>next-prime</code> | Fetch the next prime row from the open cursor |- | BF-04 | <code>next-divider</code> | Retrieve a specific prime by identity index to use as a trial divisor |- | BF-05 | <code>write-prime</code> | Insert a newly proven prime into the database |- | BF-06 | <code>db-disconnect</code> | Close the database connection and release resources |} <span id="business-rules"></span> === 1.5 Business Rules === {| !width="50%"| ID !width="50%"| Rule |- | BR-01 | The initial prime value <code>2</code> is inserted as a seed record during first-run initialisation (<code>r90-generate-primes</code>) |- | BR-02 | All operations must set <code>dal-result</code> to <code>0</code> on success or <code>1</code> on failure |- | BR-03 | All status messages (success and error) must be routed through the <code>primesui</code> subprogram |- | BR-04 | Raw SQL error codes (<code>SQLCODE</code>) must be displayed to the console on failure |- | BR-05 | Trial division uses stored primes up to the square root of the candidate number |} <span id="assumptions-and-constraints"></span> === 1.6 Assumptions and Constraints === * The database schema and table (<code>primes.primes</code>) must exist prior to program execution. * The calling program is responsible for managing the sequence of DAL method calls. * <code>r90-generate-primes</code> (seed insertion) is not reachable via the DAL dispatch and must be called directly during initial setup. ----- <span id="technical-specification-pseudocode"></span> == 2. Technical Specification / Pseudocode == <span id="program-entry-and-dispatch"></span> === 2.1 Program Entry and Dispatch === <pre>PROGRAM primes CALLED BY: external driver via LINKAGE SECTION (primes-dal) ON ENTRY: EVALUATE TRUE on dal-method flag: WHEN next-prime β PERFORM r80-get-next-prime WHEN next-divider β PERFORM r81-get-next-divider WHEN write-prime β PERFORM r83-write-prime WHEN db-connect β PERFORM s00-connect WHEN db-cursor β PERFORM s01-cursor WHEN db-disconnect β PERFORM s99-disconnect WHEN OTHER β SET dal-result = 1 END-EVALUATE EXIT PROGRAM</pre> <span id="paragraph-specifications"></span> === 2.2 Paragraph Specifications === ==== r80-get-next-prime ==== <pre>PERFORM s02-fetch</pre> ==== r81-get-next-divider ==== <pre>new-ident = old-ident + 1 SQL: SELECT prime FROM primes WHERE ident = :new-ident INTO :test-divider IF SQLCODE = 0 (test-divider now holds the next divisor prime) ELSE DISPLAY SQLCODE to console DISPLAY "select new-divider nok" to console old-ident = new-ident</pre> ==== r83-write-prime ==== <pre>SQL: INSERT INTO primes (prime) VALUES (:prime) IF SQLCODE != 0 DISPLAY SQLCODE to console DISPLAY "insert next prime nok" + prime-number to console</pre> <span id="r90-generate-primes-first-run-initialisation-not-via-dal-dispatch"></span> ==== r90-generate-primes ''(first-run initialisation, not via DAL dispatch)'' ==== <pre>PERFORM s00-connect IF dal-method-ok SQL: INSERT INTO primes (prime) VALUES (2) -- seed record IF SQLCODE = 0 primes-sequence = 1 prime-number = 2 dal-result = 0 LOG "Initial insert ok." ELSE LOG "Initial insert failed, terminating." dal-result = 1 CALL primesui (log-message)</pre> ==== s00-connect ==== <pre>SQL: CONNECT TO :DATASRC AS primes USER :DBUSR USING :DBPWD IF SQLCODE = 0 dal-result = 0 LOG "Database initialisation ok." ELSE LOG "Database initialisation failed, terminating." dal-result = 1 CALL primesui</pre> ==== s01-cursor ==== <pre>SQL: START TRANSACTION IF SQLCODE = 0 LOG "Start transaction ok." ELSE LOG "Start transaction nok." dal-result = 1 CALL primesui IF dal-method-ok OPEN CURSOR primescursor (SELECT * FROM primes) IF SQLCODE = 0 LOG "Start primescursor ok." ELSE LOG "Start primescursor nok." dal-result = 1 CALL primesui</pre> ==== s02-fetch ==== <pre>SQL: FETCH primescursor INTO :r-ident, :r-prime IF SQLCODE = 0 primes-sequence = r-ident prime-number = r-prime dal-result = 0 ELSE LOG "Fetch row nok." dal-result = 1 CALL primesui</pre> ==== s99-disconnect ==== <pre>SQL: CONNECT RESET primes IF SQLCODE = 0 dal-result = 0 LOG "Close database ok." ELSE LOG "Database initialisation failed, ending." dal-result = 1 CALL primesui DISPLAY "s99 disconnect from database" to console DISPLAY SQLCODE to console</pre> ----- <span id="data-dictionary"></span> == 3. Data Dictionary == <span id="working-storage-fields"></span> === 3.1 Working Storage Fields === {| !width="25%"| Field !width="25%"| PIC !width="25%"| COBOL Type !width="25%"| Description |- | <code>DATASRC</code> | <code>X(64)</code> | Alphanumeric | PostgreSQL connection string |- | <code>DBUSR</code> | <code>X(64)</code> | Alphanumeric | Database login username |- | <code>DBPWD</code> | <code>X(64)</code> | Alphanumeric | Database login password |- | <code>CUR-STEP</code> | <code>X(16)</code> | Alphanumeric | Current processing step label |- | <code>prime-count</code> | <code>9(9)</code> | Numeric | Count of primes (declared; populated by driver) |- | <code>prime_seq</code> | <code>9(9)</code> | Numeric | Prime sequence number (declared; populated by driver) |- | <code>divider</code> | <code>9(9)</code> | Numeric | Trial divider working field |} <span id="group-primes-row-database-fetch-buffer"></span> === 3.2 Group: <code>primes-row</code> β Database Fetch Buffer === {| !width="25%"| Field !width="25%"| PIC !width="25%"| COBOL Type !width="25%"| Description |- | <code>r-ident</code> | <code>9(9) COMP-3</code> | Packed decimal | Row identity key fetched from cursor |- | <code>r-prime</code> | <code>9(9) COMP-3</code> | Packed decimal | Prime value fetched from cursor |} <span id="group-primes-primality-test-working-storage"></span> === 3.3 Group: <code>primes</code> β Primality Test Working Storage === {| !width="33%"| Field !width="33%"| PIC / Value !width="33%"| Description |- | <code>primes-result</code> | <code>9(2)</code> | Status code: <code>1</code>=init ok Β· <code>2</code>=first divider ok Β· <code>3</code>=next divider ok |- | <code>88 init-primes-ok</code> | value <code>1</code> | Condition name: initialisation succeeded |- | <code>88 first-divider-ok</code> | value <code>2</code> | Condition name: first trial divisor retrieved |- | <code>88 next-divider-ok</code> | value <code>3</code> | Condition name: subsequent trial divisor retrieved |- | <code>test-number</code> | <code>9(9)</code> | Candidate number under primality test |- | <code>test-number-sqr</code> | <code>9(9)v9(9)</code> | Square root of <code>test-number</code> β upper bound for divisor loop |- | <code>test-divider</code> | <code>9(9)</code> | Current prime divisor retrieved from DB |- | <code>test-rest</code> | <code>9(9)v9(9)</code> | Remainder of <code>test-number Γ· test-divider</code> |- | <code>old-test-number</code> | <code>9(9)</code> | Previous candidate number |- | <code>old-ident</code> | <code>9(9)</code> | Row identity of the last retrieved divisor |- | <code>new-ident</code> | <code>9(9)</code> | Row identity of the next divisor (<code>old-ident + 1</code>) |} <span id="copybook-references"></span> === 3.4 Copybook References === {| !width="50%"| Copybook !width="50%"| Contents |- | <code>primes-table</code> | COBOL record layout mirroring the <code>primes</code> DB table |- | <code>SQLCA</code> | Standard SQL Communication Area (<code>SQLCODE</code>, <code>SQLERRM</code>, etc.) |- | <code>primes-ui</code> | Data structure for <code>primesui</code> subprogram (messages, program name, methods) |- | <code>primes-dal</code> | DAL linkage interface β method flags and <code>dal-result</code> return code |} <span id="prepared-sql-statements"></span> === 3.5 Prepared SQL Statements === {| !width="33%"| Ref !width="33%"| SQL Text !width="33%"| Used in |- | <code>SQ0001</code> | <code>SELECT * FROM primes</code> | Cursor declaration (s01-cursor) |- | <code>SQ0002</code> | <code>SELECT prime FROM primes WHERE ident = $1</code> | r81-get-next-divider |- | <code>SQ0003</code> | <code>INSERT INTO primes (prime) VALUES ($1)</code> | r83-write-prime |- | <code>SQ0004</code> | <code>INSERT INTO primes (prime) VALUES (2)</code> | r90-generate-primes (seed) |- | <code>SQ0005</code> | <code>START TRANSACTION</code> | s01-cursor |} <span id="database-table-primes.primes"></span> === 3.6 Database Table: <code>primes.primes</code> === {| !width="33%"| Column !width="33%"| Type !width="33%"| Description |- | <code>ident</code> | INTEGER (serial / sequence) | Auto-generated row identity / primary key |- | <code>prime</code> | INTEGER | The prime number value stored in this row |} ----- <span id="flow-diagrams"></span> == 4. Flow Diagrams == <span id="program-entry-dal-dispatch"></span> === 4.1 Program Entry β DAL Dispatch === <pre> ββββββββββββββββββββββββββββ β ENTRY β primes program β β (called with primes-dal) β ββββββββββββββ¬ββββββββββββββ β ββββββββββββΌβββββββββββ β EVALUATE dal-method β ββββββββββββ¬βββββββββββ ββββββββββββ¬βββββββββββββΌββββββββββββ¬βββββββββββββ¬βββββββββββ βΌ βΌ βΌ βΌ βΌ βΌ next-prime next-divider write-prime db-connect db-cursor db-disconnect β β β β β β βΌ βΌ βΌ βΌ βΌ βΌ r80-get- r81-get- r83-write- s00-connect s01-cursor s99-disconnect next-prime next-divider prime β β β β β β ββββββββββββ΄βββββββββββββ΄ββββββββββββ΄βββββββββββββ΄βββββββββββ β ββββββββββββββΌβββββββββββββ β SET dal-result β β 0 = success β β 1 = failure β ββββββββββββββ¬βββββββββββββ β ββββββββββββββΌβββββββββββββ β EXIT PROGRAM β βββββββββββββββββββββββββββ</pre> <span id="database-connection-lifecycle"></span> === 4.2 Database Connection Lifecycle === <pre> Driver calls db-connect Driver calls db-cursor β β βΌ βΌ s00-connect s01-cursor SQL CONNECT SQL START TRANSACTION β β SQLCODE=0? SQLCODE=0? ββ yes β dal-result=0 ββ yes β OPEN primescursor ββ no β dal-result=1 ββ no β dal-result=1 β β CALL primesui CALL primesui β ββββββββββββββΌβββββββββββββββ β Loop: Driver calls β β next-prime repeatedly β β β β β r80 β s02-fetch β β FETCH primescursor β β β primes-sequence β β β prime-number β β SQLCODE=0? loop / stop β ββββββββββββββ¬βββββββββββββββ β Driver calls db-disconnect β s99-disconnect SQL CONNECT RESET β CALL primesui</pre> <span id="prime-discovery-flow-cross-module-context"></span> === 4.3 Prime Discovery Flow (cross-module context) === <pre> Driver: candidate number N to test β βΌ Set old-ident = 0 β βββββββββΌβββββββββββββββββββββββββββββββββ β LOOP: call next-divider β β β r81: new-ident = old-ident + 1 β β β SQL SELECT prime WHERE ident=new β β β test-divider returned β β β β IF test-divider > SQRT(N) β PRIME! β β IF N MOD test-divider = 0 β NOT prime β β ELSE continue loop β βββββββββββββββββββββββββββββββββββββββββ β N is prime? ββ yes β call write-prime β β r83: INSERT INTO primes VALUES (N) ββ no β discard, try N+1 (even numbers typically skipped)</pre> <span id="cursor-fetch-detail"></span> === 4.4 Cursor Fetch Detail === <pre> s02-fetch β GIXSQLStartSQL β GIXSQLSetResultParams (:r-ident) GIXSQLSetResultParams (:r-prime) β GIXSQLCursorFetchOne (primes_primescursor) β GIXSQLEndSQL β SQLCODE = 0? ββ yes β primes-sequence = r-ident β prime-number = r-prime β dal-result = 0 ββ no β LOG "Fetch row nok." dal-result = 1 CALL primesui</pre> ----- ''End of specification.''
Summary:
Please note that all contributions to Webhuis wiki are considered to be released under the GNU Free Documentation License 1.3 or later (see
Project:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
Namespaces
Page
Discussion
English
Views
Read
Edit
View history
More
Search
Navigation
Voorpagina
Cobol and PostgreSQL
PostgreSQL
CFEngine
Proxmox
Webhuis Kennisbank
Basale infra
Webhuis bouwstenen
Webhuis configuratie
Webhuis Infra
Webhuis Support
Webhuis Raspberry
Opzet Applicaties
Business Applicaties
Community portal
Current events
Recent changes
Random page
Help
sitesupport
Tools
What links here
Related changes
Special pages
Page information