github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/localfs/db.go (about)

     1  // Copyright 2018-2021 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package localfs
    20  
    21  import (
    22  	"context"
    23  	"database/sql"
    24  	"path"
    25  
    26  	"github.com/pkg/errors"
    27  
    28  	// Provides sqlite drivers
    29  	_ "github.com/mattn/go-sqlite3"
    30  )
    31  
    32  func initializeDB(root, dbName string) (*sql.DB, error) {
    33  	dbPath := path.Join(root, dbName)
    34  	db, err := sql.Open("sqlite3", dbPath)
    35  	if err != nil {
    36  		return nil, errors.Wrap(err, "localfs: error opening DB connection")
    37  	}
    38  
    39  	stmt, err := db.Prepare("CREATE TABLE IF NOT EXISTS recycled_entries (key TEXT PRIMARY KEY, path TEXT)")
    40  	if err != nil {
    41  		return nil, errors.Wrap(err, "localfs: error preparing statement")
    42  	}
    43  	_, err = stmt.Exec()
    44  	if err != nil {
    45  		return nil, errors.Wrap(err, "localfs: error executing create statement")
    46  	}
    47  
    48  	stmt, err = db.Prepare("CREATE TABLE IF NOT EXISTS user_interaction (resource TEXT, grantee TEXT, role TEXT DEFAULT '', favorite INTEGER DEFAULT 0, PRIMARY KEY (resource, grantee))")
    49  	if err != nil {
    50  		return nil, errors.Wrap(err, "localfs: error preparing statement")
    51  	}
    52  	_, err = stmt.Exec()
    53  	if err != nil {
    54  		return nil, errors.Wrap(err, "localfs: error executing create statement")
    55  	}
    56  
    57  	stmt, err = db.Prepare("CREATE TABLE IF NOT EXISTS metadata (resource TEXT, key TEXT, value TEXT, PRIMARY KEY (resource, key))")
    58  	if err != nil {
    59  		return nil, errors.Wrap(err, "localfs: error preparing statement")
    60  	}
    61  	_, err = stmt.Exec()
    62  	if err != nil {
    63  		return nil, errors.Wrap(err, "localfs: error executing create statement")
    64  	}
    65  
    66  	stmt, err = db.Prepare("CREATE TABLE IF NOT EXISTS share_references (resource TEXT PRIMARY KEY, target TEXT)")
    67  	if err != nil {
    68  		return nil, errors.Wrap(err, "localfs: error preparing statement")
    69  	}
    70  	_, err = stmt.Exec()
    71  	if err != nil {
    72  		return nil, errors.Wrap(err, "localfs: error executing create statement")
    73  	}
    74  
    75  	return db, nil
    76  }
    77  
    78  func (fs *localfs) addToRecycledDB(ctx context.Context, key, fileName string) error {
    79  	stmt, err := fs.db.Prepare("INSERT INTO recycled_entries VALUES (?, ?)")
    80  	if err != nil {
    81  		return errors.Wrap(err, "localfs: error preparing statement")
    82  	}
    83  	_, err = stmt.Exec(key, fileName)
    84  	if err != nil {
    85  		return errors.Wrap(err, "localfs: error executing insert statement")
    86  	}
    87  	return nil
    88  }
    89  
    90  func (fs *localfs) getRecycledEntry(ctx context.Context, key string) (string, error) {
    91  	var filePath string
    92  	err := fs.db.QueryRow("SELECT path FROM recycled_entries WHERE key=?", key).Scan(&filePath)
    93  	if err != nil {
    94  		return "", err
    95  	}
    96  	return filePath, nil
    97  }
    98  
    99  func (fs *localfs) removeFromRecycledDB(ctx context.Context, key string) error {
   100  	stmt, err := fs.db.Prepare("DELETE FROM recycled_entries WHERE key=?")
   101  	if err != nil {
   102  		return errors.Wrap(err, "localfs: error preparing statement")
   103  	}
   104  	_, err = stmt.Exec(key)
   105  	if err != nil {
   106  		return errors.Wrap(err, "localfs: error executing delete statement")
   107  	}
   108  	return nil
   109  }
   110  
   111  func (fs *localfs) addToACLDB(ctx context.Context, resource, grantee, role string) error {
   112  	stmt, err := fs.db.Prepare("INSERT INTO user_interaction (resource, grantee, role) VALUES (?, ?, ?) ON CONFLICT(resource, grantee) DO UPDATE SET role=?")
   113  	if err != nil {
   114  		return errors.Wrap(err, "localfs: error preparing statement")
   115  	}
   116  	_, err = stmt.Exec(resource, grantee, role, role)
   117  	if err != nil {
   118  		return errors.Wrap(err, "localfs: error executing insert statement")
   119  	}
   120  	return nil
   121  }
   122  
   123  func (fs *localfs) getACLs(ctx context.Context, resource string) (*sql.Rows, error) {
   124  	grants, err := fs.db.Query("SELECT grantee, role FROM user_interaction WHERE resource=?", resource)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  	return grants, nil
   129  }
   130  
   131  func (fs *localfs) removeFromACLDB(ctx context.Context, resource, grantee string) error {
   132  	stmt, err := fs.db.Prepare("UPDATE user_interaction SET role='' WHERE resource=? AND grantee=?")
   133  	if err != nil {
   134  		return errors.Wrap(err, "localfs: error preparing statement")
   135  	}
   136  	_, err = stmt.Exec(resource, grantee)
   137  	if err != nil {
   138  		return errors.Wrap(err, "localfs: error executing delete statement")
   139  	}
   140  	return nil
   141  }
   142  
   143  func (fs *localfs) addToFavoritesDB(ctx context.Context, resource, grantee string) error {
   144  	stmt, err := fs.db.Prepare("INSERT INTO user_interaction (resource, grantee, favorite) VALUES (?, ?, 1) ON CONFLICT(resource, grantee) DO UPDATE SET favorite=1")
   145  	if err != nil {
   146  		return errors.Wrap(err, "localfs: error preparing statement")
   147  	}
   148  	_, err = stmt.Exec(resource, grantee)
   149  	if err != nil {
   150  		return errors.Wrap(err, "localfs: error executing insert statement")
   151  	}
   152  	return nil
   153  }
   154  
   155  func (fs *localfs) removeFromFavoritesDB(ctx context.Context, resource, grantee string) error {
   156  	stmt, err := fs.db.Prepare("UPDATE user_interaction SET favorite=0 WHERE resource=? AND grantee=?")
   157  	if err != nil {
   158  		return errors.Wrap(err, "localfs: error preparing statement")
   159  	}
   160  	_, err = stmt.Exec(resource, grantee)
   161  	if err != nil {
   162  		return errors.Wrap(err, "localfs: error executing delete statement")
   163  	}
   164  	return nil
   165  }
   166  
   167  func (fs *localfs) addToMetadataDB(ctx context.Context, resource, key, value string) error {
   168  	stmt, err := fs.db.Prepare("INSERT INTO metadata (resource, key, value) VALUES (?, ?, ?) ON CONFLICT(resource, key) DO UPDATE SET value=?")
   169  	if err != nil {
   170  		return errors.Wrap(err, "localfs: error preparing statement")
   171  	}
   172  	_, err = stmt.Exec(resource, key, value, value)
   173  	if err != nil {
   174  		return errors.Wrap(err, "localfs: error executing insert statement")
   175  	}
   176  	return nil
   177  }
   178  
   179  func (fs *localfs) removeFromMetadataDB(ctx context.Context, resource, key string) error {
   180  	stmt, err := fs.db.Prepare("DELETE FROM metadata WHERE resource=? AND key=?")
   181  	if err != nil {
   182  		return errors.Wrap(err, "localfs: error preparing statement")
   183  	}
   184  	_, err = stmt.Exec(resource, key)
   185  	if err != nil {
   186  		return errors.Wrap(err, "localfs: error executing delete statement")
   187  	}
   188  	return nil
   189  }
   190  
   191  func (fs *localfs) getMetadata(ctx context.Context, resource string) (*sql.Rows, error) {
   192  	grants, err := fs.db.Query("SELECT key, value FROM metadata WHERE resource=?", resource)
   193  	if err != nil {
   194  		return nil, err
   195  	}
   196  	return grants, nil
   197  }
   198  
   199  func (fs *localfs) addToReferencesDB(ctx context.Context, resource, target string) error {
   200  	stmt, err := fs.db.Prepare("INSERT INTO share_references (resource, target) VALUES (?, ?) ON CONFLICT(resource) DO UPDATE SET target=?")
   201  	if err != nil {
   202  		return errors.Wrap(err, "localfs: error preparing statement")
   203  	}
   204  	_, err = stmt.Exec(resource, target, target)
   205  	if err != nil {
   206  		return errors.Wrap(err, "localfs: error executing insert statement")
   207  	}
   208  	return nil
   209  }
   210  
   211  func (fs *localfs) getReferenceEntry(ctx context.Context, resource string) (string, error) {
   212  	var target string
   213  	err := fs.db.QueryRow("SELECT target FROM share_references WHERE resource=?", resource).Scan(&target)
   214  	if err != nil {
   215  		return "", err
   216  	}
   217  	return target, nil
   218  }
   219  
   220  func (fs *localfs) copyMD(s string, t string) (err error) {
   221  	stmt, err := fs.db.Prepare("UPDATE user_interaction SET resource=? WHERE resource=?")
   222  	if err != nil {
   223  		return errors.Wrap(err, "localfs: error preparing statement")
   224  	}
   225  	_, err = stmt.Exec(t, s)
   226  	if err != nil {
   227  		return errors.Wrap(err, "localfs: error executing delete statement")
   228  	}
   229  
   230  	stmt, err = fs.db.Prepare("UPDATE metadata SET resource=? WHERE resource=?")
   231  	if err != nil {
   232  		return errors.Wrap(err, "localfs: error preparing statement")
   233  	}
   234  	_, err = stmt.Exec(t, s)
   235  	if err != nil {
   236  		return errors.Wrap(err, "localfs: error executing delete statement")
   237  	}
   238  
   239  	stmt, err = fs.db.Prepare("UPDATE share_references SET resource=? WHERE resource=?")
   240  	if err != nil {
   241  		return errors.Wrap(err, "localfs: error preparing statement")
   242  	}
   243  	_, err = stmt.Exec(t, s)
   244  	if err != nil {
   245  		return errors.Wrap(err, "localfs: error executing delete statement")
   246  	}
   247  	return nil
   248  }