Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch fileage-enhancement Excluding Merge-Ins
This is equivalent to a diff from 522cf5f66d to 0fba2272fa
2014-12-15
| ||
18:24 | Fix the "files_of_checkin" virtual table implementation so that it works with delta manifests. Change the implementation of compute_fileage() to use common table expressions and the files_of_checkin virtual table for a pure SQL implementation (which turns out to be faster). check-in: c556f8c61c user: drh tags: trunk | |
18:17 | Fix the "files_of_checkin" virtual table so that it works correctly with delta manifests. Closed-Leaf check-in: 0fba2272fa user: drh tags: fileage-enhancement | |
17:53 | A new, faster, implementation of the compute_fileage() utility that is implemented in SQL, using the files_of_checkin virtual tables and a common table expression. check-in: cc1e965504 user: drh tags: fileage-enhancement | |
15:47 | Simply the "fileage" webpage by converting to use of the "files_of_checkin" virtual table. check-in: a0cc614326 user: drh tags: fileage-enhancement | |
2014-12-12
| ||
16:04 | Reset memory in addr for good measure just to be certain nothing is left over. check-in: 522cf5f66d user: andybradford tags: trunk | |
07:13 | Minor spelling correction. check-in: f627634ca8 user: andybradford tags: trunk | |
Changes to src/browse.c.
︙ | ︙ | |||
722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | zClass = mprintf("file file-%s", zExt+1); for( i=5; zClass[i]; i++ ) zClass[i] = fossil_tolower(zClass[i]); }else{ zClass = mprintf("file"); } return zClass; } /* ** Look at all file containing in the version "vid". Construct a ** temporary table named "fileage" that contains the file-id for each ** files, the pathname, the check-in where the file was added, and the ** mtime on that checkin. If zGlob and *zGlob then only files matching ** the given glob are computed. */ int compute_fileage(int vid, const char* zGlob){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < | < < | < < < < < < < < < < < < | < < < < < | | | | | | | > > > > > > > > > > > > > > > > > > > > > | < > | > > > > | > > > > > > > | | | | | | < < < < | | < < | < | < < < < < | | | < < < < | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 | zClass = mprintf("file file-%s", zExt+1); for( i=5; zClass[i]; i++ ) zClass[i] = fossil_tolower(zClass[i]); }else{ zClass = mprintf("file"); } return zClass; } /* ** SQL used to compute the age of all files in checkin :ckin whose ** names match :glob */ static const char zComputeFileAgeSetup[] = @ CREATE TABLE IF NOT EXISTS temp.fileage( @ fnid INTEGER PRIMARY KEY, @ fid INTEGER, @ mid INTEGER, @ mtime DATETIME, @ pathname TEXT @ ); @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin; ; static const char zComputeFileAgeRun[] = @ WITH RECURSIVE @ ckin(x) AS (VALUES(:ckin) UNION ALL @ SELECT pid FROM ckin, plink WHERE cid=x AND isprim) @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname) @ SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name @ FROM ckin, mlink, event, filename @ WHERE mlink.mid=ckin.x @ AND mlink.fnid IN (SELECT fnid FROM foci, filename @ WHERE foci.checkinID=:ckin @ AND filename.name=foci.filename @ AND filename.name GLOB :glob) @ AND filename.fnid=mlink.fnid @ AND event.objid=mlink.mid; ; /* ** Look at all file containing in the version "vid". Construct a ** temporary table named "fileage" that contains the file-id for each ** files, the pathname, the check-in where the file was added, and the ** mtime on that checkin. If zGlob and *zGlob then only files matching ** the given glob are computed. */ int compute_fileage(int vid, const char* zGlob){ Stmt q; db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/); db_prepare(&q, zComputeFileAgeRun /*works-like:"constant"*/); db_bind_int(&q, ":ckin", vid); db_bind_text(&q, ":glob", zGlob && zGlob[0] ? zGlob : "*"); db_exec(&q); db_finalize(&q); return 0; } /* ** Render the number of days in rAge as a more human-readable time span. ** Different units (seconds, minutes, hours, days, months, years) are ** selected depending on the magnitude of rAge. ** ** The string returned is obtained from fossil_malloc() and should be ** freed by the caller. */ char *human_readable_age(double rAge){ if( rAge*86400.0<120 ){ return mprintf("%d seconds", (int)(rAge*86400.0)); }else if( rAge*1440.0<90 ){ return mprintf("%.1f minutes", rAge*1440.0); }else if( rAge*24.0<36 ){ return mprintf("%.1f hours", rAge*24.0); }else if( rAge<365.0 ){ return mprintf("%.1f days", rAge); }else{ return mprintf("%.2f years", rAge/365.0); } } /* ** COMMAND: test-fileage ** ** Usage: %fossil test-fileage CHECKIN */ void test_fileage_cmd(void){ int mid; Stmt q; const char *zGlob = find_option("glob",0,1); db_find_and_open_repository(0,0); verify_all_options(); if( g.argc!=3 ) usage("test-fileage CHECKIN"); mid = name_to_typed_rid(g.argv[2],"ci"); compute_fileage(mid, zGlob); db_prepare(&q, "SELECT fid, mid, julianday('now') - mtime, pathname" " FROM fileage" ); while( db_step(&q)==SQLITE_ROW ){ char *zAge = human_readable_age(db_column_double(&q,2)); fossil_print("%8d %8d %16s %s\n", db_column_int(&q,0), db_column_int(&q,1), zAge, db_column_text(&q,3)); fossil_free(zAge); } db_finalize(&q); } /* ** WEBPAGE: fileage ** ** Parameters: ** name=VERSION Selects the checkin version (default=tip). |
︙ | ︙ | |||
849 850 851 852 853 854 855 | " FROM fileage" " ORDER BY mtime DESC, mid, pathname" ); while( db_step(&q)==SQLITE_ROW ){ double age = baseTime - db_column_double(&q, 0); int mid = db_column_int(&q, 2); const char *zFUuid = db_column_text(&q, 1); | | < < < < < < < < < < < < | | > | 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | " FROM fileage" " ORDER BY mtime DESC, mid, pathname" ); while( db_step(&q)==SQLITE_ROW ){ double age = baseTime - db_column_double(&q, 0); int mid = db_column_int(&q, 2); const char *zFUuid = db_column_text(&q, 1); char *zAge = 0; if( lastMid!=mid ){ @ <tr><td colspan=3><hr></tr> lastMid = mid; zAge = human_readable_age(age); } @ <tr> @ <td>%s(zAge?zAge:"") @ <td width="25"> @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a> @ </tr> @ fossil_free(zAge); } @ <tr><td colspan=3><hr></tr> @ </table> db_finalize(&q); style_footer(); } |
Changes to src/foci.c.
︙ | ︙ | |||
44 45 46 47 48 49 50 | */ struct FociTable { sqlite3_vtab base; /* Base class - must be first */ }; struct FociCursor { sqlite3_vtab_cursor base; /* Base class - must be first */ Manifest *pMan; /* Current manifest */ | > | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | */ struct FociTable { sqlite3_vtab base; /* Base class - must be first */ }; struct FociCursor { sqlite3_vtab_cursor base; /* Base class - must be first */ Manifest *pMan; /* Current manifest */ ManifestFile *pFile; /* Current file */ int iFile; /* File index */ }; #endif /* INTERFACE */ /* ** Connect to or create a foci virtual table. */ |
︙ | ︙ | |||
125 126 127 128 129 130 131 132 133 134 135 136 137 | } /* ** Move a focivfs cursor to the next entry in the file. */ static int fociNext(sqlite3_vtab_cursor *pCursor){ FociCursor *pCsr = (FociCursor *)pCursor; pCsr->iFile++; return SQLITE_OK; } static int fociEof(sqlite3_vtab_cursor *pCursor){ FociCursor *pCsr = (FociCursor *)pCursor; | > | > > | | | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | } /* ** Move a focivfs cursor to the next entry in the file. */ static int fociNext(sqlite3_vtab_cursor *pCursor){ FociCursor *pCsr = (FociCursor *)pCursor; pCsr->pFile = manifest_file_next(pCsr->pMan, 0); pCsr->iFile++; return SQLITE_OK; } static int fociEof(sqlite3_vtab_cursor *pCursor){ FociCursor *pCsr = (FociCursor *)pCursor; return pCsr->pFile==0; } static int fociFilter( sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ FociCursor *pCur = (FociCursor *)pCursor; manifest_destroy(pCur->pMan); if( idxNum ){ pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0); pCur->iFile = 0; manifest_file_rewind(pCur->pMan); pCur->pFile = manifest_file_next(pCur->pMan, 0); }else{ pCur->pMan = 0; pCur->iFile = 0; } return SQLITE_OK; } static int fociColumn( sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, int i ){ FociCursor *pCsr = (FociCursor *)pCursor; switch( i ){ case 0: /* checkinID */ sqlite3_result_int(ctx, pCsr->pMan->rid); break; case 1: /* filename */ sqlite3_result_text(ctx, pCsr->pFile->zName, -1, SQLITE_TRANSIENT); break; case 2: /* uuid */ sqlite3_result_text(ctx, pCsr->pFile->zUuid, -1, SQLITE_TRANSIENT); break; case 3: /* previousName */ sqlite3_result_text(ctx, pCsr->pFile->zPrior, -1, SQLITE_TRANSIENT); break; case 4: /* perm */ sqlite3_result_text(ctx, pCsr->pFile->zPerm, -1, SQLITE_TRANSIENT); break; } return SQLITE_OK; } static int fociRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ |
︙ | ︙ |