Fossil SCM
Add the "jx" column to the "user" and "reportfmt" tables, with the intent of using the column for JSON metadata. Currently unused. Make arrangements to sync the "jx" column (using the "fossil config" command) in a way that is backwards compatible with older versions that do not have the "jx" column.
Commit
b7ac178c4f27d2e01225b0c9f245684279a25ad71063b0c97c0e9b943028aec7
Parent
8dcee008378a64a…
2 files changed
+61
-28
+4
-2
+61
-28
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -357,11 +357,11 @@ | ||
| 357 | 357 | ** NAME CONTENT |
| 358 | 358 | ** ------- ----------------------------------------------------------- |
| 359 | 359 | ** /config $MTIME $NAME value $VALUE |
| 360 | 360 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE |
| 361 | 361 | ** /shun $MTIME $UUID scom $VALUE |
| 362 | -** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE | |
| 362 | +** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON | |
| 363 | 363 | ** /concealed $MTIME $HASH content $VALUE |
| 364 | 364 | ** /subscriber $SMTIME $SEMAIL suname $V ... |
| 365 | 365 | */ |
| 366 | 366 | void configure_receive(const char *zName, Blob *pContent, int groupMask){ |
| 367 | 367 | int checkMask; /* Masks for which we must first check existance of tables */ |
| @@ -378,17 +378,17 @@ | ||
| 378 | 378 | const char *zName; /* Configuration key for this table */ |
| 379 | 379 | const char *zPrimKey; /* Primary key column */ |
| 380 | 380 | int nField; /* Number of data fields */ |
| 381 | 381 | const char *azField[6]; /* Names of the data fields */ |
| 382 | 382 | } aType[] = { |
| 383 | - { "/config", "name", 1, { "value", 0,0,0,0,0 } }, | |
| 384 | - { "@user", "login", 4, { "pw","cap","info","photo",0,0} }, | |
| 385 | - { "@shun", "uuid", 1, { "scom", 0,0,0,0,0} }, | |
| 386 | - { "@reportfmt", "title", 3, { "owner","cols","sqlcode",0,0,0}}, | |
| 387 | - { "@concealed", "hash", 1, { "content", 0,0,0,0,0 } }, | |
| 383 | + { "/config", "name", 1, { "value", 0,0,0,0,0 } }, | |
| 384 | + { "@user", "login", 5, { "pw","cap","info","photo","jx",0} }, | |
| 385 | + { "@shun", "uuid", 1, { "scom", 0,0,0,0,0} }, | |
| 386 | + { "@reportfmt", "title", 4, { "owner","cols","sqlcode","jx",0,0}}, | |
| 387 | + { "@concealed", "hash", 1, { "content", 0,0,0,0,0 } }, | |
| 388 | 388 | { "@subscriber","semail",6, |
| 389 | - { "suname","sdigest","sdonotcall","ssub","sctime","smip"} }, | |
| 389 | + { "suname","sdigest","sdonotcall","ssub","sctime","smip"} }, | |
| 390 | 390 | }; |
| 391 | 391 | |
| 392 | 392 | /* Locate the receiveType in aType[ii] */ |
| 393 | 393 | for(ii=0; ii<count(aType); ii++){ |
| 394 | 394 | if( fossil_strcmp(&aType[ii].zName[1],&zName[1])==0 ) break; |
| @@ -445,11 +445,25 @@ | ||
| 445 | 445 | azToken[1] /*safe-for-%s*/, azToken[0]/*safe-for-%s*/); |
| 446 | 446 | for(jj=2; jj<nToken; jj+=2){ |
| 447 | 447 | blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/); |
| 448 | 448 | } |
| 449 | 449 | db_protect_only(PROTECT_SENSITIVE); |
| 450 | + | |
| 451 | + /* Make sure tables have the "jx" column */ | |
| 452 | + if( strcmp(&zName[1],"user")==0 | |
| 453 | + && db_table_has_column("repository","user","jx")==0 | |
| 454 | + ){ | |
| 455 | + db_multi_exec("ALTER TABLE repository.user ADD COLUMN jx TEXT"); | |
| 456 | + }else | |
| 457 | + if( strcmp(&zName[1],"reportfmt")==0 | |
| 458 | + && db_table_has_column("repository","reportfmt","jx")==0 | |
| 459 | + ){ | |
| 460 | + db_multi_exec("ALTER TABLE repository.reportfmt ADD COLUMN jx TEXT"); | |
| 461 | + } | |
| 462 | + | |
| 450 | 463 | db_multi_exec("%s)", blob_sql_text(&sql)); |
| 464 | + | |
| 451 | 465 | if( db_changes()==0 ){ |
| 452 | 466 | blob_reset(&sql); |
| 453 | 467 | blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s", |
| 454 | 468 | &zName[1], azToken[0]/*safe-for-%s*/); |
| 455 | 469 | for(jj=2; jj<nToken; jj+=2){ |
| @@ -532,41 +546,60 @@ | ||
| 532 | 546 | blob_reset(&rec); |
| 533 | 547 | } |
| 534 | 548 | db_finalize(&q); |
| 535 | 549 | } |
| 536 | 550 | if( groupMask & CONFIGSET_USER ){ |
| 537 | - db_prepare(&q, "SELECT mtime, quote(login), quote(pw), quote(cap)," | |
| 538 | - " quote(info), quote(photo) FROM user" | |
| 539 | - " WHERE mtime>=%lld", iStart); | |
| 551 | + if( db_table_has_column("repository","user","jx") ){ | |
| 552 | + db_prepare(&q, "SELECT mtime, quote(login), quote(pw), quote(cap)," | |
| 553 | + " quote(info), quote(photo), quote(jx) FROM user" | |
| 554 | + " WHERE mtime>=%lld", iStart); | |
| 555 | + }else{ | |
| 556 | + db_prepare(&q, "SELECT mtime, quote(login), quote(pw), quote(cap)," | |
| 557 | + " quote(info), quote(photo), 'NULL' FROM user" | |
| 558 | + " WHERE mtime>=%lld", iStart); | |
| 559 | + } | |
| 540 | 560 | while( db_step(&q)==SQLITE_ROW ){ |
| 541 | - blob_appendf(&rec,"%s %s pw %s cap %s info %s photo %s", | |
| 542 | - db_column_text(&q, 0), | |
| 543 | - db_column_text(&q, 1), | |
| 544 | - db_column_text(&q, 2), | |
| 545 | - db_column_text(&q, 3), | |
| 546 | - db_column_text(&q, 4), | |
| 547 | - db_column_text(&q, 5) | |
| 548 | - ); | |
| 561 | + const char *z; | |
| 562 | + blob_appendf(&rec,"%s %s", db_column_text(&q,0), db_column_text(&q,1)); | |
| 563 | + z = db_column_text(&q,2); | |
| 564 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," pw %s", z); | |
| 565 | + z = db_column_text(&q,3); | |
| 566 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," cap %s", z); | |
| 567 | + z = db_column_text(&q,4); | |
| 568 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," info %s", z); | |
| 569 | + z = db_column_text(&q,5); | |
| 570 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," photo %s", z); | |
| 571 | + z = db_column_text(&q,6); | |
| 572 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," jx %s", z); | |
| 549 | 573 | blob_appendf(pOut, "config /user %d\n%s\n", |
| 550 | 574 | blob_size(&rec), blob_str(&rec)); |
| 551 | 575 | nCard++; |
| 552 | 576 | blob_reset(&rec); |
| 553 | 577 | } |
| 554 | 578 | db_finalize(&q); |
| 555 | 579 | } |
| 556 | 580 | if( groupMask & CONFIGSET_TKT ){ |
| 557 | - db_prepare(&q, "SELECT mtime, quote(title), quote(owner), quote(cols)," | |
| 558 | - " quote(sqlcode) FROM reportfmt" | |
| 559 | - " WHERE mtime>=%lld", iStart); | |
| 581 | + if( db_table_has_column("repository","reportfmt","jx") ){ | |
| 582 | + db_prepare(&q, "SELECT mtime, quote(title), quote(owner), quote(cols)," | |
| 583 | + " quote(sqlcode), quote(jx) FROM reportfmt" | |
| 584 | + " WHERE mtime>=%lld", iStart); | |
| 585 | + }else{ | |
| 586 | + db_prepare(&q, "SELECT mtime, quote(title), quote(owner), quote(cols)," | |
| 587 | + " quote(sqlcode), 'NULL' FROM reportfmt" | |
| 588 | + " WHERE mtime>=%lld", iStart); | |
| 589 | + } | |
| 560 | 590 | while( db_step(&q)==SQLITE_ROW ){ |
| 561 | - blob_appendf(&rec,"%s %s owner %s cols %s sqlcode %s", | |
| 562 | - db_column_text(&q, 0), | |
| 563 | - db_column_text(&q, 1), | |
| 564 | - db_column_text(&q, 2), | |
| 565 | - db_column_text(&q, 3), | |
| 566 | - db_column_text(&q, 4) | |
| 567 | - ); | |
| 591 | + const char *z; | |
| 592 | + blob_appendf(&rec,"%s %s", db_column_text(&q,0), db_column_text(&q,1)); | |
| 593 | + z = db_column_text(&q,2); | |
| 594 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," owner %s", z); | |
| 595 | + z = db_column_text(&q,3); | |
| 596 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," cols %s", z); | |
| 597 | + z = db_column_text(&q,4); | |
| 598 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," sqlcode %s", z); | |
| 599 | + z = db_column_text(&q,5); | |
| 600 | + if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," jx %s", z); | |
| 568 | 601 | blob_appendf(pOut, "config /reportfmt %d\n%s\n", |
| 569 | 602 | blob_size(&rec), blob_str(&rec)); |
| 570 | 603 | nCard++; |
| 571 | 604 | blob_reset(&rec); |
| 572 | 605 | } |
| 573 | 606 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -357,11 +357,11 @@ | |
| 357 | ** NAME CONTENT |
| 358 | ** ------- ----------------------------------------------------------- |
| 359 | ** /config $MTIME $NAME value $VALUE |
| 360 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE |
| 361 | ** /shun $MTIME $UUID scom $VALUE |
| 362 | ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE |
| 363 | ** /concealed $MTIME $HASH content $VALUE |
| 364 | ** /subscriber $SMTIME $SEMAIL suname $V ... |
| 365 | */ |
| 366 | void configure_receive(const char *zName, Blob *pContent, int groupMask){ |
| 367 | int checkMask; /* Masks for which we must first check existance of tables */ |
| @@ -378,17 +378,17 @@ | |
| 378 | const char *zName; /* Configuration key for this table */ |
| 379 | const char *zPrimKey; /* Primary key column */ |
| 380 | int nField; /* Number of data fields */ |
| 381 | const char *azField[6]; /* Names of the data fields */ |
| 382 | } aType[] = { |
| 383 | { "/config", "name", 1, { "value", 0,0,0,0,0 } }, |
| 384 | { "@user", "login", 4, { "pw","cap","info","photo",0,0} }, |
| 385 | { "@shun", "uuid", 1, { "scom", 0,0,0,0,0} }, |
| 386 | { "@reportfmt", "title", 3, { "owner","cols","sqlcode",0,0,0}}, |
| 387 | { "@concealed", "hash", 1, { "content", 0,0,0,0,0 } }, |
| 388 | { "@subscriber","semail",6, |
| 389 | { "suname","sdigest","sdonotcall","ssub","sctime","smip"} }, |
| 390 | }; |
| 391 | |
| 392 | /* Locate the receiveType in aType[ii] */ |
| 393 | for(ii=0; ii<count(aType); ii++){ |
| 394 | if( fossil_strcmp(&aType[ii].zName[1],&zName[1])==0 ) break; |
| @@ -445,11 +445,25 @@ | |
| 445 | azToken[1] /*safe-for-%s*/, azToken[0]/*safe-for-%s*/); |
| 446 | for(jj=2; jj<nToken; jj+=2){ |
| 447 | blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/); |
| 448 | } |
| 449 | db_protect_only(PROTECT_SENSITIVE); |
| 450 | db_multi_exec("%s)", blob_sql_text(&sql)); |
| 451 | if( db_changes()==0 ){ |
| 452 | blob_reset(&sql); |
| 453 | blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s", |
| 454 | &zName[1], azToken[0]/*safe-for-%s*/); |
| 455 | for(jj=2; jj<nToken; jj+=2){ |
| @@ -532,41 +546,60 @@ | |
| 532 | blob_reset(&rec); |
| 533 | } |
| 534 | db_finalize(&q); |
| 535 | } |
| 536 | if( groupMask & CONFIGSET_USER ){ |
| 537 | db_prepare(&q, "SELECT mtime, quote(login), quote(pw), quote(cap)," |
| 538 | " quote(info), quote(photo) FROM user" |
| 539 | " WHERE mtime>=%lld", iStart); |
| 540 | while( db_step(&q)==SQLITE_ROW ){ |
| 541 | blob_appendf(&rec,"%s %s pw %s cap %s info %s photo %s", |
| 542 | db_column_text(&q, 0), |
| 543 | db_column_text(&q, 1), |
| 544 | db_column_text(&q, 2), |
| 545 | db_column_text(&q, 3), |
| 546 | db_column_text(&q, 4), |
| 547 | db_column_text(&q, 5) |
| 548 | ); |
| 549 | blob_appendf(pOut, "config /user %d\n%s\n", |
| 550 | blob_size(&rec), blob_str(&rec)); |
| 551 | nCard++; |
| 552 | blob_reset(&rec); |
| 553 | } |
| 554 | db_finalize(&q); |
| 555 | } |
| 556 | if( groupMask & CONFIGSET_TKT ){ |
| 557 | db_prepare(&q, "SELECT mtime, quote(title), quote(owner), quote(cols)," |
| 558 | " quote(sqlcode) FROM reportfmt" |
| 559 | " WHERE mtime>=%lld", iStart); |
| 560 | while( db_step(&q)==SQLITE_ROW ){ |
| 561 | blob_appendf(&rec,"%s %s owner %s cols %s sqlcode %s", |
| 562 | db_column_text(&q, 0), |
| 563 | db_column_text(&q, 1), |
| 564 | db_column_text(&q, 2), |
| 565 | db_column_text(&q, 3), |
| 566 | db_column_text(&q, 4) |
| 567 | ); |
| 568 | blob_appendf(pOut, "config /reportfmt %d\n%s\n", |
| 569 | blob_size(&rec), blob_str(&rec)); |
| 570 | nCard++; |
| 571 | blob_reset(&rec); |
| 572 | } |
| 573 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -357,11 +357,11 @@ | |
| 357 | ** NAME CONTENT |
| 358 | ** ------- ----------------------------------------------------------- |
| 359 | ** /config $MTIME $NAME value $VALUE |
| 360 | ** /user $MTIME $LOGIN pw $VALUE cap $VALUE info $VALUE photo $VALUE |
| 361 | ** /shun $MTIME $UUID scom $VALUE |
| 362 | ** /reportfmt $MTIME $TITLE owner $VALUE cols $VALUE sqlcode $VALUE jx $JSON |
| 363 | ** /concealed $MTIME $HASH content $VALUE |
| 364 | ** /subscriber $SMTIME $SEMAIL suname $V ... |
| 365 | */ |
| 366 | void configure_receive(const char *zName, Blob *pContent, int groupMask){ |
| 367 | int checkMask; /* Masks for which we must first check existance of tables */ |
| @@ -378,17 +378,17 @@ | |
| 378 | const char *zName; /* Configuration key for this table */ |
| 379 | const char *zPrimKey; /* Primary key column */ |
| 380 | int nField; /* Number of data fields */ |
| 381 | const char *azField[6]; /* Names of the data fields */ |
| 382 | } aType[] = { |
| 383 | { "/config", "name", 1, { "value", 0,0,0,0,0 } }, |
| 384 | { "@user", "login", 5, { "pw","cap","info","photo","jx",0} }, |
| 385 | { "@shun", "uuid", 1, { "scom", 0,0,0,0,0} }, |
| 386 | { "@reportfmt", "title", 4, { "owner","cols","sqlcode","jx",0,0}}, |
| 387 | { "@concealed", "hash", 1, { "content", 0,0,0,0,0 } }, |
| 388 | { "@subscriber","semail",6, |
| 389 | { "suname","sdigest","sdonotcall","ssub","sctime","smip"} }, |
| 390 | }; |
| 391 | |
| 392 | /* Locate the receiveType in aType[ii] */ |
| 393 | for(ii=0; ii<count(aType); ii++){ |
| 394 | if( fossil_strcmp(&aType[ii].zName[1],&zName[1])==0 ) break; |
| @@ -445,11 +445,25 @@ | |
| 445 | azToken[1] /*safe-for-%s*/, azToken[0]/*safe-for-%s*/); |
| 446 | for(jj=2; jj<nToken; jj+=2){ |
| 447 | blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/); |
| 448 | } |
| 449 | db_protect_only(PROTECT_SENSITIVE); |
| 450 | |
| 451 | /* Make sure tables have the "jx" column */ |
| 452 | if( strcmp(&zName[1],"user")==0 |
| 453 | && db_table_has_column("repository","user","jx")==0 |
| 454 | ){ |
| 455 | db_multi_exec("ALTER TABLE repository.user ADD COLUMN jx TEXT"); |
| 456 | }else |
| 457 | if( strcmp(&zName[1],"reportfmt")==0 |
| 458 | && db_table_has_column("repository","reportfmt","jx")==0 |
| 459 | ){ |
| 460 | db_multi_exec("ALTER TABLE repository.reportfmt ADD COLUMN jx TEXT"); |
| 461 | } |
| 462 | |
| 463 | db_multi_exec("%s)", blob_sql_text(&sql)); |
| 464 | |
| 465 | if( db_changes()==0 ){ |
| 466 | blob_reset(&sql); |
| 467 | blob_append_sql(&sql, "UPDATE \"%w\" SET mtime=%s", |
| 468 | &zName[1], azToken[0]/*safe-for-%s*/); |
| 469 | for(jj=2; jj<nToken; jj+=2){ |
| @@ -532,41 +546,60 @@ | |
| 546 | blob_reset(&rec); |
| 547 | } |
| 548 | db_finalize(&q); |
| 549 | } |
| 550 | if( groupMask & CONFIGSET_USER ){ |
| 551 | if( db_table_has_column("repository","user","jx") ){ |
| 552 | db_prepare(&q, "SELECT mtime, quote(login), quote(pw), quote(cap)," |
| 553 | " quote(info), quote(photo), quote(jx) FROM user" |
| 554 | " WHERE mtime>=%lld", iStart); |
| 555 | }else{ |
| 556 | db_prepare(&q, "SELECT mtime, quote(login), quote(pw), quote(cap)," |
| 557 | " quote(info), quote(photo), 'NULL' FROM user" |
| 558 | " WHERE mtime>=%lld", iStart); |
| 559 | } |
| 560 | while( db_step(&q)==SQLITE_ROW ){ |
| 561 | const char *z; |
| 562 | blob_appendf(&rec,"%s %s", db_column_text(&q,0), db_column_text(&q,1)); |
| 563 | z = db_column_text(&q,2); |
| 564 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," pw %s", z); |
| 565 | z = db_column_text(&q,3); |
| 566 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," cap %s", z); |
| 567 | z = db_column_text(&q,4); |
| 568 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," info %s", z); |
| 569 | z = db_column_text(&q,5); |
| 570 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," photo %s", z); |
| 571 | z = db_column_text(&q,6); |
| 572 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," jx %s", z); |
| 573 | blob_appendf(pOut, "config /user %d\n%s\n", |
| 574 | blob_size(&rec), blob_str(&rec)); |
| 575 | nCard++; |
| 576 | blob_reset(&rec); |
| 577 | } |
| 578 | db_finalize(&q); |
| 579 | } |
| 580 | if( groupMask & CONFIGSET_TKT ){ |
| 581 | if( db_table_has_column("repository","reportfmt","jx") ){ |
| 582 | db_prepare(&q, "SELECT mtime, quote(title), quote(owner), quote(cols)," |
| 583 | " quote(sqlcode), quote(jx) FROM reportfmt" |
| 584 | " WHERE mtime>=%lld", iStart); |
| 585 | }else{ |
| 586 | db_prepare(&q, "SELECT mtime, quote(title), quote(owner), quote(cols)," |
| 587 | " quote(sqlcode), 'NULL' FROM reportfmt" |
| 588 | " WHERE mtime>=%lld", iStart); |
| 589 | } |
| 590 | while( db_step(&q)==SQLITE_ROW ){ |
| 591 | const char *z; |
| 592 | blob_appendf(&rec,"%s %s", db_column_text(&q,0), db_column_text(&q,1)); |
| 593 | z = db_column_text(&q,2); |
| 594 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," owner %s", z); |
| 595 | z = db_column_text(&q,3); |
| 596 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," cols %s", z); |
| 597 | z = db_column_text(&q,4); |
| 598 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," sqlcode %s", z); |
| 599 | z = db_column_text(&q,5); |
| 600 | if( strcmp(z,"NULL")!=0 ) blob_appendf(&rec," jx %s", z); |
| 601 | blob_appendf(pOut, "config /reportfmt %d\n%s\n", |
| 602 | blob_size(&rec), blob_str(&rec)); |
| 603 | nCard++; |
| 604 | blob_reset(&rec); |
| 605 | } |
| 606 |
+4
-2
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -126,11 +126,12 @@ | ||
| 126 | 126 | @ cookie TEXT, -- WWW login cookie |
| 127 | 127 | @ ipaddr TEXT, -- IP address for which cookie is valid |
| 128 | 128 | @ cexpire DATETIME, -- Time when cookie expires |
| 129 | 129 | @ info TEXT, -- contact information |
| 130 | 130 | @ mtime DATE, -- last change. seconds since 1970 |
| 131 | -@ photo BLOB -- JPEG image of this user | |
| 131 | +@ photo BLOB, -- JPEG image of this user | |
| 132 | +@ jx TEXT -- Extra fields in JSON | |
| 132 | 133 | @ ); |
| 133 | 134 | @ |
| 134 | 135 | @ -- The config table holds miscellanous information about the repository. |
| 135 | 136 | @ -- in the form of name-value pairs. |
| 136 | 137 | @ -- |
| @@ -176,11 +177,12 @@ | ||
| 176 | 177 | @ rn INTEGER PRIMARY KEY, -- Report number |
| 177 | 178 | @ owner TEXT, -- Owner of this report format (not used) |
| 178 | 179 | @ title TEXT UNIQUE, -- Title of this report |
| 179 | 180 | @ mtime DATE, -- Last modified. seconds since 1970 |
| 180 | 181 | @ cols TEXT, -- A color-key specification |
| 181 | -@ sqlcode TEXT -- An SQL SELECT statement for this report | |
| 182 | +@ sqlcode TEXT, -- An SQL SELECT statement for this report | |
| 183 | +@ jx TEXT -- Additional fields encoded as JSON | |
| 182 | 184 | @ ); |
| 183 | 185 | @ |
| 184 | 186 | @ -- Some ticket content (such as the originators email address or contact |
| 185 | 187 | @ -- information) needs to be obscured to protect privacy. This is achieved |
| 186 | 188 | @ -- by storing an SHA1 hash of the content. For display, the hash is |
| 187 | 189 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -126,11 +126,12 @@ | |
| 126 | @ cookie TEXT, -- WWW login cookie |
| 127 | @ ipaddr TEXT, -- IP address for which cookie is valid |
| 128 | @ cexpire DATETIME, -- Time when cookie expires |
| 129 | @ info TEXT, -- contact information |
| 130 | @ mtime DATE, -- last change. seconds since 1970 |
| 131 | @ photo BLOB -- JPEG image of this user |
| 132 | @ ); |
| 133 | @ |
| 134 | @ -- The config table holds miscellanous information about the repository. |
| 135 | @ -- in the form of name-value pairs. |
| 136 | @ -- |
| @@ -176,11 +177,12 @@ | |
| 176 | @ rn INTEGER PRIMARY KEY, -- Report number |
| 177 | @ owner TEXT, -- Owner of this report format (not used) |
| 178 | @ title TEXT UNIQUE, -- Title of this report |
| 179 | @ mtime DATE, -- Last modified. seconds since 1970 |
| 180 | @ cols TEXT, -- A color-key specification |
| 181 | @ sqlcode TEXT -- An SQL SELECT statement for this report |
| 182 | @ ); |
| 183 | @ |
| 184 | @ -- Some ticket content (such as the originators email address or contact |
| 185 | @ -- information) needs to be obscured to protect privacy. This is achieved |
| 186 | @ -- by storing an SHA1 hash of the content. For display, the hash is |
| 187 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -126,11 +126,12 @@ | |
| 126 | @ cookie TEXT, -- WWW login cookie |
| 127 | @ ipaddr TEXT, -- IP address for which cookie is valid |
| 128 | @ cexpire DATETIME, -- Time when cookie expires |
| 129 | @ info TEXT, -- contact information |
| 130 | @ mtime DATE, -- last change. seconds since 1970 |
| 131 | @ photo BLOB, -- JPEG image of this user |
| 132 | @ jx TEXT -- Extra fields in JSON |
| 133 | @ ); |
| 134 | @ |
| 135 | @ -- The config table holds miscellanous information about the repository. |
| 136 | @ -- in the form of name-value pairs. |
| 137 | @ -- |
| @@ -176,11 +177,12 @@ | |
| 177 | @ rn INTEGER PRIMARY KEY, -- Report number |
| 178 | @ owner TEXT, -- Owner of this report format (not used) |
| 179 | @ title TEXT UNIQUE, -- Title of this report |
| 180 | @ mtime DATE, -- Last modified. seconds since 1970 |
| 181 | @ cols TEXT, -- A color-key specification |
| 182 | @ sqlcode TEXT, -- An SQL SELECT statement for this report |
| 183 | @ jx TEXT -- Additional fields encoded as JSON |
| 184 | @ ); |
| 185 | @ |
| 186 | @ -- Some ticket content (such as the originators email address or contact |
| 187 | @ -- information) needs to be obscured to protect privacy. This is achieved |
| 188 | @ -- by storing an SHA1 hash of the content. For display, the hash is |
| 189 |