OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "sql/recovery.h" | 5 #include "sql/recovery.h" |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 std::string rowid_decl; // ROWID version of column |rowid_ofs|. | 359 std::string rowid_decl; // ROWID version of column |rowid_ofs|. |
360 | 360 |
361 while (s.Step()) { | 361 while (s.Step()) { |
362 const std::string column_name(s.ColumnString(1)); | 362 const std::string column_name(s.ColumnString(1)); |
363 const std::string column_type(s.ColumnString(2)); | 363 const std::string column_type(s.ColumnString(2)); |
364 const bool not_null = s.ColumnBool(3); | 364 const bool not_null = s.ColumnBool(3); |
365 const int default_type = s.ColumnType(4); | 365 const int default_type = s.ColumnType(4); |
366 const bool default_is_null = (default_type == COLUMN_TYPE_NULL); | 366 const bool default_is_null = (default_type == COLUMN_TYPE_NULL); |
367 const int pk_column = s.ColumnInt(5); | 367 const int pk_column = s.ColumnInt(5); |
368 | 368 |
369 if (pk_column > 0) { | 369 // http://www.sqlite.org/pragma.html#pragma_table_info documents column 5 as |
370 // TODO(shess): http://www.sqlite.org/pragma.html#pragma_table_info | 370 // the 1-based index of the column in the primary key, otherwise 0. |
371 // documents column 5 as the index of the column in the primary key | 371 if (pk_column > 0) |
372 // (zero for not in primary key). I find that it is always 1 for | |
373 // columns in the primary key. Since this code is very dependent on | |
374 // that pragma, review if the implementation changes. | |
375 DCHECK_EQ(1, pk_column); | |
376 ++pk_column_count; | 372 ++pk_column_count; |
377 } | |
378 | 373 |
379 // Construct column declaration as "name type [optional constraint]". | 374 // Construct column declaration as "name type [optional constraint]". |
380 std::string column_decl = column_name; | 375 std::string column_decl = column_name; |
381 | 376 |
382 // SQLite's affinity detection is documented at: | 377 // SQLite's affinity detection is documented at: |
383 // http://www.sqlite.org/datatype3.html#affname | 378 // http://www.sqlite.org/datatype3.html#affname |
384 // The gist of it is that CHAR, TEXT, and INT use substring matches. | 379 // The gist of it is that CHAR, TEXT, and INT use substring matches. |
385 // TODO(shess): It would be nice to unit test the type handling, | 380 // TODO(shess): It would be nice to unit test the type handling, |
386 // but it is not obvious to me how to write a test which would | 381 // but it is not obvious to me how to write a test which would |
387 // fail appropriately when something was broken. It would have to | 382 // fail appropriately when something was broken. It would have to |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 } | 522 } |
528 return false; | 523 return false; |
529 } | 524 } |
530 | 525 |
531 RecordRecoveryEvent(RECOVERY_SUCCESS_META_VERSION); | 526 RecordRecoveryEvent(RECOVERY_SUCCESS_META_VERSION); |
532 *version = recovery_version.ColumnInt(0); | 527 *version = recovery_version.ColumnInt(0); |
533 return true; | 528 return true; |
534 } | 529 } |
535 | 530 |
536 } // namespace sql | 531 } // namespace sql |
OLD | NEW |