Comments 8
Может просто баг и нужно багрепорт запостить куда-нибудь?
если поведение не соответствует документации, сообщите об этом разработчикам, а не пишите статью на хабр. лучше же добиться ожидаемого поведения от библиотеки, чем заниматься внедрением кривохаков с свой код
У разработчиков в багтрекере уже есть тикет.
code.google.com/p/android/issues/detail?id=13045
Только, похоже, им не особо занимаются — висит с декабря, а до сих пор без владельца. Я зашел туда, поставил звездочку. Можете тоже отметиться.
А написать об этом, думаю, не повредит. Когда исправят библиотеку неизвестно. Опять же, у меня лично нет уверенности, что исправления попадут в старые версии андроида. Я вот убил целый день, чтобы понять, почему у меня в базе кривые данные оказались. Может, кому-то это знание сэкономит немного времени.
code.google.com/p/android/issues/detail?id=13045
Только, похоже, им не особо занимаются — висит с декабря, а до сих пор без владельца. Я зашел туда, поставил звездочку. Можете тоже отметиться.
А написать об этом, думаю, не повредит. Когда исправят библиотеку неизвестно. Опять же, у меня лично нет уверенности, что исправления попадут в старые версии андроида. Я вот убил целый день, чтобы понять, почему у меня в базе кривые данные оказались. Может, кому-то это знание сэкономит немного времени.
SQLite — библиотека с открытым кодом. Хочется, чтобы в этой статье появились и результаты изучения этого кода. А может, и патч!
выложите код воспроизводящий баг, чтобы каждый мог убедиться.
Не совсем понятно, Вы при вставке уже передаете в ContentValues id? Или на таблице задан другой Unique constrain? Вообще, я не помню, чтоб какая либо БД при операции INSERT выбрасывала ошибку с указанием конкретного ключа, обычно мы получаем инфу только об имени сработавшего констрейна.
Поэтому, разработчики API и не стали париться с этим. Чтоб вернуть ключ «конфликтной» записи пришлось бы после вставки понять, какой констрейн сработал, определить, какое поля в него входят, сделать соответствующий select для извлечения _id… Короче, сложно, и медленно, поэтому разработчики отдали этот на реализацию нам.
Ну естественно, это просто мои мысли в слух :)
Поэтому, разработчики API и не стали париться с этим. Чтоб вернуть ключ «конфликтной» записи пришлось бы после вставки понять, какой констрейн сработал, определить, какое поля в него входят, сделать соответствующий select для извлечения _id… Короче, сложно, и медленно, поэтому разработчики отдали этот на реализацию нам.
Ну естественно, это просто мои мысли в слух :)
В таблице задано ограничение unique на колонку кроме id.
Я мог бы понять, если бы разработчики просто не стали париться с проблемой. Но зачем писать в документации то, что реально не сдалано, причем не просто не сделано, а делает вид, что отработало нормально, но возвращает совершенно левое значение? Для себя я уже написал обертку, которая делает select, если вставка не удалась. Ничего особо сложного там нет, хотя параметров приходится передавать чуть больше, чем в обычный insert. Сделали бы так или не делали бы совсем.
И это, на самом деле, далеко не единственная заморочка с андроидными базами. Например, есть замечательный класс SQLiteOpenHelper, от которого мне пришлось отказаться. Теоретически он использует ContextWrapper.getDatabasePath(), чтобы получить полный путь к файлу. Я хотел воспользоваться этим, чтобы создавать базу на карточке, а не в самом телефоне (база довольно большая, а скорость не принципиальна). Оказалось, что getDatabasePath вызывается далеко не всегда. Появляется реальный шанс создать базу в одном месте, а открыть ее для чтения из совсем другого.
Вобщем, там, похоже, просто баг на баге сидит, а каждое слово из документации надо проверять отдельным тестом. Хотя, когда смотришь на андроидоный API в первый раз, все кажется логичным и удобным.
Я мог бы понять, если бы разработчики просто не стали париться с проблемой. Но зачем писать в документации то, что реально не сдалано, причем не просто не сделано, а делает вид, что отработало нормально, но возвращает совершенно левое значение? Для себя я уже написал обертку, которая делает select, если вставка не удалась. Ничего особо сложного там нет, хотя параметров приходится передавать чуть больше, чем в обычный insert. Сделали бы так или не делали бы совсем.
И это, на самом деле, далеко не единственная заморочка с андроидными базами. Например, есть замечательный класс SQLiteOpenHelper, от которого мне пришлось отказаться. Теоретически он использует ContextWrapper.getDatabasePath(), чтобы получить полный путь к файлу. Я хотел воспользоваться этим, чтобы создавать базу на карточке, а не в самом телефоне (база довольно большая, а скорость не принципиальна). Оказалось, что getDatabasePath вызывается далеко не всегда. Появляется реальный шанс создать базу в одном месте, а открыть ее для чтения из совсем другого.
Вобщем, там, похоже, просто баг на баге сидит, а каждое слово из документации надо проверять отдельным тестом. Хотя, когда смотришь на андроидоный API в первый раз, все кажется логичным и удобным.
Sign up to leave a comment.
Осторожнее с SQLiteDatabase.insert-ами