@@ -158,6 +158,16 @@ inline void THROW_ERR_SQLITE_ERROR(Isolate* isolate, int errcode) {
158
158
}
159
159
}
160
160
161
+ inline MaybeLocal<Value> NullableSQLiteStringToValue (Isolate* isolate,
162
+ const char * str) {
163
+ if (str == nullptr ) {
164
+ return Null (isolate);
165
+ }
166
+
167
+ return String::NewFromUtf8 (isolate, str, NewStringType::kInternalized )
168
+ .As <Value>();
169
+ }
170
+
161
171
class BackupJob : public ThreadPoolWork {
162
172
public:
163
173
explicit BackupJob (Environment* env,
@@ -1918,6 +1928,72 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
1918
1928
args.GetReturnValue ().Set (result);
1919
1929
}
1920
1930
1931
+ void StatementSync::Columns (const FunctionCallbackInfo<Value>& args) {
1932
+ StatementSync* stmt;
1933
+ ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
1934
+ Environment* env = Environment::GetCurrent (args);
1935
+ THROW_AND_RETURN_ON_BAD_STATE (
1936
+ env, stmt->IsFinalized (), " statement has been finalized" );
1937
+ int num_cols = sqlite3_column_count (stmt->statement_ );
1938
+ Isolate* isolate = env->isolate ();
1939
+ LocalVector<Value> cols (isolate);
1940
+ LocalVector<Name> col_keys (isolate,
1941
+ {env->column_string (),
1942
+ env->database_string (),
1943
+ env->name_string (),
1944
+ env->table_string (),
1945
+ env->type_string ()});
1946
+ Local<Value> value;
1947
+
1948
+ cols.reserve (num_cols);
1949
+ for (int i = 0 ; i < num_cols; ++i) {
1950
+ LocalVector<Value> col_values (isolate);
1951
+ col_values.reserve (col_keys.size ());
1952
+
1953
+ if (!NullableSQLiteStringToValue (
1954
+ isolate, sqlite3_column_origin_name (stmt->statement_ , i))
1955
+ .ToLocal (&value)) {
1956
+ return ;
1957
+ }
1958
+ col_values.emplace_back (value);
1959
+
1960
+ if (!NullableSQLiteStringToValue (
1961
+ isolate, sqlite3_column_database_name (stmt->statement_ , i))
1962
+ .ToLocal (&value)) {
1963
+ return ;
1964
+ }
1965
+ col_values.emplace_back (value);
1966
+
1967
+ if (!stmt->ColumnNameToName (i).ToLocal (&value)) {
1968
+ return ;
1969
+ }
1970
+ col_values.emplace_back (value);
1971
+
1972
+ if (!NullableSQLiteStringToValue (
1973
+ isolate, sqlite3_column_table_name (stmt->statement_ , i))
1974
+ .ToLocal (&value)) {
1975
+ return ;
1976
+ }
1977
+ col_values.emplace_back (value);
1978
+
1979
+ if (!NullableSQLiteStringToValue (
1980
+ isolate, sqlite3_column_decltype (stmt->statement_ , i))
1981
+ .ToLocal (&value)) {
1982
+ return ;
1983
+ }
1984
+ col_values.emplace_back (value);
1985
+
1986
+ Local<Object> column = Object::New (isolate,
1987
+ Null (isolate),
1988
+ col_keys.data (),
1989
+ col_values.data (),
1990
+ col_keys.size ());
1991
+ cols.emplace_back (column);
1992
+ }
1993
+
1994
+ args.GetReturnValue ().Set (Array::New (isolate, cols.data (), cols.size ()));
1995
+ }
1996
+
1921
1997
void StatementSync::SourceSQLGetter (const FunctionCallbackInfo<Value>& args) {
1922
1998
StatementSync* stmt;
1923
1999
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
@@ -2040,6 +2116,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
2040
2116
SetProtoMethod (isolate, tmpl, " all" , StatementSync::All);
2041
2117
SetProtoMethod (isolate, tmpl, " get" , StatementSync::Get);
2042
2118
SetProtoMethod (isolate, tmpl, " run" , StatementSync::Run);
2119
+ SetProtoMethodNoSideEffect (
2120
+ isolate, tmpl, " columns" , StatementSync::Columns);
2043
2121
SetSideEffectFreeGetter (isolate,
2044
2122
tmpl,
2045
2123
FIXED_ONE_BYTE_STRING (isolate, " sourceSQL" ),
0 commit comments