Etter en ukes skitur til Østerrike, Bad Gastein, fikk mitt nye full-HD lommekamera prøve seg. Kameraet er av type Toshiba Camileo S10, et full-HD videokamera som passer fint ned i lomma.
Enkelte dager var det ned mot 19 minusgrader i bakkene og det taklet ikke kameraet. Under opptak i 1080p låste kameraet seg gjentatte ganger, fra bare noen sekunder til et halvt minutt med opptak, avhengig av dagens vær. Eneste løsning var å nappe ut batteriet og sette det inn igjen. Irriterende nok er det ikke eget batteri for klokka, så denne blir tilbakestilt.
For å i det hele tatt kunne filme noe i 1080p utendørs på ski måtte jeg filme korte klipp på 10-15 sekunder og vente litt mellom hvert opptak. Kameraet oppbevarte jeg i en snor rundt halsen på innsiden av skijakka.
Jeg mistenker at problemet ligger i minnebrikka, at kameraet ikke klarer å lagre unna raskt nok all den data som full-HD opptak krever. Da jeg stilte oppløsningen til 720p gikk det betraktelig bedre. Allikevel mistet jeg ett minutts opptak med denne innstillingen også, dette i pent og varmt vær, men med noe snø i lufta. Mitt tips er derfor å stoppe og starte opptaket ofte.
Minnebrikken jeg brukte var av type SDHC Class 4 på 4 GB fra Verbatim. Noen som kan anbefale en bedre og raskere minnebrikke?
VGnett gjorde en liten test av kameraet da det kom på markedet.
Kameraet skal garantert være med på flere skiturer, da det er lite, starter opp og er klar til bruk veldig raskt og tar flott video og flotte bilder utendørs, så lenge elektronikken holder seg i gang da…
Digg this
Gi kudos!
Emneord: · test, Toshiba S10, videokamera
I am novice on Android application development, slowly starting to understand the architecture. I particularly like that communication between applications and data storage are resource centric. But anyway…
If you have been developing mobile applications for Android you have most likely seen some exceptions in the Eclipse debugger that you don’t understand, maybe not the tiniest bit. This mostly has to do with lack of experience with the API combined with the strict way that Android sets up views and restricts which threads that are allowed to draw and control the views, along with other concurrency issues.
Starting up your application in the emulated Android environment is not the fastest thing to do, so how can you debug your applications in a little more snappier way? – In short, I really don’t know.
What I want is a sane error message with a stack trace of my application code, but since I can’t get that, I have to debug my application in other ways.
Break points
By setting a breakpoint in your code on places where you think the bug might exist, you can step through your source code until the application fails.
The cons of this are that it is time consuming to do all the manual step by step operations, it’s a boring way of debugging and the exception message you get might not be understandable to you.
Logging
The Android API provides a Log class that can be used to log messages and exceptions. It took me some time to figure out how to read the log messages, but the Android Eclipse plugin provides a LogCat view.
To show the LogCat view in Eclipse, you go to “Window”, “Show View”, “Other …”, expand the “Android” category and then open the “LogCat” view.
Example output from the LogCat view.
01-09 16:56:52.069: ERROR/Listings(1064): Failed to get trip listings
01-09 16:56:52.069: ERROR/Listings(1064): java.lang.RuntimeException: Example of exception logging
01-09 16:56:52.069: ERROR/Listings(1064): at no.ut.trip.Listings$ProgressThread.run(Listings.java:112)
The example above shows an error message on the first line, the exception class and message on the second line, with the stack trace on the following lines. Might be helpful.
Digg this
Gi kudos!
Emneord: · Android, debugging
Apache Solr is a very powerful index and search engine. Unfortunately it does have some flaws, at least I think this issue is somehow not “by design”.
If you are going to use a field to sort on, make sure you use one of the native data types in Solr, and don’t enable any tokenizer on that data type. If you do, you might end up with HTTP 500 Internal Server Error and error log messages like this:
SEVERE: java.lang.RuntimeException: there are more terms than documents in field “title”, but it’s impossible to sort on tokenized fields
I found out that I had been using a data type with some filters and a tokenizer on a couple of fields, quite unnecessary since I don’t do any search on them. I have another field that I do search on. I only use these fields for display and sort.
Keep it simple. Use “string” for strings you don’t have to search on. If you have to do both search and sort on a field, make two fields. For example, name one of them like “title.sort”.
Digg this
Gi kudos!
Emneord: · search, Solr, sort, tokenizer
Cowboy coding seems interesting, and it might be just that I have been doing when developing Madcow, a PHP web framework.
However, it is not the same as Scrum. Many projects tend to fail using the Scrum methodology, possibly because of the lack of clearly defined roles, and then fall back to something looking like Cowboy Coding.
Unfortunately, it seems that the project I am currently working on at work is exactly that, Cowboy Coding, not Scrum…
Digg this
Gi kudos!
Emneord: · Cowboy Coding, Methodology, Scrum
I dag kom jeg over noe merkelige greier i MySQL.
I en SELECT-spørring hvor jeg bruker WHERE for å søke etter strenger, så betyr det ingenting om jeg spør mot en tom streng eller masse mellomrom.
Jeg har en tabell som heter “texts” med kolonnene “uuid”, “name” og “content”. Feltet “content” er av type TEXT fordi jeg har behov for å lagre et ukjent antall tegn med tekst her.
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| uuid | varchar(36) | NO | PRI | | |
| name | varchar(16) | NO | | | |
| content | text | NO | | | |
+--------------+--------------+------+-----+---------+-------+
Først testet jeg med en tom streng:
mysql> SELECT uuid,name,content FROM texts \
-> WHERE content = "";
+--------------------------------------+-------------+---------+
| uuid | name | content |
+--------------------------------------+-------------+---------+
| 1b74168e-5b91-4c27-b1eb-257d6d0cee18 | description | |
| 963c7f0a-e0dc-45e5-af5b-a803dee3a743 | arrival | |
| a7bf022e-fc95-4410-bd6e-e92b64f12db4 | regulation | |
| ebffc5bb-b3f8-473d-8f34-a5041f73987c | sanitation | |
+--------------------------------------+-------------+---------+
4 rows in set (0.00 sec)
Deretter forsøkte jeg bare for moro skyld å søke etter tre mellomrom:
mysql> SELECT uuid,name,content FROM texts \
-> WHERE content = " ";
+--------------------------------------+-------------+---------+
| uuid | name | content |
+--------------------------------------+-------------+---------+
| 1b74168e-5b91-4c27-b1eb-257d6d0cee18 | description | |
| 963c7f0a-e0dc-45e5-af5b-a803dee3a743 | arrival | |
| a7bf022e-fc95-4410-bd6e-e92b64f12db4 | regulation | |
| ebffc5bb-b3f8-473d-8f34-a5041f73987c | sanitation | |
+--------------------------------------+-------------+---------+
4 rows in set (0.00 sec)
Men for all del da? Dette er jo samme resultatet som ovenfor.
Eller hva med denne spørringen? Jeg kan ikke skjønne hvorfor det er slik. En tom streng er ikke det samme som tre spacer!
mysql> SELECT uuid,name,content FROM texts \
-> WHERE content = " " AND content = "";
+--------------------------------------+-------------+---------+
| uuid | name | content |
+--------------------------------------+-------------+---------+
| 1b74168e-5b91-4c27-b1eb-257d6d0cee18 | description | |
| 963c7f0a-e0dc-45e5-af5b-a803dee3a743 | arrival | |
| a7bf022e-fc95-4410-bd6e-e92b64f12db4 | regulation | |
| ebffc5bb-b3f8-473d-8f34-a5041f73987c | sanitation | |
+--------------------------------------+-------------+---------+
4 rows in set (0.00 sec)
Hvorfor i alle dager gjør MySQL dette her mot meg?
Én teori jeg har er at MySQL skal hjelpe meg som en dum utvikler i å returnere det korrekte svaret selv om jeg skulle skrevet inn et mellomrom for mye i søkefeltet mitt. Akkurat i samme stil som de andre gangene MySQL har vært så hjelpsom mot meg…
Digg this
Gi kudos!
Emneord: · integritet, kode, MySQL
Lørdag dro jeg og tre kamerater til Gautablikk for å prøve ut snowboard og ski før vinterens store skiferie til Bad Gastein.

Gaustablikk har nå én åpen bakke, med t-krokheis. Det er ikke store greiene, men nok til å få oss opp av senga kl 7 om morgenen på en lørdag. Jeg forstår fremdeles ikke hvordan det gikk til…

Det var overskyet og lavt lys og det kom noe snø. Legg også merke til snøskillet på fjellene rundt dalen på bildet over.
Bakken var stort sett i fin form, men snøklumper og ujevn preparering gjorde det krevende å kjøre. Allikevel var det bedre forhold enn forventet, eller fryktet.
For å bevist at man har vært et sted, så tar man et bilde. Vi måtte dokumentere at vi var på Gaustablikk denne dagen.


Vi følte også for å dokumentere at bilder ble tatt…

Digg this
Gi kudos!
Emneord: · Gaustablikk, slalåm
En kollega på jobben hadde filmet noen korte videoklipp og disse var lagret på et Compact Flash-kort. Dessverre fikk hun bare “read error”-meldinger da hun prøvde å hente ut videoklippene, både på sin laptop og direkte fra kameraet.
Illustrasjonsfoto: Canon Compact Flash Card av Simon Clayson, Creative Commons
Jeg ga Linux-maskinen min et forsøk. Ved første øyekast så det mørkt ut og jeg fikk mange stygge feilmeldinger i dmesg-loggen. “fdisk -l” viste meg ingen partisjoner på minnekortet.
Jeg prøvde å ta ut og sette inn kortet igjen, bare for å sjekke en gang til. Denne gangen gikk det mye bedre.
Først tok jeg en kopi av minnekortet til en fil med verktøyet dd. Dette er viktig å gjøre hvis man har med ustabilt medium å gjøre for å ikke slite unødvendig på minnekortet eller risikere å slette noe.
$ sudo dd if=/dev/sdb of=/tmp/sdb.dd
Deretter lastet jeg ned programmet TestDisk fra CGSecurity. Dette er et gjenopprettingsverktøy som jeg ikke har brukt tidligere. Det dukket opp i flere søkeresultater på Google, så jeg ga det en sjanse. Og jeg kommer garantert til å bruke det ved liknende anledninger senere.
Jeg startet testdisk med “/list”-opsjonen mot kopien jeg lagde av minnekortet, for å se om verktøyet fant noe nyttig om disken.
$ sudo testdisk /list sdb.dd
TestDisk 6.10, Data Recovery Utility, July 2008
Christophe GRENIER
http://www.cgsecurity.org
Please wait...
Disk sdb.dd - 256 MB / 245 MiB - CHS 32 255 63, sector size=512
Disk sdb.dd - 256 MB / 245 MiB - CHS 32 255 63
Partition Start End Size in sectors
Partition sector doesn't have the endmark 0xAA55
Dette lovet ikke bra. Jeg forsøkte så å starte opp testdisk uten list-opsjonen og ble så presentert med en meny for å velge disk søke etter partisjoner, samt noen valg.
Jeg forsøkte flere av valgene, blant annet at disken var opprettet på et i386-system, men da fant den ingen partisjoner. Siden dette minnekortet har stått i et kompaktkamera var det sikkert ikke opprettet noen partisjoner på kortet, så jeg forsøkte det valget i stedet.
Det viste seg at det ikke var noen partisjoner på kortet. Filsystemet, som var vfat, var skrevet rett på minnekortet. Programmet viste meg en filbrowser og jeg kunne navigere rundt og kopiere ut filer.
Det ga meg også mulighet til å kopiere ut filer som tidligere hadde vært slettet. Jeg forsøkte å hente ut to bilder, for å teste dette. Det ene bildet var korrupt, trolig skrevet over etter at det var slettet, mens det andre bildet kunne vises uten problemer.
Må si at dette verktøyet var en stor suksess!
Digg this
Gi kudos!
Emneord: · gjenoppretting, Linux, minnekort, TestDisk, verktøy
Ikke så lenge siden skrev jeg om MySQL sine problemer med datatyper og NULL-konstraints. Og problemene stopper ikke der.
Jeg kom i dag over en merkelig og helt uforståelig bug i MySQL. Eller, det heter vel kanskje feature når det gjelder MySQL.
Ta følgende scenario: En kolonne “disabled_reason_ref” i tabellen “countries” refererer til feltet “uuid” i tabellen “texts”. Kolonnen “disabled_reason_ref” er definert med mindre størrelse enn feltet den refererer til. Dette visste jeg ikke om. Begge tabellene bruker InnoDB og det er satt opp fremmednøkler. Hvordan dette gir noe som helst mening i MySQL-verden vet jeg ikke.
Ihvertfall. Det hele startet med denne SQL INSERT-spørringen.
mysql> INSERT INTO countries (uuid, country_code, disabled, disabled_reason_ref, page_ref) VALUES ("a63d5a26-9719-47dd-9617-c07bd8126061", "NO", 1, "e80c8d7c-dd84-4a4f-8df4-778efe9b311a", NULL);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`utenlandsbolig/countries`, CONSTRAINT `countries_ibfk_2` FOREIGN KEY (`disabled_reason_ref`) REFERENCES `texts` (`uuid`))
Det er ingenting i feilmeldingen fra denne spørringen som sier noe om det.
Jeg lurte litt på om kolonnenavnet var for langt, så jeg lagde en ny kolonne som heter “reason_ref”.
mysql> alter table countries add column reason_ref VARCHAR(32) REFERENCES texts(uuid);
Query OK, 1 row affected (0.52 sec)
Records: 1 Duplicates: 0 Warnings: 0
MySQL satte riktignok ikke opp noen fremmednøkkel her, noe jeg sjekket med “SHOW CREATE TABLE countries”.
Lurer da fælt på hva den i så fall referer til…
Vel, MySQL er MySQL.
Jeg tenkte så at jeg ikke trengte “disabled_reason_ref” lenger.
mysql> alter table countries drop column disabled_reason_ref;
ERROR 1025 (HY000): Error on rename of './utenlandsbolig/#sql-4fa3_6' to './utenlandsbolig/countries' (errno: 150)
Hva i alle dager betyr dette?
Jeg kom meg ikke rundt feilen, så jeg lot kolonnen bare ligge.
Jeg hadde på dette tidspunktet ikke oppdaget at “reason_ref” var for liten. Kolonnen den refererer til er nemlig av type VARCHAR(36).
Et nytt forsøk på INSERT, nå ved å bruke den nye kolonnen.
mysql> INSERT INTO countries (uuid, country_code, disabled, reason_ref, page_ref) VALUES ("a63d5a26-9719-47dd-9617-c07bd8126061", "NO", 1, "e80c8d7c-dd84-4a4f-8df4-778efe9b311a", NULL);
Query OK, 1 row affected, 1 warning (0.19 sec)
mysql> show warnings;
+---------+------+-------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------+
| Warning | 1265 | Data truncated for column 'reason_ref' at row 1 |
+---------+------+-------------------------------------------------+
1 row in set (0.00 sec)
Og det viste seg at kolonnen var for liten. Dermed fant den ingen rad i “texts”-tabellen som hadde den refererte verdien på 32 tegn, da verdien egentlig skulle vært på 36 tegn.
mysql> alter table countries modify column disabled_reason_ref varchar(36);
Query OK, 2 rows affected (0.40 sec)
Records: 2 Duplicates: 0 Warnings: 0
Greit at det var jeg som gjorde feilen med å deklarere kolonnen for liten.
Men hallooo, litt hjelp kan man vel få fra en database? Spesielt fra en relasjonsdatabase!
Dumme MySQL!
Digg this
Gi kudos!
Emneord: · integritet, kode, MySQL, relasjoner
MySQL gjør mye rart. Her har vi en ganske normal tabell, med kolonner som krever en verdi og med kolonner av forskjellige datatyper. Fire av kolonnene i tabellen kan ta default verdier, resten kan det ikke.
mysql> DESC user_status;
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| uid | int(10) | NO | PRI | NULL | |
| verified | tinyint(1) | NO | | 0 | |
| registered_nick | tinyint(1) | NO | | 0 | |
| first_time | tinyint(1) | NO | | 1 | |
| registration_date | datetime | NO | | NULL | |
| verification_code | int(10) | NO | | NULL | |
| nick | varchar(32) | NO | | NULL | |
| active | tinyint(1) | NO | | 1 | |
| ban_reason | varchar(255) | NO | | NULL | |
| logincount | int(11) | NO | | NULL | |
| lastlogin | datetime | NO | | NULL | |
+-------------------+--------------+------+-----+---------+-------+
Så legger vi inn en rad i tabellen. Legg merke til at vi bare legger inn data i noen av kolonnene.
INSERT INTO user_status(
uid, verified, registration_date,
verification_code, nick)
VALUES(1, 1, NOW(), "asd", "ut");
Så får jeg en suksessmelding tilbake fra MySQL, jippi. Eller vent, det står noe om at det er generert tre advarsler. Ok tenker jeg, så jeg får vel finne ut hva disse advarslene er.
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------------------+
| Warning | 1364 | Field 'ban_reason' doesn't have a default value |
| Warning | 1364 | Field 'logincount' doesn't have a default value |
| Warning | 1364 | Field 'lastlogin' doesn't have a default value |
| Warning | 1366 | Incorrect integer value: 'asd' for column 'verification_code' at row 1 |
+---------+------+------------------------------------------------------------------------+
Det at MySQL gir blaffen i påkrevde kolonner visste jeg egentlig, og jeg blir sinna hver gang jeg tenker på det. Så egentlig var de første advarslene godt kjente for meg.
Det som virkelig overrasket meg var,
Hva?! Tillater MySQL meg å opprette en rad i en tabell med noe data i en kollonne med en annen datatype?
MySQL tillater meg faktisk å sende inn tekststrengen “asd” inn kolonnen “verification_code” som er deklarert som et heltall. Hva i alle dager? Hvilken verdi har MySQL satt inn i tabellen min da? Dette må undersøkes.
mysql> SELECT * FROM user_status;
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
| uid | verified | registered_nick | first_time | registration_date | verification_code | nick | active | ban_reason | logincount | lastlogin |
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
| 1 | 1 | 0 | 1 | 2009-09-29 17:08:57 | 0 | ut | 1 | | 0 | 0000-00-00 00:00:00 |
+-----+----------+-----------------+------------+---------------------+-------------------+------+--------+------------+------------+---------------------+
Den satte inn tallet “0″ i verification_code-kolonnen. Hvordan MySQL fant ut at det var en smart idé vet jeg ikke. Kolonnen er av type heltall, den krever en verdi og er deklarert uten noen default verdi. Jeg sender inn tekststrengen “asd”.
I et scriptspråk som PHP eller Perl evalueres denne strengen til en bolsk sann verdi. Så kanskje kunne heltallsrepresentasjonen av strengen vært “1″. Derimot er det ikke sikkert at kolonnen representerer en bolsk verdi, for da ville jeg vel brukt en datatype som bit eller bool, ikke sant? Det eneste fornuftige å gjøre er faktisk å ikke tillate verdien og forhindre meg i å opprette raden.
Det jeg stusser litt på, og blir lei meg over, er den manglende forståelsen av integritet i MySQL. Hvis jeg forsøker å opprette en rad i en tabell uten å sende inn alle påkrevde felt, så burde jeg ikke få lov til å opprette raden. Så enkelt kan det gjøres.
MySQL må ikke tro at den er smartere enn meg.
Digg this
Gi kudos!
Emneord: · integritet, kode, MySQL
Ok, so I have been debugging a Perl application that I wrote about six months ago. Basically it creates some meta data and copies files to other user accounts using SSH.
For file transfer it uses File::RsyncP and for remote control it uses Net::SSH::Perl. Some times I get the error message Could not dupe: Bad file descriptor. Not a very informative error message, but I had an idea that it might have something to do with the file transfer. After I restart the application, running as a FastCGI web application, everything works, for a short while, then it breaks again.
I found out that it stops working right after I end my SSH connection, after debugging and restarting the application. After some research I found out it had something to do with the loss of STDIN. My best guess is that SSH needs STDIN to be able to read the password entered by the user, but I use keys for authentication, so I won’t need STDIN at all for interacting with SSH.
I tried different tactics to keep STDIN open. Running it using nohup did not help. Then I tried starting up the web application using screen, and now it still runs several hours after logging out from the server.
I don’t like this workaround very much. So if anyone has a better solution to this problem, I would love to hear about it.
A possible solution might be to redirect STDIN to a temporary file. Anyone had success doing this with Net::SSH::Perl or File::RsyncP?
Digg this
Gi kudos!
Emneord: · debugging, Perl, SSH