@@ -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,
@@ -1897,6 +1907,72 @@ void StatementSync::Run(const FunctionCallbackInfo<Value>& args) {
1897
1907
args.GetReturnValue ().Set (result);
1898
1908
}
1899
1909
1910
+ void StatementSync::Columns (const FunctionCallbackInfo<Value>& args) {
1911
+ StatementSync* stmt;
1912
+ ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
1913
+ Environment* env = Environment::GetCurrent (args);
1914
+ THROW_AND_RETURN_ON_BAD_STATE (
1915
+ env, stmt->IsFinalized (), " statement has been finalized" );
1916
+ int num_cols = sqlite3_column_count (stmt->statement_ );
1917
+ Isolate* isolate = env->isolate ();
1918
+ LocalVector<Value> cols (isolate);
1919
+ LocalVector<Name> col_keys (isolate,
1920
+ {env->column_string (),
1921
+ env->database_string (),
1922
+ env->name_string (),
1923
+ env->table_string (),
1924
+ env->type_string ()});
1925
+ Local<Value> value;
1926
+
1927
+ cols.reserve (num_cols);
1928
+ for (int i = 0 ; i < num_cols; ++i) {
1929
+ LocalVector<Value> col_values (isolate);
1930
+ col_values.reserve (col_keys.size ());
1931
+
1932
+ if (!NullableSQLiteStringToValue (
1933
+ isolate, sqlite3_column_origin_name (stmt->statement_ , i))
1934
+ .ToLocal (&value)) {
1935
+ return ;
1936
+ }
1937
+ col_values.emplace_back (value);
1938
+
1939
+ if (!NullableSQLiteStringToValue (
1940
+ isolate, sqlite3_column_database_name (stmt->statement_ , i))
1941
+ .ToLocal (&value)) {
1942
+ return ;
1943
+ }
1944
+ col_values.emplace_back (value);
1945
+
1946
+ if (!stmt->ColumnNameToName (i).ToLocal (&value)) {
1947
+ return ;
1948
+ }
1949
+ col_values.emplace_back (value);
1950
+
1951
+ if (!NullableSQLiteStringToValue (
1952
+ isolate, sqlite3_column_table_name (stmt->statement_ , i))
1953
+ .ToLocal (&value)) {
1954
+ return ;
1955
+ }
1956
+ col_values.emplace_back (value);
1957
+
1958
+ if (!NullableSQLiteStringToValue (
1959
+ isolate, sqlite3_column_decltype (stmt->statement_ , i))
1960
+ .ToLocal (&value)) {
1961
+ return ;
1962
+ }
1963
+ col_values.emplace_back (value);
1964
+
1965
+ Local<Object> column = Object::New (isolate,
1966
+ Null (isolate),
1967
+ col_keys.data (),
1968
+ col_values.data (),
1969
+ col_keys.size ());
1970
+ cols.emplace_back (column);
1971
+ }
1972
+
1973
+ args.GetReturnValue ().Set (Array::New (isolate, cols.data (), cols.size ()));
1974
+ }
1975
+
1900
1976
void StatementSync::SourceSQLGetter (const FunctionCallbackInfo<Value>& args) {
1901
1977
StatementSync* stmt;
1902
1978
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
@@ -2002,6 +2078,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
2002
2078
SetProtoMethod (isolate, tmpl, " all" , StatementSync::All);
2003
2079
SetProtoMethod (isolate, tmpl, " get" , StatementSync::Get);
2004
2080
SetProtoMethod (isolate, tmpl, " run" , StatementSync::Run);
2081
+ SetProtoMethodNoSideEffect (
2082
+ isolate, tmpl, " columns" , StatementSync::Columns);
2005
2083
SetSideEffectFreeGetter (isolate,
2006
2084
tmpl,
2007
2085
FIXED_ONE_BYTE_STRING (isolate, " sourceSQL" ),
0 commit comments