blob: a754dbb4ceae1805bed8e41b51d6caed7cf3e220 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 opendal
import (
"context"
"unsafe"
"github.com/jupiterrider/ffi"
)
// Stat retrieves metadata for the specified path.
//
// This function is a wrapper around the C-binding function `opendal_operator_stat`.
//
// # Parameters
//
// - path: The path of the file or directory to get metadata for.
//
// # Returns
//
// - *Metadata: Metadata of the specified path.
// - error: An error if the operation fails, or nil if successful.
//
// # Notes
//
// - The current implementation does not support `stat_with` functionality.
// - If the path does not exist, an error with code opendal.CodeNotFound will be returned.
//
// # Example
//
// func exampleStat(op *opendal.Operator) {
// meta, err := op.Stat("/path/to/file")
// if err != nil {
// if e, ok := err.(*opendal.Error); ok && e.Code() == opendal.CodeNotFound {
// fmt.Println("File not found")
// return
// }
// log.Fatalf("Stat operation failed: %v", err)
// }
// fmt.Printf("File size: %d bytes\n", meta.ContentLength())
// fmt.Printf("Last modified: %v\n", meta.LastModified())
// }
//
// Note: This example assumes proper error handling and import statements.
func (op *Operator) Stat(path string) (*Metadata, error) {
meta, err := ffiOperatorStat.symbol(op.ctx)(op.inner, path)
if err != nil {
return nil, err
}
return newMetadata(op.ctx, meta), nil
}
// IsExist checks if a file or directory exists at the specified path.
//
// This method provides a convenient way to determine the existence of a resource
// without fetching its full metadata.
//
// # Parameters
//
// - path: The path of the file or directory to check.
//
// # Returns
//
// - bool: true if the resource exists, false otherwise.
// - error: An error if the check operation fails, or nil if the check is successful.
// Note that a false return value with a nil error indicates that the resource does not exist.
//
// # Example
//
// exists, err := op.IsExist("path/to/file")
// if err != nil {
// log.Fatalf("Error checking existence: %v", err)
// }
// if exists {
// fmt.Println("The file exists")
// } else {
// fmt.Println("The file does not exist")
// }
func (op *Operator) IsExist(path string) (bool, error) {
return ffiOperatorIsExist.symbol(op.ctx)(op.inner, path)
}
var ffiOperatorStat = newFFI(ffiOpts{
sym: "opendal_operator_stat",
rType: &typeResultStat,
aTypes: []*ffi.Type{&ffi.TypePointer, &ffi.TypePointer},
}, func(ctx context.Context, ffiCall ffiCall) func(op *opendalOperator, path string) (*opendalMetadata, error) {
return func(op *opendalOperator, path string) (*opendalMetadata, error) {
bytePath, err := BytePtrFromString(path)
if err != nil {
return nil, err
}
var result resultStat
ffiCall(
unsafe.Pointer(&result),
unsafe.Pointer(&op),
unsafe.Pointer(&bytePath),
)
if result.error != nil {
return nil, parseError(ctx, result.error)
}
return result.meta, nil
}
})
var ffiOperatorIsExist = newFFI(ffiOpts{
sym: "opendal_operator_is_exist",
rType: &typeResultIsExist,
aTypes: []*ffi.Type{&ffi.TypePointer, &ffi.TypePointer},
}, func(ctx context.Context, ffiCall ffiCall) func(op *opendalOperator, path string) (bool, error) {
return func(op *opendalOperator, path string) (bool, error) {
bytePath, err := BytePtrFromString(path)
if err != nil {
return false, err
}
var result resultIsExist
ffiCall(
unsafe.Pointer(&result),
unsafe.Pointer(&op),
unsafe.Pointer(&bytePath),
)
if result.error != nil {
return false, parseError(ctx, result.error)
}
return result.is_exist == 1, nil
}
})