4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
19 #include "sqlite3expert.h"
22 static void option_requires_argument(const char *zOpt
){
23 fprintf(stderr
, "Option requires an argument: %s\n", zOpt
);
27 static int option_integer_arg(const char *zVal
){
31 static void usage(char **argv
){
32 fprintf(stderr
, "\n");
33 fprintf(stderr
, "Usage %s ?OPTIONS? DATABASE\n", argv
[0]);
34 fprintf(stderr
, "\n");
35 fprintf(stderr
, "Options are:\n");
36 fprintf(stderr
, " -sql SQL (analyze SQL statements passed as argument)\n");
37 fprintf(stderr
, " -file FILE (read SQL statements from file FILE)\n");
38 fprintf(stderr
, " -verbose LEVEL (integer verbosity level. default 1)\n");
39 fprintf(stderr
, " -sample PERCENT (percent of db to sample. default 100)\n");
43 static int readSqlFromFile(sqlite3expert
*p
, const char *zFile
, char **pzErr
){
44 FILE *in
= fopen(zFile
, "rb");
50 *pzErr
= sqlite3_mprintf("failed to open file %s\n", zFile
);
53 fseek(in
, 0, SEEK_END
);
56 pBuf
= sqlite3_malloc64( nIn
+1 );
57 nRead
= fread(pBuf
, nIn
, 1, in
);
61 *pzErr
= sqlite3_mprintf("failed to read file %s\n", zFile
);
65 rc
= sqlite3_expert_sql(p
, pBuf
, pzErr
);
70 int main(int argc
, char **argv
){
75 int iVerbose
= 1; /* -verbose option */
80 if( argc
<2 ) usage(argv
);
82 if( zDb
[0]=='-' ) usage(argv
);
83 rc
= sqlite3_open(zDb
, &db
);
85 fprintf(stderr
, "Cannot open db file: %s - %s\n", zDb
, sqlite3_errmsg(db
));
89 p
= sqlite3_expert_new(db
, &zErr
);
91 fprintf(stderr
, "Cannot run analysis: %s\n", zErr
);
94 for(i
=1; i
<(argc
-1); i
++){
97 if( zArg
[0]=='-' && zArg
[1]=='-' && zArg
[2]!=0 ) zArg
++;
98 nArg
= (int)strlen(zArg
);
99 if( nArg
>=2 && 0==sqlite3_strnicmp(zArg
, "-file", nArg
) ){
100 if( ++i
==(argc
-1) ) option_requires_argument("-file");
101 rc
= readSqlFromFile(p
, argv
[i
], &zErr
);
104 else if( nArg
>=3 && 0==sqlite3_strnicmp(zArg
, "-sql", nArg
) ){
105 if( ++i
==(argc
-1) ) option_requires_argument("-sql");
106 rc
= sqlite3_expert_sql(p
, argv
[i
], &zErr
);
109 else if( nArg
>=3 && 0==sqlite3_strnicmp(zArg
, "-sample", nArg
) ){
111 if( ++i
==(argc
-1) ) option_requires_argument("-sample");
112 iSample
= option_integer_arg(argv
[i
]);
113 sqlite3_expert_config(p
, EXPERT_CONFIG_SAMPLE
, iSample
);
116 else if( nArg
>=2 && 0==sqlite3_strnicmp(zArg
, "-verbose", nArg
) ){
117 if( ++i
==(argc
-1) ) option_requires_argument("-verbose");
118 iVerbose
= option_integer_arg(argv
[i
]);
128 rc
= sqlite3_expert_analyze(p
, &zErr
);
132 int nQuery
= sqlite3_expert_count(p
);
134 const char *zCand
= sqlite3_expert_report(p
,0,EXPERT_REPORT_CANDIDATES
);
135 fprintf(stdout
, "-- Candidates -------------------------------\n");
136 fprintf(stdout
, "%s\n", zCand
);
138 for(i
=0; i
<nQuery
; i
++){
139 const char *zSql
= sqlite3_expert_report(p
, i
, EXPERT_REPORT_SQL
);
140 const char *zIdx
= sqlite3_expert_report(p
, i
, EXPERT_REPORT_INDEXES
);
141 const char *zEQP
= sqlite3_expert_report(p
, i
, EXPERT_REPORT_PLAN
);
142 if( zIdx
==0 ) zIdx
= "(no new indexes)\n";
144 fprintf(stdout
, "-- Query %d ----------------------------------\n",i
+1);
145 fprintf(stdout
, "%s\n\n", zSql
);
147 fprintf(stdout
, "%s\n%s\n", zIdx
, zEQP
);
150 fprintf(stderr
, "Error: %s\n", zErr
? zErr
: "?");
153 sqlite3_expert_destroy(p
);