2011-03-05 22:14:00 +00:00
/ *
Copyright 2011 Google Inc .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package mysqlindexer
import (
2011-04-03 15:07:40 +00:00
"fmt"
2011-04-09 06:20:24 +00:00
"io"
2011-03-05 22:14:00 +00:00
"os"
2011-06-19 21:36:46 +00:00
"strconv"
2011-03-05 22:14:00 +00:00
2011-04-16 05:25:45 +00:00
"camli/blobref"
"camli/blobserver"
"camli/jsonconfig"
2011-03-05 22:14:00 +00:00
)
type Indexer struct {
2011-04-03 15:07:40 +00:00
* blobserver . SimpleBlobHubPartitionMap
2011-07-02 16:09:50 +00:00
KeyFetcher blobref . StreamingFetcher // for verifying claims
2011-03-16 06:16:24 +00:00
2011-11-07 16:40:31 +00:00
// Used for fetching blobs to find the complete sha1s of file & bytes
// schema blobs.
2011-07-02 16:09:50 +00:00
BlobSource blobserver . Storage
2011-06-09 00:49:31 +00:00
2011-07-05 07:11:29 +00:00
db * MySQLWrapper
2011-03-05 22:14:00 +00:00
}
2011-06-09 00:49:31 +00:00
func newFromConfig ( ld blobserver . Loader , config jsonconfig . Obj ) ( blobserver . Storage , os . Error ) {
blobPrefix := config . RequiredString ( "blobSource" )
2011-07-05 07:11:29 +00:00
db := & MySQLWrapper {
Host : config . OptionalString ( "host" , "localhost" ) ,
User : config . RequiredString ( "user" ) ,
Password : config . OptionalString ( "password" , "" ) ,
Database : config . RequiredString ( "database" ) ,
}
2011-04-03 15:07:40 +00:00
indexer := & Indexer {
SimpleBlobHubPartitionMap : & blobserver . SimpleBlobHubPartitionMap { } ,
2011-07-05 07:11:29 +00:00
db : db ,
2011-04-03 15:07:40 +00:00
}
if err := config . Validate ( ) ; err != nil {
return nil , err
}
2011-04-16 05:25:45 +00:00
2011-06-09 00:49:31 +00:00
sto , err := ld . GetStorage ( blobPrefix )
if err != nil {
return nil , err
}
indexer . BlobSource = sto
2011-06-23 01:08:07 +00:00
// Good enough, for now:
indexer . KeyFetcher = indexer . BlobSource
2011-04-03 15:07:40 +00:00
ok , err := indexer . IsAlive ( )
if ! ok {
return nil , fmt . Errorf ( "Failed to connect to MySQL: %v" , err )
}
2011-06-19 21:36:46 +00:00
version , err := indexer . SchemaVersion ( )
if err != nil {
return nil , fmt . Errorf ( "error getting schema version (need to init database?): %v" , err )
}
if version != requiredSchemaVersion {
if os . Getenv ( "CAMLI_ADVERTISED_PASSWORD" ) != "" {
// Good signal that we're using the dev-server script, so help out
// the user with a more useful tip:
return nil , fmt . Errorf ( "database schema version is %d; expect %d (run \"./dev-server --wipe\" to wipe both your blobs and re-populate the database schema)" , version , requiredSchemaVersion )
}
return nil , fmt . Errorf ( "database schema version is %d; expect %d (need to re-init/upgrade database?)" ,
version , requiredSchemaVersion )
}
2011-04-03 15:07:40 +00:00
return indexer , nil
}
func init ( ) {
blobserver . RegisterStorageConstructor ( "mysqlindexer" , blobserver . StorageConstructor ( newFromConfig ) )
}
2011-03-05 23:09:36 +00:00
func ( mi * Indexer ) IsAlive ( ) ( ok bool , err os . Error ) {
2011-07-05 07:11:29 +00:00
err = mi . db . Ping ( )
ok = err == nil
return
2011-03-05 23:09:36 +00:00
}
2011-06-19 21:36:46 +00:00
func ( mi * Indexer ) SchemaVersion ( ) ( version int , err os . Error ) {
2011-07-05 07:11:29 +00:00
rs , err := mi . db . Query ( "SELECT value FROM meta WHERE metakey='version'" )
2011-06-19 21:36:46 +00:00
if err != nil {
return
}
2011-07-05 07:11:29 +00:00
defer rs . Close ( )
if ! rs . Next ( ) {
2011-06-19 21:36:46 +00:00
return 0 , nil
}
2011-07-05 07:11:29 +00:00
strVersion := ""
if err = rs . Scan ( & strVersion ) ; err != nil {
2011-06-28 01:42:00 +00:00
return
}
2011-07-05 07:11:29 +00:00
return strconv . Atoi ( strVersion )
2011-03-05 23:09:36 +00:00
}
2011-03-05 22:14:00 +00:00
func ( mi * Indexer ) Fetch ( blob * blobref . BlobRef ) ( blobref . ReadSeekCloser , int64 , os . Error ) {
return nil , 0 , os . NewError ( "Fetch isn't supported by the MySQL indexer" )
}
2011-04-09 06:20:24 +00:00
func ( mi * Indexer ) FetchStreaming ( blob * blobref . BlobRef ) ( io . ReadCloser , int64 , os . Error ) {
return nil , 0 , os . NewError ( "Fetch isn't supported by the MySQL indexer" )
}
2011-09-29 02:37:28 +00:00
func ( mi * Indexer ) RemoveBlobs ( blobs [ ] * blobref . BlobRef ) os . Error {
return os . NewError ( "RemoveBlobs isn't supported by the MySQL indexer" )
2011-03-05 22:14:00 +00:00
}