11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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
|
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
|
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This module contains the code that initializes the "sqlite3" command-line
** This module contains the code that initializes the "sqlite4" command-line
** shell against the repository database. The command-line shell itself
** is a copy of the "shell.c" code from SQLite. This file contains logic
** to initialize the code in shell.c.
*/
#include "config.h"
#include "sqlcmd.h"
#include <zlib.h>
/*
** Implementation of the "content(X)" SQL function. Return the complete
** content of artifact identified by X as a blob.
*/
static void sqlcmd_content(
sqlite3_context *context,
sqlite4_context *context,
int argc,
sqlite3_value **argv
sqlite4_value **argv
){
int rid;
Blob cx;
const char *zName;
assert( argc==1 );
zName = (const char*)sqlite3_value_text(argv[0]);
zName = (const char*)sqlite4_value_text(argv[0]);
if( zName==0 ) return;
g.db = sqlite3_context_db_handle(context);
g.db = sqlite4_context_db_handle(context);
g.repositoryOpen = 1;
rid = name_to_rid(zName);
if( rid==0 ) return;
if( content_get(rid, &cx) ){
sqlite3_result_blob(context, blob_buffer(&cx), blob_size(&cx),
sqlite4_result_blob(context, blob_buffer(&cx), blob_size(&cx),
SQLITE_TRANSIENT);
blob_reset(&cx);
}
}
/*
** Implementation of the "compress(X)" SQL function. The input X is
** compressed using zLib and the output is returned.
*/
static void sqlcmd_compress(
sqlite3_context *context,
sqlite4_context *context,
int argc,
sqlite3_value **argv
sqlite4_value **argv
){
const unsigned char *pIn;
unsigned char *pOut;
unsigned int nIn;
unsigned long int nOut;
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
pIn = sqlite4_value_blob(argv[0]);
nIn = sqlite4_value_bytes(argv[0]);
nOut = 13 + nIn + (nIn+999)/1000;
pOut = sqlite3_malloc( nOut+4 );
pOut = sqlite4_malloc(0, nOut+4);
pOut[0] = nIn>>24 & 0xff;
pOut[1] = nIn>>16 & 0xff;
pOut[2] = nIn>>8 & 0xff;
pOut[3] = nIn & 0xff;
compress(&pOut[4], &nOut, pIn, nIn);
sqlite3_result_blob(context, pOut, nOut+4, sqlite3_free);
sqlite4_result_blob(context, pOut, nOut+4, SQLITE_DYNAMIC);
}
/*
** Implementation of the "decompress(X)" SQL function. The argument X
** is a blob which was obtained from compress(Y). The output will be
** the value Y.
*/
static void sqlcmd_decompress(
sqlite3_context *context,
sqlite4_context *context,
int argc,
sqlite3_value **argv
sqlite4_value **argv
){
const unsigned char *pIn;
unsigned char *pOut;
unsigned int nIn;
unsigned long int nOut;
int rc;
pIn = sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
pIn = sqlite4_value_blob(argv[0]);
nIn = sqlite4_value_bytes(argv[0]);
nOut = (pIn[0]<<24) + (pIn[1]<<16) + (pIn[2]<<8) + pIn[3];
pOut = sqlite3_malloc( nOut+1 );
pOut = sqlite4_malloc(0, nOut+1);
rc = uncompress(pOut, &nOut, &pIn[4], nIn-4);
if( rc==Z_OK ){
sqlite3_result_blob(context, pOut, nOut, sqlite3_free);
sqlite4_result_blob(context, pOut, nOut, SQLITE_DYNAMIC);
}else{
sqlite3_result_error(context, "input is not zlib compressed", -1);
sqlite4_result_error(context, "input is not zlib compressed", -1);
}
}
/*
** This is the "automatic extensionn" initializer that runs right after
** the connection to the repository database is opened. Set up the
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
sqlite3 *db,
sqlite4 *db,
const char **pzErrMsg,
const void *notUsed
){
sqlite3_create_function(db, "content", 1, SQLITE_ANY, 0,
sqlite4_create_function(db, "content", 1, SQLITE_ANY, 0,
sqlcmd_content, 0, 0);
sqlite3_create_function(db, "compress", 1, SQLITE_ANY, 0,
sqlite4_create_function(db, "compress", 1, SQLITE_ANY, 0,
sqlcmd_compress, 0, 0);
sqlite3_create_function(db, "decompress", 1, SQLITE_ANY, 0,
sqlite4_create_function(db, "decompress", 1, SQLITE_ANY, 0,
sqlcmd_decompress, 0, 0);
return SQLITE_OK;
}
/*
** COMMAND: sqlite3
** COMMAND: sqlite4
**
** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS?
** Usage: %fossil sqlite4 ?DATABASE? ?OPTIONS?
**
** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS.
** Run the standalone sqlite4 command-line shell on DATABASE with OPTIONS.
** If DATABASE is omitted, then the repository that serves the working
** directory is opened.
**
** WARNING: Careless use of this command can corrupt a Fossil repository
** in ways that are unrecoverable. Be sure you know what you are doing before
** running any SQL commands that modifies the repository database.
*/
void sqlite3_cmd(void){
extern int sqlite3_shell(int, char**);
void sqlite4_cmd(void){
extern int sqlite4_shell(int, char**);
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
db_close(1);
sqlite3_shutdown();
sqlite3_shell(g.argc-1, g.argv+1);
sqlite4_shutdown(0);
sqlite4_shell(g.argc-1, g.argv+1);
}
/*
** This routine is called by the patched sqlite3 command-line shell in order
** This routine is called by the patched sqlite4 command-line shell in order
** to load the name and database connection for the open Fossil database.
*/
void fossil_open(const char **pzRepoName){
sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit);
/*sqlite4_auto_extension((void(*)(void))sqlcmd_autoinit);*/
*pzRepoName = g.zRepositoryName;
}
|