Fossil

Diff
Login

Differences From Artifact [431c30c840]:

To Artifact [a0de858682]:


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;
}